summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManoj Srivastava <srivasta@debian.org>2020-05-27 16:31:00 -0700
committerManoj Srivastava <srivasta@debian.org>2020-05-27 16:31:00 -0700
commitd7533e931cfb49a68dc8e6e3f524d49e364cef83 (patch)
tree06d31523b9647d3de8ce8888f6e83d24f046aa82
parent4e9b9c402ed95bf9a17fd6d795bc49bb4128a6fa (diff)
New upstream version 2.41-ah~0.git.20200131
-rw-r--r--CMakeLists.txt23
-rw-r--r--README.md6
-rw-r--r--lib/CMakeLists.txt1
-rw-r--r--lib/dngn/dun1.142
-rw-r--r--lib/dngn/dun10.03
-rw-r--r--lib/dngn/dun11.202
-rw-r--r--lib/dngn/dun11.222
-rw-r--r--lib/dngn/dun17.155
-rw-r--r--lib/dngn/dun18.02
-rw-r--r--lib/dngn/dun18.12
-rw-r--r--lib/dngn/dun19.115
-rw-r--r--lib/dngn/dun2.312
-rw-r--r--lib/dngn/dun22.102
-rw-r--r--lib/dngn/dun22.55
-rw-r--r--lib/dngn/dun24.03
-rw-r--r--lib/dngn/dun29.156
-rw-r--r--lib/dngn/dun3.185
-rw-r--r--lib/dngn/dun3.285
-rw-r--r--lib/dngn/dun3.35
-rw-r--r--lib/dngn/dun5.03
-rw-r--r--lib/dngn/dun5.1414
-rw-r--r--lib/dngn/dun6.03
-rw-r--r--lib/edit/a_info.txt39
-rw-r--r--lib/edit/ba_info.txt13
-rw-r--r--lib/edit/d_info.txt80
-rw-r--r--lib/edit/k_info.txt185
-rw-r--r--lib/edit/p_info.txt3
-rw-r--r--lib/edit/ra_info.txt9
-rw-r--r--lib/edit/s_orc.map11
-rw-r--r--lib/edit/set_info.txt1
-rw-r--r--lib/edit/st_info.txt33
-rw-r--r--lib/edit/t_bree.txt9
-rw-r--r--lib/edit/t_d_bree.txt9
-rw-r--r--lib/file/book-10.txt250
-rw-r--r--lib/file/book-11.txt250
-rw-r--r--lib/file/book-12.txt250
-rw-r--r--lib/file/book-13.txt250
-rw-r--r--lib/file/book-14.txt250
-rw-r--r--lib/file/book-15.txt250
-rw-r--r--lib/file/book-16.txt250
-rw-r--r--lib/file/book-17.txt250
-rw-r--r--lib/file/book-18.txt250
-rw-r--r--lib/file/book-19.txt250
-rw-r--r--lib/file/book-9.txt240
-rw-r--r--lib/help/debug.txt15
-rw-r--r--lib/help/g_eru.txt8
-rw-r--r--lib/help/m_divin.txt13
-rw-r--r--lib/help/macrofaq.txt14
-rw-r--r--lib/help/wishing.txt7
-rw-r--r--lib/mods/theme/CMakeLists.txt1
-rw-r--r--lib/mods/theme/dngn/dun1.142
-rw-r--r--lib/mods/theme/dngn/dun1.222
-rw-r--r--lib/mods/theme/dngn/dun10.03
-rw-r--r--lib/mods/theme/dngn/dun11.202
-rw-r--r--lib/mods/theme/dngn/dun11.222
-rw-r--r--lib/mods/theme/dngn/dun17.155
-rw-r--r--lib/mods/theme/dngn/dun18.02
-rw-r--r--lib/mods/theme/dngn/dun18.12
-rw-r--r--lib/mods/theme/dngn/dun19.115
-rw-r--r--lib/mods/theme/dngn/dun2.312
-rw-r--r--lib/mods/theme/dngn/dun20.15
-rw-r--r--lib/mods/theme/dngn/dun22.102
-rw-r--r--lib/mods/theme/dngn/dun22.205
-rw-r--r--lib/mods/theme/dngn/dun22.55
-rw-r--r--lib/mods/theme/dngn/dun24.03
-rw-r--r--lib/mods/theme/dngn/dun29.156
-rw-r--r--lib/mods/theme/dngn/dun3.185
-rw-r--r--lib/mods/theme/dngn/dun3.285
-rw-r--r--lib/mods/theme/dngn/dun3.35
-rw-r--r--lib/mods/theme/dngn/dun36.55
-rw-r--r--lib/mods/theme/dngn/dun39.09
-rw-r--r--lib/mods/theme/dngn/dun4.92
-rw-r--r--lib/mods/theme/dngn/dun40.09
-rw-r--r--lib/mods/theme/dngn/dun5.03
-rw-r--r--lib/mods/theme/dngn/dun5.1414
-rw-r--r--lib/mods/theme/dngn/dun6.03
-rw-r--r--lib/mods/theme/edit/a_info.txt33
-rw-r--r--lib/mods/theme/edit/ba_info.txt18
-rw-r--r--lib/mods/theme/edit/d_info.txt126
-rw-r--r--lib/mods/theme/edit/k_info.txt182
-rw-r--r--lib/mods/theme/edit/p_info.txt3
-rw-r--r--lib/mods/theme/edit/ra_info.txt17
-rw-r--r--lib/mods/theme/edit/set_info.txt6
-rw-r--r--lib/mods/theme/edit/st_info.txt68
-rw-r--r--lib/mods/theme/edit/t_bree.txt9
-rw-r--r--lib/mods/theme/edit/t_d_bree.txt9
-rw-r--r--lib/mods/theme/file/book-10.txt75
-rw-r--r--lib/mods/theme/file/book-11.txt51
-rw-r--r--lib/mods/theme/file/book-12.txt68
-rw-r--r--lib/mods/theme/file/book-13.txt54
-rw-r--r--lib/mods/theme/file/book-14.txt55
-rw-r--r--lib/mods/theme/file/book-15.txt68
-rw-r--r--lib/mods/theme/file/book-16.txt43
-rw-r--r--lib/mods/theme/file/book-17.txt47
-rw-r--r--lib/mods/theme/file/book-18.txt55
-rw-r--r--lib/mods/theme/file/book-19.txt47
-rw-r--r--lib/mods/theme/file/book-9.txt99
-rw-r--r--lib/mods/theme/help/debug.txt15
-rw-r--r--lib/mods/theme/help/g_eru.txt8
-rw-r--r--lib/mods/theme/help/m_divin.txt13
-rw-r--r--lib/mods/theme/help/macrofaq.txt14
-rw-r--r--lib/mods/theme/help/wishing.txt7
-rw-r--r--lib/mods/theme/pref/xtra-xxx.prf137
-rw-r--r--lib/pref/pref.prf4
-rw-r--r--lib/pref/xtra-xxx.prf137
-rw-r--r--src/CMakeLists.txt41
-rw-r--r--src/ability_type.hpp2
-rw-r--r--src/activation.hpp2
-rw-r--r--src/alloc.hpp2
-rw-r--r--src/alloc_entry.hpp2
-rw-r--r--src/angband.h94
-rw-r--r--src/artifact_type.hpp6
-rw-r--r--src/between_exit.hpp6
-rw-r--r--src/birth.cc363
-rw-r--r--src/birth.hpp8
-rw-r--r--src/birther.hpp27
-rw-r--r--src/bldg.cc239
-rw-r--r--src/bldg.hpp5
-rw-r--r--src/cave.cc861
-rw-r--r--src/cave.hpp14
-rw-r--r--src/cave_type.hpp5
-rw-r--r--src/cli_comm.hpp6
-rw-r--r--src/cmd1.cc573
-rw-r--r--src/cmd1.hpp14
-rw-r--r--src/cmd2.cc774
-rw-r--r--src/cmd2.hpp3
-rw-r--r--src/cmd3.cc199
-rw-r--r--src/cmd3.hpp6
-rw-r--r--src/cmd4.cc629
-rw-r--r--src/cmd4.hpp4
-rw-r--r--src/cmd5.cc155
-rw-r--r--src/cmd5.hpp10
-rw-r--r--src/cmd6.cc1334
-rw-r--r--src/cmd6.hpp4
-rw-r--r--src/cmd7.cc262
-rw-r--r--src/cmd7.hpp2
-rw-r--r--src/config.hpp (renamed from src/config.h)34
-rw-r--r--src/corrupt.cc108
-rw-r--r--src/corrupt.hpp8
-rw-r--r--src/defines.hpp (renamed from src/defines.h)196
-rw-r--r--src/device_allocation_fwd.hpp2
-rw-r--r--src/dice.cc20
-rw-r--r--src/dice_fwd.hpp5
-rw-r--r--src/dungeon.cc1465
-rw-r--r--src/dungeon.h12
-rw-r--r--src/dungeon.hpp5
-rw-r--r--src/dungeon_flag_list.hpp2
-rw-r--r--src/dungeon_info_type.hpp12
-rw-r--r--src/effect_type.hpp16
-rw-r--r--src/ego_item_type.hpp10
-rw-r--r--src/fate.hpp6
-rw-r--r--src/feature_type.hpp6
-rw-r--r--src/files.cc625
-rw-r--r--src/files.h15
-rw-r--r--src/files.hpp30
-rw-r--r--src/flag_set.hpp15
-rw-r--r--src/flags_group.hpp2
-rw-r--r--src/format_ext.cc24
-rw-r--r--src/format_ext.hpp33
-rw-r--r--src/frontend.cc1
-rw-r--r--src/frontend.hpp107
-rw-r--r--src/frontend_fwd.hpp3
-rw-r--r--src/game.cc756
-rw-r--r--src/game.hpp34
-rw-r--r--src/game_edit_data.cc18
-rw-r--r--src/game_edit_data.hpp11
-rw-r--r--src/gen_evol.cc40
-rw-r--r--src/gen_evol.hpp6
-rw-r--r--src/gen_maze.cc8
-rw-r--r--src/gen_maze.hpp4
-rw-r--r--src/generate.cc1026
-rw-r--r--src/generate.hpp12
-rw-r--r--src/gods.cc38
-rw-r--r--src/gods.hpp10
-rw-r--r--src/h-basic.h27
-rw-r--r--src/h-basic.hpp134
-rw-r--r--src/h-config.h84
-rw-r--r--src/h-define.h92
-rw-r--r--src/h-system.h90
-rw-r--r--src/h-type.h187
-rw-r--r--src/help.cc70
-rw-r--r--src/help.hpp4
-rw-r--r--src/help_info.hpp8
-rw-r--r--src/hiscore.cc7
-rw-r--r--src/hiscore.hpp2
-rw-r--r--src/hook_build_room1_in.hpp2
-rw-r--r--src/hook_calculate_hp_in.hpp2
-rw-r--r--src/hook_calculate_hp_out.hpp2
-rw-r--r--src/hook_chardump_in.hpp2
-rw-r--r--src/hook_chat_in.hpp2
-rw-r--r--src/hook_eat_out.hpp7
-rw-r--r--src/hook_enter_dungeon_in.hpp2
-rw-r--r--src/hook_identify_in.hpp2
-rw-r--r--src/hook_mon_speak_in.hpp4
-rw-r--r--src/hook_monster_ai_in.hpp2
-rw-r--r--src/hook_monster_ai_out.hpp2
-rw-r--r--src/hook_monster_death_in.hpp2
-rw-r--r--src/hook_new_monster_in.hpp2
-rw-r--r--src/hook_quest_fail_in.hpp2
-rw-r--r--src/hook_quest_finish_in.hpp2
-rw-r--r--src/hook_quest_gen_in.hpp9
-rw-r--r--src/hook_stair_out.hpp4
-rw-r--r--src/hook_wild_gen_in.hpp4
-rw-r--r--src/hooks.cc12
-rw-r--r--src/hooks.hpp4
-rw-r--r--src/identify_mode.hpp3
-rw-r--r--src/include/tome/enum_string_map.hpp8
-rw-r--r--src/include/tome/squelch/condition.hpp56
-rw-r--r--src/include/tome/squelch/object_status.hpp4
-rw-r--r--src/include/tome/squelch/rule.hpp7
-rw-r--r--src/include/tome/unique_handle.hpp88
-rw-r--r--src/init1.cc613
-rw-r--r--src/init1.hpp4
-rw-r--r--src/init2.cc115
-rw-r--r--src/init2.h13
-rw-r--r--src/init2.hpp5
-rw-r--r--src/inscription_info_type.hpp2
-rw-r--r--src/joke.cc8
-rw-r--r--src/joke.hpp2
-rw-r--r--src/key_queue.cc1
-rw-r--r--src/key_queue.hpp76
-rw-r--r--src/key_queue_fwd.hpp3
-rw-r--r--src/level_data.cc1
-rw-r--r--src/level_data.hpp56
-rw-r--r--src/levels.cc238
-rw-r--r--src/levels.hpp51
-rw-r--r--src/loadsave.cc533
-rw-r--r--src/loadsave.h15
-rw-r--r--src/loadsave.hpp11
-rw-r--r--src/lua_bind.cc10
-rw-r--r--src/lua_bind.hpp4
-rw-r--r--src/magic_power.hpp12
-rw-r--r--src/main-gcu.cc (renamed from src/main-gcu.c)473
-rw-r--r--src/main-gtk2.cc (renamed from src/main-gtk2.c)736
-rw-r--r--src/main-sdl.c2113
-rw-r--r--src/main-win.cc (renamed from src/main-win.c)384
-rw-r--r--src/main-x11.cc (renamed from src/main-x11.c)1349
-rw-r--r--src/main.cc76
-rw-r--r--src/main.hpp (renamed from src/main.h)8
-rw-r--r--src/martial_arts.hpp16
-rw-r--r--src/melee1.cc195
-rw-r--r--src/melee1.hpp6
-rw-r--r--src/melee2.cc2653
-rw-r--r--src/melee2.hpp6
-rw-r--r--src/message.hpp2
-rw-r--r--src/messages.cc2
-rw-r--r--src/messages.hpp4
-rw-r--r--src/mimic.cc63
-rw-r--r--src/mimic.hpp10
-rw-r--r--src/module_type.hpp14
-rw-r--r--src/modules.cc168
-rw-r--r--src/modules.hpp11
-rw-r--r--src/monster1.cc295
-rw-r--r--src/monster2.cc588
-rw-r--r--src/monster2.hpp50
-rw-r--r--src/monster3.cc174
-rw-r--r--src/monster3.hpp28
-rw-r--r--src/monster_blow.hpp2
-rw-r--r--src/monster_ego.hpp4
-rw-r--r--src/monster_power.hpp10
-rw-r--r--src/monster_race.hpp4
-rw-r--r--src/monster_type.hpp4
-rw-r--r--src/move_info_type.hpp4
-rw-r--r--src/music.hpp2
-rw-r--r--src/notes.cc51
-rw-r--r--src/obj_theme.hpp2
-rw-r--r--src/object1.cc1328
-rw-r--r--src/object1.hpp24
-rw-r--r--src/object2.cc1021
-rw-r--r--src/object2.hpp34
-rw-r--r--src/object_filter.hpp2
-rw-r--r--src/object_flag_list.hpp1
-rw-r--r--src/object_kind.hpp28
-rw-r--r--src/object_kind_fwd.hpp3
-rw-r--r--src/object_proto.hpp2
-rw-r--r--src/object_type.hpp10
-rw-r--r--src/option_type.hpp8
-rw-r--r--src/options.cc10
-rw-r--r--src/options.hpp132
-rw-r--r--src/owner_type.hpp9
-rw-r--r--src/player_class.hpp6
-rw-r--r--src/player_level_flag.hpp2
-rw-r--r--src/player_race.hpp4
-rw-r--r--src/player_race_ability_type.hpp2
-rw-r--r--src/player_race_mod.hpp12
-rw-r--r--src/player_shared.hpp2
-rw-r--r--src/player_spec.hpp2
-rw-r--r--src/player_type.hpp211
-rw-r--r--src/power_activation.hpp12
-rw-r--r--src/power_type.hpp34
-rw-r--r--src/powers.cc261
-rw-r--r--src/powers.hpp1
-rw-r--r--src/program_args.cc1
-rw-r--r--src/program_args.hpp32
-rw-r--r--src/q_betwen.cc43
-rw-r--r--src/q_betwen.hpp2
-rw-r--r--src/q_bounty.cc53
-rw-r--r--src/q_bounty.hpp6
-rw-r--r--src/q_dragons.cc21
-rw-r--r--src/q_dragons.hpp2
-rw-r--r--src/q_eol.cc26
-rw-r--r--src/q_eol.hpp2
-rw-r--r--src/q_evil.cc17
-rw-r--r--src/q_evil.hpp2
-rw-r--r--src/q_fireprof.cc59
-rw-r--r--src/q_fireprof.hpp4
-rw-r--r--src/q_god.cc45
-rw-r--r--src/q_god.hpp2
-rw-r--r--src/q_haunted.cc19
-rw-r--r--src/q_haunted.hpp2
-rw-r--r--src/q_hobbit.cc30
-rw-r--r--src/q_hobbit.hpp2
-rw-r--r--src/q_invas.cc29
-rw-r--r--src/q_invas.hpp2
-rw-r--r--src/q_library.cc40
-rw-r--r--src/q_library.hpp4
-rw-r--r--src/q_main.cc7
-rw-r--r--src/q_main.hpp2
-rw-r--r--src/q_narsil.cc19
-rw-r--r--src/q_narsil.hpp2
-rw-r--r--src/q_nazgul.cc21
-rw-r--r--src/q_nazgul.hpp2
-rw-r--r--src/q_nirna.cc11
-rw-r--r--src/q_nirna.hpp2
-rw-r--r--src/q_one.cc23
-rw-r--r--src/q_one.hpp2
-rw-r--r--src/q_poison.cc53
-rw-r--r--src/q_poison.hpp2
-rw-r--r--src/q_rand.cc68
-rw-r--r--src/q_rand.hpp4
-rw-r--r--src/q_shroom.cc52
-rw-r--r--src/q_shroom.hpp2
-rw-r--r--src/q_spider.cc14
-rw-r--r--src/q_spider.hpp2
-rw-r--r--src/q_thief.cc32
-rw-r--r--src/q_thief.hpp2
-rw-r--r--src/q_thrain.cc20
-rw-r--r--src/q_thrain.hpp2
-rw-r--r--src/q_troll.cc29
-rw-r--r--src/q_troll.hpp2
-rw-r--r--src/q_ultrae.hpp2
-rw-r--r--src/q_ultrag.cc42
-rw-r--r--src/q_ultrag.hpp2
-rw-r--r--src/q_wight.cc17
-rw-r--r--src/q_wight.hpp2
-rw-r--r--src/q_wolves.cc15
-rw-r--r--src/q_wolves.hpp2
-rw-r--r--src/quest_type.hpp4
-rw-r--r--src/randart.cc64
-rw-r--r--src/randart.hpp8
-rw-r--r--src/randart_part_type.hpp2
-rw-r--r--src/random_artifact.hpp2
-rw-r--r--src/random_quest.hpp2
-rw-r--r--src/random_spell.hpp2
-rw-r--r--src/range.hpp2
-rw-r--r--src/rule_type.hpp2
-rw-r--r--src/school_book.hpp2
-rw-r--r--src/school_type.hpp10
-rw-r--r--src/set_component.hpp4
-rw-r--r--src/skill_descriptor.hpp2
-rw-r--r--src/skill_modifier.hpp2
-rw-r--r--src/skill_modifiers.hpp2
-rw-r--r--src/skill_type.hpp2
-rw-r--r--src/skills.cc185
-rw-r--r--src/skills.hpp19
-rw-r--r--src/spell_type.cc66
-rw-r--r--src/spell_type.hpp42
-rw-r--r--src/spell_type_fwd.hpp3
-rw-r--r--src/spellbinder.hpp2
-rw-r--r--src/spells1.cc1040
-rw-r--r--src/spells1.hpp29
-rw-r--r--src/spells2.cc940
-rw-r--r--src/spells2.hpp142
-rw-r--r--src/spells3.cc1899
-rw-r--r--src/spells3.hpp221
-rw-r--r--src/spells4.cc29
-rw-r--r--src/spells4.hpp8
-rw-r--r--src/spells5.cc99
-rw-r--r--src/spells5.hpp6
-rw-r--r--src/spells6.cc39
-rw-r--r--src/squelch/automatizer.cc2
-rw-r--r--src/squelch/condition.cc263
-rw-r--r--src/squelch/condition_metadata.cc28
-rw-r--r--src/squelch/jsoncons_helpers.hpp27
-rw-r--r--src/squelch/object_status.cc40
-rw-r--r--src/squelch/rule.cc28
-rw-r--r--src/squelch/tree_printer.cc6
-rw-r--r--src/squeltch.cc50
-rw-r--r--src/squeltch.hpp3
-rw-r--r--src/store.cc510
-rw-r--r--src/store_action_type.hpp5
-rw-r--r--src/store_info_type.hpp2
-rw-r--r--src/store_item.hpp49
-rw-r--r--src/store_type.hpp2
-rw-r--r--src/tables.cc757
-rw-r--r--src/tables.h12
-rw-r--r--src/tables.hpp17
-rw-r--r--src/tactic_info_type.hpp4
-rw-r--r--src/timer_type.hpp2
-rw-r--r--src/town_type.hpp8
-rw-r--r--src/util.cc948
-rw-r--r--src/util.h19
-rw-r--r--src/util.hpp95
-rw-r--r--src/variable.cc114
-rw-r--r--src/variable.h31
-rw-r--r--src/variable.hpp98
-rw-r--r--src/vault_type.hpp2
-rw-r--r--src/wild.cc203
-rw-r--r--src/wilderness_map.hpp4
-rw-r--r--src/wilderness_type_info.hpp2
-rw-r--r--src/wizard2.cc271
-rw-r--r--src/wizard2.hpp4
-rw-r--r--src/xtra1.cc700
-rw-r--r--src/xtra1.hpp8
-rw-r--r--src/xtra2.cc788
-rw-r--r--src/xtra2.hpp131
-rw-r--r--src/z-form.cc (renamed from src/z-form.c)68
-rw-r--r--src/z-form.hpp (renamed from src/z-form.h)18
-rw-r--r--src/z-rand.cc8
-rw-r--r--src/z-rand.hpp27
-rw-r--r--src/z-term.cc (renamed from src/z-term.c)1163
-rw-r--r--src/z-term.h269
-rw-r--r--src/z-term.hpp108
-rw-r--r--src/z-util.cc (renamed from src/z-util.c)48
-rw-r--r--src/z-util.h41
-rw-r--r--src/z-util.hpp17
-rw-r--r--tests/arbitrary/boost_optional.cc1
-rw-r--r--tests/arbitrary/boost_optional.hpp60
l---------vendor/CppQuickCheck1
-rw-r--r--vendor/CppQuickCheck-2018-03-28/.travis.yml36
-rw-r--r--vendor/CppQuickCheck-2018-03-28/CMakeLists.txt32
-rw-r--r--vendor/CppQuickCheck-2018-03-28/COPYING23
-rw-r--r--vendor/CppQuickCheck-2018-03-28/INSTALL11
-rw-r--r--vendor/CppQuickCheck-2018-03-28/LICENSE21
-rw-r--r--vendor/CppQuickCheck-2018-03-28/README.md74
-rw-r--r--vendor/CppQuickCheck-2018-03-28/examples/CMakeLists.txt33
-rw-r--r--vendor/CppQuickCheck-2018-03-28/examples/src/BoostTupleSupport.cpp131
-rw-r--r--vendor/CppQuickCheck-2018-03-28/examples/src/TestChooseGenerator.cpp54
-rw-r--r--vendor/CppQuickCheck-2018-03-28/examples/src/TestReverse.cpp59
-rw-r--r--vendor/CppQuickCheck-2018-03-28/examples/src/TestReverseArray.cpp69
-rw-r--r--vendor/CppQuickCheck-2018-03-28/examples/src/TestSlowShrinking.cpp61
-rw-r--r--vendor/CppQuickCheck-2018-03-28/examples/src/TestSort.cpp79
-rw-r--r--vendor/CppQuickCheck-2018-03-28/examples/src/TestSortCompact.cpp95
-rw-r--r--vendor/CppQuickCheck-2018-03-28/examples/src/TestWithCustomGenerator.cpp86
-rw-r--r--vendor/CppQuickCheck-2018-03-28/examples/src/exampleElementsGen.cpp55
-rw-r--r--vendor/CppQuickCheck-2018-03-28/examples/src/sampleOutput.cpp73
-rw-r--r--vendor/CppQuickCheck-2018-03-28/examples/src/sampleShrinkOutput.cpp82
-rw-r--r--vendor/CppQuickCheck-2018-03-28/include/cppqc.h9
-rw-r--r--vendor/CppQuickCheck-2018-03-28/include/cppqc/Arbitrary.h446
-rw-r--r--vendor/CppQuickCheck-2018-03-28/include/cppqc/CompactCheck.h178
-rw-r--r--vendor/CppQuickCheck-2018-03-28/include/cppqc/Generator.h1355
-rw-r--r--vendor/CppQuickCheck-2018-03-28/include/cppqc/PrettyPrint.h69
-rw-r--r--vendor/CppQuickCheck-2018-03-28/include/cppqc/Property.h461
-rw-r--r--vendor/CppQuickCheck-2018-03-28/include/cppqc/Test.h330
-rw-r--r--vendor/CppQuickCheck-2018-03-28/include/cppqc/cxx-prettyprint.h472
-rw-r--r--vendor/CppQuickCheck-2018-03-28/src/Arbitrary.cpp80
-rw-r--r--vendor/CppQuickCheck-2018-03-28/test/catch-main.cpp27
-rw-r--r--vendor/CppQuickCheck-2018-03-28/test/catch.hpp9427
-rw-r--r--vendor/CppQuickCheck-2018-03-28/test/compact-check-tests.cpp82
-rw-r--r--vendor/CppQuickCheck-2018-03-28/test/functional-tests.cpp110
-rw-r--r--vendor/CppQuickCheck-2018-03-28/test/shrink-explosion-protection.cpp173
l---------vendor/fmt2
-rw-r--r--vendor/fmt-3.0.1/fmt/format.cc940
-rw-r--r--vendor/fmt-3.0.1/fmt/time.h53
-rw-r--r--vendor/fmt-4.1.0/fmt/CMakeLists.txt (renamed from vendor/fmt-3.0.1/fmt/CMakeLists.txt)37
-rw-r--r--vendor/fmt-4.1.0/fmt/container.h82
-rw-r--r--vendor/fmt-4.1.0/fmt/format.cc495
-rw-r--r--vendor/fmt-4.1.0/fmt/format.h (renamed from vendor/fmt-3.0.1/fmt/format.h)776
-rw-r--r--vendor/fmt-4.1.0/fmt/ostream.cc (renamed from vendor/fmt-3.0.1/fmt/ostream.cc)14
-rw-r--r--vendor/fmt-4.1.0/fmt/ostream.h (renamed from vendor/fmt-3.0.1/fmt/ostream.h)63
-rw-r--r--vendor/fmt-4.1.0/fmt/posix.cc (renamed from vendor/fmt-3.0.1/fmt/posix.cc)5
-rw-r--r--vendor/fmt-4.1.0/fmt/posix.h (renamed from vendor/fmt-3.0.1/fmt/posix.h)65
-rw-r--r--vendor/fmt-4.1.0/fmt/printf.cc32
-rw-r--r--vendor/fmt-4.1.0/fmt/printf.h603
-rw-r--r--vendor/fmt-4.1.0/fmt/string.h148
-rw-r--r--vendor/fmt-4.1.0/fmt/time.h143
l---------vendor/jsoncons2
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/detail/heap_only_string.hpp155
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/detail/number_parsers.hpp266
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/detail/number_printers.hpp374
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/detail/obufferedstream.hpp264
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/detail/type_traits_helper.hpp226
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/detail/unicode_traits.hpp1463
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/detail/writer.hpp155
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/json.hpp4959
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/json_decoder.hpp310
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/json_deserializer.hpp12
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/json_error_category.hpp (renamed from vendor/jsoncons-0.99.2/jsoncons/json_error_category.hpp)99
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/json_exception.hpp107
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/json_filter.hpp465
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/json_input_handler.hpp308
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/json_output_handler.hpp (renamed from vendor/jsoncons-0.99.2/jsoncons/json_output_handler.hpp)170
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/json_parser.hpp2830
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/json_reader.hpp408
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/json_serializer.hpp585
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/json_structures.hpp1864
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/json_type_traits.hpp966
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/jsoncons_config.hpp106
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/jsoncons_utilities.hpp954
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/parse_error_handler.hpp165
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/serialization_options.hpp279
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/serialization_traits.hpp315
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons/version.hpp50
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons_ext/binary/binary_utilities.hpp354
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons_ext/cbor/cbor.hpp2792
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_error_category.hpp (renamed from vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_error_category.hpp)37
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_parameters.hpp635
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_parser.hpp1260
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_reader.hpp235
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_serializer.hpp504
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons_ext/jsonpatch/jsonpatch.hpp530
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons_ext/jsonpatch/jsonpatch_error_category.hpp82
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons_ext/jsonpath/json_query.hpp1119
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons_ext/jsonpath/jsonpath_error_category.hpp (renamed from vendor/jsoncons-0.99.2/jsoncons_ext/jsonpath/jsonpath_error_category.hpp)50
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons_ext/jsonpath/jsonpath_filter.hpp1874
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons_ext/jsonpointer/jsonpointer.hpp810
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons_ext/jsonpointer/jsonpointer_error_category.hpp87
-rw-r--r--vendor/jsoncons-0.104.0/jsoncons_ext/msgpack/msgpack.hpp795
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/json.hpp3574
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/json_deserializer.hpp267
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/json_filter.hpp324
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/json_input_handler.hpp282
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/json_parser.hpp1587
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/json_parser.hpp.orig2157
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/json_reader.hpp176
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/json_serializer.hpp435
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/json_structures.hpp860
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/json_type_traits.hpp594
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/jsoncons.hpp347
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/jsoncons_config.hpp123
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/jsoncons_io.hpp358
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/output_format.hpp330
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/ovectorstream.hpp227
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/parse_error_handler.hpp172
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons_ext/boost/type_extensions.hpp59
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_parameters.hpp341
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_parser.hpp903
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_reader.hpp175
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_serializer.hpp445
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons_ext/jsonpath/json_query.hpp921
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons_ext/jsonpath/jsonpath_filter.hpp1495
541 files changed, 61638 insertions, 44767 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cf31d878..7f265aef 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
# Project definition.
PROJECT (tome2)
-CMAKE_MINIMUM_REQUIRED (VERSION 3.1)
+CMAKE_MINIMUM_REQUIRED (VERSION 3.5)
# We want a readable feature summary.
INCLUDE(FeatureSummary)
@@ -9,6 +9,11 @@ INCLUDE(FeatureSummary)
INCLUDE(FindPkgConfig)
#
+# C++ standard
+#
+SET(CMAKE_CXX_STANDARD 17)
+
+#
# Basic common compiler flags.
#
SET(COMMON_COMPILER_FLAGS "-pipe -Wall -Wextra -Wno-unused-value -Wno-unused-parameter")
@@ -28,7 +33,8 @@ SET(CMAKE_C_FLAGS_DEBUG "-O0 -g ${SANITIZER_FLAGS}")
#
# C++ Compiler Flags
#
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_COMPILER_FLAGS} --std=c++14")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_COMPILER_FLAGS}")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DJSONCONS_NO_DEPRECATED")
SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g ${SANITIZER_FLAGS} -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC")
@@ -77,19 +83,6 @@ FIND_PACKAGE(X11)
FIND_PACKAGE(GTK2)
#
-# SDL support (OPTIONAL)
-#
-FIND_PACKAGE(SDL)
-IF(SDL_FOUND)
- # We assume that if we want to compile for SDL that
- # any required dependencies should be installed.
- FIND_PACKAGE(SDL_image)
- FIND_PACKAGE(SDL_ttf)
- SET_PACKAGE_PROPERTIES(SDL_image PROPERTIES TYPE REQUIRED)
- SET_PACKAGE_PROPERTIES(SDL_ttf PROPERTIES TYPE REQUIRED)
-ENDIF()
-
-#
# Curses support (OPTIONAL)
#
FIND_PACKAGE(Curses)
diff --git a/README.md b/README.md
index 9ab5b368..994ba3e1 100644
--- a/README.md
+++ b/README.md
@@ -65,7 +65,6 @@ packages.
Each frontend requires the additional packages listed below:
- X11: `libx11-dev`
-- SDL: `libsdl-image1.2-dev` `libsdl-ttf2.0-dev`
- ncurses: `libncurses5-dev`
@@ -81,11 +80,6 @@ linking the executable. As a workaround, set the environment variable
$ env LDFLAGS=-L/usr/X11R6/lib cmake .
$ make
-The SDL frontend also requires these packages:
-
-- `sdl-image`
-- `sdl-ttf`
-
## Compiling on Windows using MinGW
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 15591830..721cee4d 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -2,7 +2,6 @@ INSTALL(DIRECTORY
apex
cmov
data
- dngn
edit
file
help
diff --git a/lib/dngn/dun1.14 b/lib/dngn/dun1.14
deleted file mode 100644
index 6421e80b..00000000
--- a/lib/dngn/dun1.14
+++ /dev/null
@@ -1,2 +0,0 @@
-# On this level there is a stairway leading to the Heart of the Earth
-B:10
diff --git a/lib/dngn/dun10.0 b/lib/dngn/dun10.0
deleted file mode 100644
index b89ce05e..00000000
--- a/lib/dngn/dun10.0
+++ /dev/null
@@ -1,3 +0,0 @@
-# Father branch is Mirkwood(1), on level 14
-A:1
-L:14
diff --git a/lib/dngn/dun11.20 b/lib/dngn/dun11.20
deleted file mode 100644
index 9cc611d3..00000000
--- a/lib/dngn/dun11.20
+++ /dev/null
@@ -1,2 +0,0 @@
-# On this level there is a stairway leading to the Nether Realm
-B:6
diff --git a/lib/dngn/dun11.22 b/lib/dngn/dun11.22
deleted file mode 100644
index 149e2c33..00000000
--- a/lib/dngn/dun11.22
+++ /dev/null
@@ -1,2 +0,0 @@
-#I'm downright evil
-F:NO_GENO |
diff --git a/lib/dngn/dun17.15 b/lib/dngn/dun17.15
deleted file mode 100644
index d08bf5e7..00000000
--- a/lib/dngn/dun17.15
+++ /dev/null
@@ -1,5 +0,0 @@
-N:Machine
-U:s_factory.map
-D:The clatter of strange machinery surrounds you.
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT
diff --git a/lib/dngn/dun18.0 b/lib/dngn/dun18.0
deleted file mode 100644
index da1b6c27..00000000
--- a/lib/dngn/dun18.0
+++ /dev/null
@@ -1,2 +0,0 @@
-# The level is SAVED in the playername.mz? file
-#S:mz0
diff --git a/lib/dngn/dun18.1 b/lib/dngn/dun18.1
deleted file mode 100644
index 70f27718..00000000
--- a/lib/dngn/dun18.1
+++ /dev/null
@@ -1,2 +0,0 @@
-# The level is SAVED in the playername.mz? file
-#S:mz1
diff --git a/lib/dngn/dun19.11 b/lib/dngn/dun19.11
deleted file mode 100644
index 7fba690d..00000000
--- a/lib/dngn/dun19.11
+++ /dev/null
@@ -1,5 +0,0 @@
-N:Deathwatch
-U:s_death.map
-D:This level looks filled with evilness.
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT
diff --git a/lib/dngn/dun2.31 b/lib/dngn/dun2.31
deleted file mode 100644
index dd8669a5..00000000
--- a/lib/dngn/dun2.31
+++ /dev/null
@@ -1,2 +0,0 @@
-# On this level there is a stairway leading to the Mount Doom
-B:5
diff --git a/lib/dngn/dun22.10 b/lib/dngn/dun22.10
deleted file mode 100644
index e7eb116e..00000000
--- a/lib/dngn/dun22.10
+++ /dev/null
@@ -1,2 +0,0 @@
-# On this level there is a stairway leading to the Small Water Cave
-B:24
diff --git a/lib/dngn/dun22.5 b/lib/dngn/dun22.5
deleted file mode 100644
index 11d8e51f..00000000
--- a/lib/dngn/dun22.5
+++ /dev/null
@@ -1,5 +0,0 @@
-N:Orc Town
-U:s_orc.map
-D:You hear orc warcries.
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT
diff --git a/lib/dngn/dun24.0 b/lib/dngn/dun24.0
deleted file mode 100644
index bbb93f85..00000000
--- a/lib/dngn/dun24.0
+++ /dev/null
@@ -1,3 +0,0 @@
-# Father branch is the Moria(22), on level 10
-A:22
-L:10
diff --git a/lib/dngn/dun29.15 b/lib/dngn/dun29.15
deleted file mode 100644
index 4df873b5..00000000
--- a/lib/dngn/dun29.15
+++ /dev/null
@@ -1,6 +0,0 @@
-N:Galleon
-U:s_ship.map
-D:A ship of antique design lies jammed in the ice here.
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT
-
diff --git a/lib/dngn/dun3.18 b/lib/dngn/dun3.18
deleted file mode 100644
index 84c0a74a..00000000
--- a/lib/dngn/dun3.18
+++ /dev/null
@@ -1,5 +0,0 @@
-N:Dim Gates
-U:s_gates.map
-D:Visions of death fill your mind.
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT
diff --git a/lib/dngn/dun3.28 b/lib/dngn/dun3.28
deleted file mode 100644
index 0acd4193..00000000
--- a/lib/dngn/dun3.28
+++ /dev/null
@@ -1,5 +0,0 @@
-N:Nameless
-U:s_name.map
-D:You sense a powerful artifact here.
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT
diff --git a/lib/dngn/dun3.3 b/lib/dngn/dun3.3
deleted file mode 100644
index 710ef5f8..00000000
--- a/lib/dngn/dun3.3
+++ /dev/null
@@ -1,5 +0,0 @@
-N:Crypt
-U:s_crypt.map
-D:Looks like a forgotten crypt...
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT
diff --git a/lib/dngn/dun5.0 b/lib/dngn/dun5.0
deleted file mode 100644
index 48a7bea6..00000000
--- a/lib/dngn/dun5.0
+++ /dev/null
@@ -1,3 +0,0 @@
-# Father branch is the Mordor, on level 32
-A:2
-L:31
diff --git a/lib/dngn/dun5.14 b/lib/dngn/dun5.14
deleted file mode 100644
index 3d7a3080..00000000
--- a/lib/dngn/dun5.14
+++ /dev/null
@@ -1,14 +0,0 @@
-# The level is SAVED in the playername.mdm file
-S:mdm
-
-# Use the map in s_doom.map file
-U:s_doom.map
-
-# Use Mt Doom as level name
-N:Mt Doom
-
-D:You finally reach the top of Mount Doom, here must lie the Great Fire.
-F:DESC
-F:NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:NO_TELEPORT
-
diff --git a/lib/dngn/dun6.0 b/lib/dngn/dun6.0
deleted file mode 100644
index c750ea67..00000000
--- a/lib/dngn/dun6.0
+++ /dev/null
@@ -1,3 +0,0 @@
-# Father branch is Void(11), on level 20
-A:11
-L:20
diff --git a/lib/edit/a_info.txt b/lib/edit/a_info.txt
index c1ab7fa1..643fc954 100644
--- a/lib/edit/a_info.txt
+++ b/lib/edit/a_info.txt
@@ -57,7 +57,6 @@ F:LITE3
F:SEE_INVIS
F:SPEED
a:MAP_LIGHT
-Z:detect curses
D:The shining Star of the West, a famed heirloom of Elendil's house.
@@ -381,25 +380,6 @@ D:wields it. It is rumoured that it may even protect the wearer from
D:the passing of time.
-# This artifact has a low artifact level to prevent it being worthless for
-# chars with poor magic skills.
-
-# The Stone of Lore
-
-N:15:of Lore
-I:39:106:0
-W:15:12:15:20000
-P:0:1d1:0:0:0
-F:ACTIVATE
-F:EASY_USE
-F:INSTA_ART
-F:LITE1
-F:SPECIAL_GENE
-a:STONE_LORE
-D:A great emerald that fills your mind with images of knowledge and dreadful
-D:understanding as you stare into its depths.
-
-
# The Multi-Hued Dragon Scale Mail 'Razorback'
N:16:'Razorback'
@@ -2815,7 +2795,7 @@ F:SLAY_EVIL
F:SPELL_CONTAIN
F:WIELD_CAST
F:WIS
-a:ID_PLAIN
+a:DETECT_ALL
D:The radiant golden staff of an Istari of legend, this wizard's companion
D:grants keen sight and the knowledge of many hidden things.
@@ -3672,23 +3652,6 @@ D:Crafted of purest ice and held solid by powerful spells, this icy axe
D:delivers a chill of death to its victims.
-# The Iron Helm of Knowledge
-
-N:160:of Knowledge
-I:32:5:-6
-W:20:5:75:100000
-P:6:1d3:0:0:20
-F:ACTIVATE
-F:AUTO_ID
-F:HIDE_TYPE
-F:LITE1
-F:LUCK
-F:SPECIAL_GENE
-a:KNOWLEDGE
-D:This helm, designed by Petty-Dwarves ages ago to act as the brain of a
-D:long lost project, is made of finest glass. Its light banishes all secrets,
-D:and makes audible whispers from the deceased.
-
# The Broken Sword 'Narsil'
N:164:'Narsil'
diff --git a/lib/edit/ba_info.txt b/lib/edit/ba_info.txt
index 20e7bb77..ed95662e 100644
--- a/lib/edit/ba_info.txt
+++ b/lib/edit/ba_info.txt
@@ -69,10 +69,6 @@ N:13:Game rules
C:0:0:0
I:13:0:r
-N:14:Research item
-C:1400:1300:1200
-I:1:0:a
-
N:15:Town history
C:0:0:0
I:2:0:h
@@ -109,10 +105,6 @@ N:26:Recharge item
C:350:300:75
I:25:0:r
-N:27:Identify possessions
-C:900:800:100
-I:26:0:i
-
N:28:Healing prayer
C:600:400:0
I:28:0:h
@@ -168,11 +160,6 @@ C:1500:1500:1500
I:1:0:a
#for Star-Dome
-N:46:Identify possessions
-C:1200:1000:250
-I:26:0:i
-
-#for Star-Dome
N:47:Recharge item
C:1200:1000:150
I:25:0:r
diff --git a/lib/edit/d_info.txt b/lib/edit/d_info.txt
index fe20c276..9c73ccd2 100644
--- a/lib/edit/d_info.txt
+++ b/lib/edit/d_info.txt
@@ -56,6 +56,7 @@ F:NO_DESTROY
F:NO_DOORS
F:PRINCIPAL
R:100:0
+@:14:B:10
N:2:Mordor
D:Mdr:a door to the Land of Mordor.
@@ -71,6 +72,7 @@ F:LAVA_RIVER
F:NO_STREAMERS
F:PRINCIPAL
R:100:0
+@:31:B:5
N:3:Angband
D:Ang:an entrance to the Pits of Angband.
@@ -86,6 +88,33 @@ F:NO_EASY_MOVE
F:NO_RECALL
F:PRINCIPAL
R:100:0
+@:3:N:Crypt
+@:3:U:s_crypt.map
+@:3:D:Looks like a forgotten crypt...
+@:3:F:NO_GENO
+@:3:F:NO_NEW_MONSTER
+@:3:F:SPECIAL
+@:3:F:NO_STAIR
+@:3:F:ASK_LEAVE
+@:3:F:NO_TELEPORT
+@:18:N:Dim Gates
+@:18:U:s_gates.map
+@:18:D:Visions of death fill your mind.
+@:18:F:NO_GENO
+@:18:F:NO_NEW_MONSTER
+@:18:F:SPECIAL
+@:18:F:NO_STAIR
+@:18:F:ASK_LEAVE
+@:18:F:NO_TELEPORT
+@:28:N:Nameless
+@:28:U:s_name.map
+@:28:D:You sense a powerful artifact here.
+@:28:F:NO_GENO
+@:28:F:NO_NEW_MONSTER
+@:28:F:SPECIAL
+@:28:F:NO_STAIR
+@:28:F:ASK_LEAVE
+@:28:F:NO_TELEPORT
N:4:Barrow-Downs
D:BDw:a way to the Barrow-Downs.
@@ -122,6 +151,15 @@ F:NO_STREAMERS
F:NO_UP
R:100:1
M:IM_FIRE
+@:14:N:Mt Doom
+@:14:S:mdm
+@:14:U:s_doom.map
+@:14:D:You finally reach the top of Mount Doom, here must lie the Great Fire.
+@:14:F:NO_GENO
+@:14:F:NO_NEW_MONSTER
+@:14:F:SPECIAL
+@:14:F:NO_STAIR
+@:14:F:NO_TELEPORT
# Nether Realm
# Levels 666-696 (!!!)
@@ -273,6 +311,8 @@ M:DRAGON
M:NONLIVING
M:SPIRIT
M:UNDEAD
+@:20:B:6
+@:22:F:NO_GENO
# TEST dungeon
N:12:Test
@@ -311,7 +351,7 @@ M:UNDEAD
# The Illusory Castle
# levels 35-52
-# Guarded by The Glass Golem guarding The Helm of Knowledge
+# Guarded by The Glass Golem
N:17:Illusory Castle
D:Ill:an entrance to the Illusory Castle.
W:35:52:10:24:100
@@ -320,7 +360,6 @@ A:56:50:189:50:56:0:57:58
O:50:10:20:20
E:6d2:6:CONFUSION
F:FILL_METHOD_1
-F:FINAL_ARTIFACT_160
F:FINAL_GUARDIAN_1033
F:NO_STREAMERS
F:RANDOM_TOWNS
@@ -343,6 +382,15 @@ S:BR_CONF
S:CONF
S:FORGET
S:MULTIPLY
+@:15:N:Machine
+@:15:U:s_factory.map
+@:15:D:The clatter of strange machinery surrounds you.
+@:15:F:NO_GENO
+@:15:F:NO_NEW_MONSTER
+@:15:F:SPECIAL
+@:15:F:NO_STAIR
+@:15:F:ASK_LEAVE
+@:15:F:NO_TELEPORT
# The Maze
# Levels 25-37
@@ -384,6 +432,15 @@ M:ORC
M:R_CHAR_O
M:R_CHAR_k
M:R_CHAR_o
+@:11:N:Deathwatch
+@:11:U:s_death.map
+@:11:D:This level looks filled with evilness.
+@:11:F:NO_GENO
+@:11:F:NO_NEW_MONSTER
+@:11:F:SPECIAL
+@:11:F:NO_STAIR
+@:11:F:ASK_LEAVE
+@:11:F:NO_TELEPORT
# Erebor
# levels 60-72
@@ -461,6 +518,16 @@ M:TROLL
R:20:3
M:DEMON
R:10:0
+@:5:N:Orc Town
+@:5:U:s_orc.map
+@:5:D:You hear orc warcries.
+@:5:F:NO_GENO
+@:5:F:NO_NEW_MONSTER
+@:5:F:SPECIAL
+@:5:F:NO_STAIR
+@:5:F:ASK_LEAVE
+@:5:F:NO_TELEPORT
+@:10:B:24
# The tower of Dol Guldur
# Levels 57-70
@@ -607,6 +674,15 @@ F:NO_STREAMERS
F:WATER_RIVER
R:100:1
M:IM_COLD
+@:15:N:Galleon
+@:15:U:s_ship.map
+@:15:D:A ship of antique design lies jammed in the ice here.
+@:15:F:NO_GENO
+@:15:F:NO_NEW_MONSTER
+@:15:F:SPECIAL
+@:15:F:NO_STAIR
+@:15:F:ASK_LEAVE
+@:15:F:NO_TELEPORT
# The Lost Temple of "..player.pgod.."
# Generated in god quest.
diff --git a/lib/edit/k_info.txt b/lib/edit/k_info.txt
index 1f97827b..5e93d95d 100644
--- a/lib/edit/k_info.txt
+++ b/lib/edit/k_info.txt
@@ -1839,22 +1839,6 @@ A:15/1
D:This scroll will try to enchant a piece of armour in your possession, making it more effective
D:in protecting you. Highly enchanted armour is likely not to accept this enchantment, however.
-N:176:Identify
-G:?:d
-I:70:12:0
-W:1:0:5:50
-A:1/1:5/1:10/1:30/1
-D:If you read this scroll, the identity of an item you specify will be laid open to you.
-
-N:177:*Identify*
-G:?:d
-I:70:13:0
-W:30:0:5:1000
-A:30/1:50/2:80/1:100/1
-D:This scroll will allow you to gain insight into an object's special properties.
-D:Only the highly magical objects, like rare rings and amulets or very unusual weapons
-D:and armour possess abilities which warrant the use of this magic.
-
N:178:Rumour
G:?:d
I:70:51:0
@@ -2963,13 +2947,6 @@ W:30:0:50:100
A:30/1
P:0:1d2:0:0:0
-N:313:Identify
-G:_:d
-I:55:14:-1:SPELL=Identify
-W:10:0:50:100
-A:10/1
-P:0:1d2:0:0:0
-
N:314:Sense Hidden
G:_:d
I:55:15:-1:SPELL=Sense Hidden
@@ -3135,64 +3112,6 @@ D:A thick book with solid leather binding. It looks entirely
D:unremarkable, but as you hold it, you feel strangely able
D:to learn the inner workings of things and creatures.
-##### Chests #####
-
-N:338:& Small wooden chest~
-G:~:s
-I:7:1:0
-W:5:0:250:20
-A:5/1
-P:0:2d3:0:0:0
-D:A small wooden box, locked and possibly trapped. You wonder what might be inside.
-
-N:339:& Large wooden chest~
-G:~:s
-I:7:5:0
-W:15:0:500:60
-A:15/1
-P:0:2d5:0:0:0
-D:A large wooden box. It doesn't seem to be locked - why not risk a look inside?
-
-N:340:& Small iron chest~
-G:~:s
-I:7:2:0
-W:25:0:300:100
-A:25/1
-P:0:2d4:0:0:0
-D:A small rectangular container made of wood and reinforced with iron corners and latches.
-
-N:341:& Large iron chest~
-G:~:s
-I:7:6:0
-W:35:0:1000:150
-A:35/1
-P:0:2d6:0:0:0
-D:A big container made of wood, with a heavy iron lock.
-
-N:342:& Small steel chest~
-G:~:s
-I:7:3:0
-W:45:0:500:200
-A:45/1
-P:0:2d4:0:0:0
-D:A small wooden box with strong steel locks and reinforcements.
-
-N:343:& Large steel chest~
-G:~:s
-I:7:7:0
-W:55:0:1000:250
-A:55/1
-P:0:2d6:0:0:0
-D:A nearly indestructible chest of wood and steel. The lock doesn't look impenetrable, but it
-D:might be trapped.
-
-N:344:& Ruined chest~
-G:~:s
-I:7:0:0
-W:0:0:250:0
-A:75/1
-D:A broken, empty chest.
-
##### Various Stuff #####
N:345:& Iron Spike~
@@ -3406,14 +3325,6 @@ A:65/4
P:0:1d1:0:0:0
D:This rod grants you knowledge of your surroundings.
-N:372:Perception
-G:-:d
-I:66:2:20
-W:50:0:15:13000
-A:50/8:100/8
-P:0:1d1:0:0:0
-D:This rod makes you insightful, laying open the identity of your possessions.
-
N:373:Curing
G:-:d
I:66:8:35
@@ -5152,94 +5063,6 @@ A:40/3
D:This parchment contains information about unique
D:artifacts that are rumoured to exist upon Arda.
-N:594:Monstrous Compendium 1
-G:?:o
-I:8:9:0
-W:10:0:5:50
-A:10/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:595:Monstrous Compendium 2
-G:?:o
-I:8:10:0
-W:11:0:5:50
-A:11/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:596:Monstrous Compendium 3
-G:?:o
-I:8:11:0
-W:12:0:5:50
-A:12/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:597:Monstrous Compendium 4
-G:?:o
-I:8:12:0
-W:13:0:5:50
-A:13/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:598:Monstrous Compendium 5
-G:?:o
-I:8:13:0
-W:14:0:5:50
-A:14/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:599:Monstrous Compendium 6
-G:?:o
-I:8:14:0
-W:15:0:5:50
-A:15/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:600:Monstrous Compendium 7
-G:?:o
-I:8:15:0
-W:16:0:5:50
-A:16/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:601:Monstrous Compendium 8
-G:?:o
-I:8:16:0
-W:17:0:5:50
-A:17/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:602:Monstrous Compendium 9
-G:?:o
-I:8:17:0
-W:18:0:5:50
-A:18/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:603:Monstrous Compendium 10
-G:?:o
-I:8:18:0
-W:19:0:5:50
-A:19/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:604:Monstrous Compendium 11
-G:?:o
-I:8:19:0
-W:20:0:5:50
-A:20/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
#### Here come the shape-shifting potions. ####
N:605:& Morphic Oil~ of #
@@ -5327,14 +5150,6 @@ F:RES_FIRE
D:This suit of thick impregnated cloth is worn by the riders of flying steeds,
D:and protects them from extremes of temperatures.
-# The Stone of Lore -- see artifact list
-N:647:& Stone~
-G:~:g
-I:39:106:0
-W:15:0:15:20000
-F:INSTA_ART
-F:SPECIAL_GENE
-
# Here are the boomerangs
N:648:& Small Wooden Boomerang~
diff --git a/lib/edit/p_info.txt b/lib/edit/p_info.txt
index 5cb2e5cd..f00948aa 100644
--- a/lib/edit/p_info.txt
+++ b/lib/edit/p_info.txt
@@ -514,7 +514,7 @@ C:a:O:36:6:1d1
C:a:k:+0:-100:Combat
C:a:k:+0:-100:Weaponmastery
C:a:k:+0:-300:Archery
-C:a:k:-1000:-700:Barehand-combat
+C:a:k:+0:-100:Barehand-combat
C:a:k:+0:-200:Spirituality
C:a:k:+1000:+300:Possession
C:a:k:+0:+200:Corpse-preservation
@@ -631,7 +631,6 @@ C:D:1:Pope
C:S:-1:-3:3:-1:0:2:0:0
C:B:4:35:3
C:P:2:20
-C:Z:detect curses
C:G:GOD_FRIEND
C:E:0:0:0:0:0:0
C:k:+1000:+900:Magic
diff --git a/lib/edit/ra_info.txt b/lib/edit/ra_info.txt
index 6ac58484..85da205b 100644
--- a/lib/edit/ra_info.txt
+++ b/lib/edit/ra_info.txt
@@ -1903,20 +1903,13 @@ C:0:0:0:0
Z:MAGIC MAP
N:511
-X:30:1
-T:39:0:255
-W:20:1:24
-C:0:0:0:0
-Z:DETECT CURSES
-
-N:512
X:25:1
T:39:0:255
W:20:1:17
C:0:0:0:0
Z:DAZZLE
-N:513
+N:512
X:40:1
T:39:0:255
W:20:1:50
diff --git a/lib/edit/s_orc.map b/lib/edit/s_orc.map
index 48913e02..54f1c89a 100644
--- a/lib/edit/s_orc.map
+++ b/lib/edit/s_orc.map
@@ -53,13 +53,8 @@ F:9:1:0:*75:*55
# Random monster (upto 3 levels ood)
F:-:1:0:*38
-# Random object (upto 7 levels ood)
-F:=:1:0:0:*42
-
-### Guaranteed Items
-
-# The stone of lore
-F:1:1:0:0:0:0:15
+# Random object (upto 25 levels ood)
+F:=:1:0:0:*60
### Level Design
D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
@@ -67,7 +62,7 @@ D:Xa.......................ccccccccc.......................aX
D:X.lllllllllllllllllllllllllllllllllllllllllllllllllllllll.X
D:X.l......................ccccccccc.....g.g..............l.X
D:X.l.XXXXXXXXXXXXXXXXXXXXXXXXX.XXXXXXXXXXDXXXXXXXXXXXXXX.l.X
-D:X.l.Xa.......efX1Xfe.......aX.X.aaa.D.gX.XacbdddccjjjaX.l.X
+D:X.l.Xa.......efX=Xfe.......aX.X.aaa.D.gX.XacbdddccjjjaX.l.X
D:X.l.D........efG.Gfe........D.D.bbb.XXXX.XcfbcbcbbjjeeX.l.X
D:X.l.X........efX.Xfe........X.X.bbb.D.gX.XfbbgdcbdbjjjX.l.X
D:X.l.XXXXXX...efG.Gfe...XXXXXX.X.bbb.XXXX.XebdcfbdccejjX.l.X
diff --git a/lib/edit/set_info.txt b/lib/edit/set_info.txt
index c803d79f..26d30d14 100644
--- a/lib/edit/set_info.txt
+++ b/lib/edit/set_info.txt
@@ -85,6 +85,5 @@ F:IM_FIRE
F:SH_ELEC
# The demonhorn of Gothmog
P:183:3:0
-F:AUTO_ID
F:ESP_EVIL
F:ESP_GOOD
diff --git a/lib/edit/st_info.txt b/lib/edit/st_info.txt
index b5ae29cf..e3a8dd23 100644
--- a/lib/edit/st_info.txt
+++ b/lib/edit/st_info.txt
@@ -101,10 +101,8 @@ G:3:w
W:24
N:3:Temple
-I:100:& Nunchaku~
I:100:& Quarterstaff~
I:100:& Mace~
-I:100:& Bo Staff~
I:100:& War Hammer~
I:100:& Lucerne Hammer~
I:100:& Morning Star~
@@ -153,10 +151,6 @@ N:4:Alchemy shop
I:100:Enchant Weapon To-Hit
I:100:Enchant Weapon To-Dam
I:100:Enchant Armour
-I:100:Identify
-I:100:Identify
-I:100:Identify
-I:100:Identify
I:100:Light
I:100:Phase Door
I:100:Phase Door
@@ -182,13 +176,6 @@ I:100:Restore Dexterity
#I:100:Restore Constitution
T:100:71:46
I:100:Restore Charisma
-I:100:Identify
-I:100:*Identify*
-I:100:*Identify*
-I:100:*Identify*
-I:100:*Identify*
-I:100:*Identify*
-I:100:*Identify*
I:100:Light
#I:100:Restore Strength
T:100:71:42
@@ -220,7 +207,6 @@ I:100:Slow Digestion
T:100:40:3
I:100:Acid Resistance
I:100:Lightning Resistance
-I:100:Searching
I:100:Cure Light Wounds
# Rods
I:25:& Wooden Rod~ of#
@@ -316,8 +302,7 @@ F:RANDOM
W:2
N:13:Library
-I:100:Identify
-A:0:0:14:15:16:2
+A:0:0:0:15:16:2
O:4:4:4:4
G:+:U
W:2
@@ -347,7 +332,7 @@ G:+:s
W:0
N:18:Tower of Magery
-A:0:0:26:27:0:0
+A:0:0:26:0:0:0
O:21:21:21:21
G:+:b
W:0
@@ -389,7 +374,7 @@ G:+:U
W:0
N:25:Wizards Spire
-A:60:0:26:27:0:0
+A:60:0:26:0:0:0
O:54:54:54:54
G:+:U
W:0
@@ -407,8 +392,7 @@ G:+:U
W:0
N:28:Library
-I:100:Identify
-A:0:0:14:15:16:2
+A:0:0:0:15:16:2
O:58:58:58:58
G:+:U
W:2
@@ -443,7 +427,7 @@ G:+:U
W:0
N:33:Star-Dome
-A:0:0:46:47:0:0
+A:0:0:0:47:0:0
O:63:63:63:63
G:+:U
W:0
@@ -573,7 +557,7 @@ T:100:122:256
T:100:123:256
T:100:124:256
T:100:125:256
-A:27:0:1:2:3:4
+A:0:0:1:2:3:4
O:8:9:10:11
G:9:y
F:DEPEND_LEVEL
@@ -598,7 +582,7 @@ T:100:122:256
T:100:123:256
T:100:124:256
T:100:125:256
-A:27:0:1:2:3:4
+A:0:0:1:2:3:4
O:8:9:10:11
G:9:v
F:DEEP_LEVEL
@@ -746,8 +730,7 @@ W:24
## Library quest in Minas Anor
N:60:Library
-I:100:Identify
-A:61:0:14:15:16:2
+A:61:0:0:15:16:2
O:4:4:4:4
G:+:U
W:2
diff --git a/lib/edit/t_bree.txt b/lib/edit/t_bree.txt
index 3d19b888..4d648ea6 100644
--- a/lib/edit/t_bree.txt
+++ b/lib/edit/t_bree.txt
@@ -117,12 +117,7 @@ D:# ^^^^^^^^^^^^^^ .
D:######################################################################################################################################################################################################
-############### Starting positions ###############
+############### Starting position ###############
-# Standard starting position for normal races
-?:[AND [EQU $LEAVING_QUEST 0] [NOT [EQU $RACE Vampire] ] ]
+?:[EQU $LEAVING_QUEST 0]
P:33:131
-
-# Standard starting position for vampires (at the dungeon entrance)
-?:[AND [EQU $LEAVING_QUEST 0] [EQU $RACE Vampire] ]
-P:31:150
diff --git a/lib/edit/t_d_bree.txt b/lib/edit/t_d_bree.txt
index 2112bc4e..b77fa37e 100644
--- a/lib/edit/t_d_bree.txt
+++ b/lib/edit/t_d_bree.txt
@@ -90,12 +90,7 @@ D:# ^^^^^^^^^^^^^^ ADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD .DDDD
D:######################################################################################################################################################################################################
-############### Starting positions ###############
+############### Starting position ###############
-# Standard starting position for normal races
-?:[AND [EQU $LEAVING_QUEST 0] [NOT [EQU $RACE Vampire] ] ]
+?:[EQU $LEAVING_QUEST 0]
P:33:131
-
-# Standard starting position for vampires (at the dungeon entrance)
-?:[AND [EQU $LEAVING_QUEST 0] [EQU $RACE Vampire] ]
-P:31:150
diff --git a/lib/file/book-10.txt b/lib/file/book-10.txt
deleted file mode 100644
index 51d43c60..00000000
--- a/lib/file/book-10.txt
+++ /dev/null
@@ -1,250 +0,0 @@
-The Large yellow snake is a common monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Cave spider is a common monster,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Wild cat is an uncommon monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-Smeagol is a unique monster,
-occurring at surface depths.
-He is laughably weak, not at all dangerous,
-and has no magical powers.
-
-The Green ooze is an uncommon monster,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Poltergeist is a common undead monster,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Metallic blue centipede is a common monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Giant white louse is a common monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Black naga is a common monster,
-occurring at surface depths.
-She is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Spotted mushroom patch is a common monster,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Silver jelly is an uncommon monster,
-occurring at surface depths.
-It is laughably weak, just a small bit dangerous,
-and has no magical powers.
-
-The Yellow jelly is a common monster,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Scruffy looking hobbit is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Giant white ant is a common monster,
-occurring at surface depths.
-It is laughably weak, not at all dangerous,
-and has no magical powers.
-
-The Yellow mold is a common monster,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Metallic red centipede is a common monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Yellow worm mass is an uncommon animal,
-occurring at surface depths.
-It is laughably weak, just a little bit dangerous,
-and has no magical powers.
-
-The Clear worm mass is an uncommon animal,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Radiation eye is a common monster,
-occurring at surface depths.
-It is laughably weak, not at all dangerous,
-and has no magical powers.
-
-The Cave lizard is a common animal,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Novice ranger is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has an inkling of magical powers.
-
-The Novice paladin is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has an inkling of magical powers.
-
-The Blue jelly is a common monster,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Creeping copper coins is an uncommon animal,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Giant white rat is a common monster,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Blue worm mass is a common animal,
-occurring at surface depths.
-It is laughably weak, just a little bit dangerous,
-and has no magical powers.
-
-The Large grey snake is a common monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-Bullroarer the Hobbit is a unique monster,
-occurring at surface depths.
-It is laughably weak, just a little bit dangerous,
-and has no magical powers.
-
-The Novice mage is an uncommon monster,
-occurring at surface depths.
-He is laughably weak, just a small bit dangerous,
-and has rudimentary magical powers.
-
-The Green naga is a common monster,
-occurring at surface depths.
-She is extremely weak, just a small bit dangerous,
-and has no magical powers.
-
-The Blue ooze is a common monster,
-occurring at surface depths.
-It is laughably weak, just a small bit dangerous,
-and has no magical powers.
-
-The Green glutton ghost is a common undead monster,
-occurring at surface depths.
-It is laughably weak, just a small bit dangerous,
-and has no magical powers.
-
-The Green jelly is a common monster,
-occurring at surface depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Large kobold is a common monster,
-occurring at surface depths.
-It is extremely weak, just a little bit dangerous,
-and has no magical powers.
-
-The Skeleton kobold is a common undead monster,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Grey icky thing is a common monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Disenchanter eye is an uncommon monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Red worm mass is a common animal,
-occurring at surface depths.
-It is laughably weak, just a little bit dangerous,
-and has no magical powers.
-
-The Copperhead snake is a common animal,
-occurring at surface depths.
-It is laughably weak, just a small bit dangerous,
-and has no magical powers.
-
-The Purple mushroom patch is an uncommon monster,
-occurring at surface depths.
-It is laughably weak, moderately dangerous,
-and has no magical powers.
-
-The Novice priest is an uncommon monster,
-occurring at surface depths.
-He is laughably weak, just a little bit dangerous,
-and has small magical powers.
-
-The Novice warrior is an uncommon monster,
-occurring at surface depths.
-He is laughably weak, just a small bit dangerous,
-and has no magical powers.
-
-The Novice rogue is an uncommon monster,
-occurring at surface depths.
-He is laughably weak, just a small bit dangerous,
-and has no magical powers.
-
-The Brown mold is a common monster,
-occurring at surface depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Giant brown bat is a common animal,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Novice archer is an uncommon monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has an inkling of magical powers.
-
-The Creeping silver coins is an uncommon animal,
-occurring at surface depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Snaga is a common orc,
-occurring at surface depths.
-He is laughably weak, just a little bit dangerous,
-and has no magical powers.
-
-The Rattlesnake is a common animal,
-occurring at surface depths.
-It is laughably weak, just a small bit dangerous,
-and has no magical powers.
-
-The Cave orc is a common orc,
-occurring at surface depths.
-He is extremely weak, just a little bit dangerous,
-and has no magical powers.
-
diff --git a/lib/file/book-11.txt b/lib/file/book-11.txt
deleted file mode 100644
index bd3c0593..00000000
--- a/lib/file/book-11.txt
+++ /dev/null
@@ -1,250 +0,0 @@
-The Wood spider is a somewhat rare animal,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Manes is an uncommon monster,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Bloodshot eye is a somewhat rare monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Pink naga is an uncommon monster,
-occurring at surface depths.
-She is extremely weak, just a little bit dangerous,
-and has no magical powers.
-
-The Pink jelly is a common monster,
-occurring at surface depths.
-It is very weak, somewhat dangerous,
-and has no magical powers.
-
-The Giant pink frog is a common animal,
-occurring at surface depths.
-It is laughably weak, not at all dangerous,
-and has no magical powers.
-
-The Green icky thing is an uncommon monster,
-occurring at surface depths.
-It is laughably weak, not at all dangerous,
-and has no magical powers.
-
-The Zombified kobold is a common undead monster,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Lost soul is an uncommon undead monster,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has rudimentary magical powers.
-
-The Dark elf is an uncommon monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has an inkling of magical powers.
-
-The Night lizard is an uncommon monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-Mughash the Kobold Lord is a unique monster,
-occurring at surface depths.
-He is extremely weak, moderately dangerous,
-and has no magical powers.
-
-Wormtongue, Agent of Saruman is a unique monster,
-occurring at surface depths.
-He is very weak, not at all dangerous,
-and has remarkable magical powers.
-
-Lagduf, the Snaga is a unique orc,
-occurring at surface depths.
-He is very weak, somewhat dangerous,
-and has no magical powers.
-
-The Brown yeek is a common animal,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Novice ranger is a common monster,
-occurring at surface depths.
-He is laughably weak, just a little bit dangerous,
-and has an inkling of magical powers.
-
-The Giant salamander is a common animal,
-occurring at surface depths.
-It is laughably weak, not at all dangerous,
-and has no magical powers.
-
-The Green mold is an uncommon monster,
-occurring at surface depths.
-It is extremely weak, moderately dangerous,
-and has no magical powers.
-
-The Skeleton orc is a common undead monster,
-occurring at surface depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Novice paladin is an uncommon monster,
-occurring at surface depths.
-He is laughably weak, just a little bit dangerous,
-and has an inkling of magical powers.
-
-The Lemure is a somewhat rare monster,
-occurring at surface depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Hill orc is a common monster,
-occurring at surface depths.
-He is extremely weak, just a small bit dangerous,
-and has no magical powers.
-
-The Bandit is an uncommon monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Yeti is a somewhat rare animal,
-occurring at surface depths.
-It is extremely weak, not one little bit dangerous,
-and has no magical powers.
-
-The Bloodshot icky thing is a somewhat rare monster,
-occurring at surface depths.
-It is laughably weak, not at all dangerous,
-and has no magical powers.
-
-The Giant grey rat is a common animal,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Black harpy is a common animal,
-occurring at surface depths.
-She is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Orc shaman is a common orc,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has rudimentary magical powers.
-
-The Baby blue dragon is an uncommon dragon,
-occurring at surface depths.
-It is extremely weak, not at all dangerous,
-and has no magical powers.
-
-The Baby white dragon is an uncommon dragon,
-occurring at surface depths.
-It is extremely weak, not at all dangerous,
-and has no magical powers.
-
-The Baby green dragon is an uncommon dragon,
-occurring at surface depths.
-It is extremely weak, not at all dangerous,
-and has no magical powers.
-
-The Baby black dragon is an uncommon dragon,
-occurring at surface depths.
-It is extremely weak, not at all dangerous,
-and has no magical powers.
-
-The Baby red dragon is an uncommon dragon,
-occurring at surface depths.
-It is extremely weak, not at all dangerous,
-and has no magical powers.
-
-The Giant pink ant is an uncommon monster,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-Brodda, the Easterling is a unique monster,
-occurring at surface depths.
-It is very weak, just a little bit dangerous,
-and has no magical powers.
-
-The King cobra is an uncommon animal,
-occurring at surface depths.
-It is extremely weak, just a little bit dangerous,
-and has no magical powers.
-
-The Giant spider is an uncommon animal,
-occurring at very shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Dark elven mage is a common monster,
-occurring at very shallow depths.
-He is laughably weak, not at all dangerous,
-and has simple magical powers.
-
-Orfax, Son of Boldor is a unique animal,
-occurring at very shallow depths.
-He is extremely weak, somewhat dangerous,
-and has remarkable magical powers.
-
-The Dark elven warrior is a common monster,
-occurring at very shallow depths.
-He is extremely weak, not one little bit dangerous,
-and has no magical powers.
-
-The Clear mushroom patch is an uncommon monster,
-occurring at very shallow depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-Grishnakh, the Hill Orc is a unique orc,
-occurring at very shallow depths.
-He is very weak, somewhat dangerous,
-and has no magical powers.
-
-The Giant white tick is an uncommon animal,
-occurring at very shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Hairy mold is an uncommon monster,
-occurring at very shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Disenchanter mold is an uncommon monster,
-occurring at very shallow depths.
-It is extremely weak, moderately dangerous,
-and has no magical powers.
-
-The Pseudo dragon is an uncommon monster,
-occurring at very shallow depths.
-It is very weak, not at all dangerous,
-and has simple magical powers.
-
-The Tengu is a common monster,
-occurring at very shallow depths.
-It is extremely weak, just a small bit dangerous,
-and has rudimentary magical powers.
-
-The Creeping gold coins is a somewhat rare animal,
-occurring at very shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Wolf is a common animal,
-occurring at very shallow depths.
-It is laughably weak, just a little bit dangerous,
-and has no magical powers.
-
-The Giant fruit fly is a legendary animal,
-occurring at very shallow depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
diff --git a/lib/file/book-12.txt b/lib/file/book-12.txt
deleted file mode 100644
index d111d15d..00000000
--- a/lib/file/book-12.txt
+++ /dev/null
@@ -1,250 +0,0 @@
-The Panther is an uncommon monster,
-occurring at very shallow depths.
-It is extremely weak, not one little bit dangerous,
-and has no magical powers.
-
-The Brigand is an uncommon monster,
-occurring at very shallow depths.
-He is extremely weak, not one little bit dangerous,
-and has no magical powers.
-
-The Baby multi-hued dragon is an uncommon dragon,
-occurring at very shallow depths.
-It is extremely weak, moderately dangerous,
-and has arcane magical powers.
-
-The Hippogryph is a common monster,
-occurring at very shallow depths.
-It is extremely weak, not one little bit dangerous,
-and has no magical powers.
-
-The Zombified orc is a common undead monster,
-occurring at very shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Gnome mage is an uncommon monster,
-occurring at very shallow depths.
-He is laughably weak, not one little bit dangerous,
-and has unremarkable magical powers.
-
-The Black mamba is a somewhat rare animal,
-occurring at very shallow depths.
-It is extremely weak, just a small bit dangerous,
-and has no magical powers.
-
-The White wolf is a common animal,
-occurring at very shallow depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Grape jelly is a somewhat rare monster,
-occurring at very shallow depths.
-It is moderately strong, just a small bit dangerous,
-and has no magical powers.
-
-The Nether worm mass is a somewhat rare animal,
-occurring at very shallow depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-Golfimbul, the Hill Orc Chief is a unique orc,
-occurring at very shallow depths.
-He is somewhat weak, moderately dangerous,
-and has no magical powers.
-
-The Master yeek is an uncommon animal,
-occurring at very shallow depths.
-It is extremely weak, not one little bit dangerous,
-and has arcane magical powers.
-
-The Priest is a common monster,
-occurring at very shallow depths.
-He is extremely weak, not one little bit dangerous,
-and has unremarkable magical powers.
-
-The Dark elven priest is a common monster,
-occurring at very shallow depths.
-He is extremely weak, not one little bit dangerous,
-and has unremarkable magical powers.
-
-The Air spirit is an uncommon monster,
-occurring at very shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Skeleton human is a common undead monster,
-occurring at very shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Zombified human is a common undead monster,
-occurring at very shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Tiger is an uncommon monster,
-occurring at very shallow depths.
-It is extremely weak, not one little bit dangerous,
-and has no magical powers.
-
-The Moaning spirit is an uncommon undead monster,
-occurring at very shallow depths.
-It is laughably weak, moderately dangerous,
-and has rudimentary magical powers.
-
-The Swordsman is a common monster,
-occurring at very shallow depths.
-He is extremely weak, not one little bit dangerous,
-and has no magical powers.
-
-The Stegocentipede is an uncommon monster,
-occurring at very shallow depths.
-It is extremely weak, not at all dangerous,
-and has no magical powers.
-
-The Spotted jelly is a somewhat rare monster,
-occurring at very shallow depths.
-It is extremely weak, moderately dangerous,
-and has no magical powers.
-
-The Drider is an uncommon monster,
-occurring at very shallow depths.
-It is extremely weak, just a little bit dangerous,
-and has rudimentary magical powers.
-
-The Killer brown beetle is an uncommon monster,
-occurring at very shallow depths.
-It is extremely weak, not at all dangerous,
-and has no magical powers.
-
-Boldor, King of the Yeeks is a unique animal,
-occurring at very shallow depths.
-He is very weak, somewhat dangerous,
-and has remarkable magical powers.
-
-The Ogre is an uncommon monster,
-occurring at very shallow depths.
-It is extremely weak, just a small bit dangerous,
-and has no magical powers.
-
-The Creeping mithril coins is a rare animal,
-occurring at very shallow depths.
-It is very weak, somewhat dangerous,
-and has no magical powers.
-
-The Illusionist is an uncommon monster,
-occurring at very shallow depths.
-He is extremely weak, not one little bit dangerous,
-and has arcane magical powers.
-
-The Druid is an uncommon monster,
-occurring at very shallow depths.
-He is extremely weak, not one little bit dangerous,
-and has remarkable magical powers.
-
-The Black orc is an uncommon orc,
-occurring at very shallow depths.
-He is extremely weak, just a little bit dangerous,
-and has no magical powers.
-
-The Ochre jelly is a somewhat rare monster,
-occurring at very shallow depths.
-It is extremely weak, very dangerous,
-and has no magical powers.
-
-The Giant flea is a common monster,
-occurring at very shallow depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-Ufthak of Cirith Ungol is a unique orc,
-occurring at very shallow depths.
-He is somewhat weak, moderately dangerous,
-and has no magical powers.
-
-The Giant white dragon fly is a somewhat rare animal,
-occurring at very shallow depths.
-It is laughably weak, not at all dangerous,
-and has no magical powers.
-
-The Blue icky thing is a rare monster,
-occurring at very shallow depths.
-It is laughably weak, just a small bit dangerous,
-and has an inkling of magical powers.
-
-The Hill giant is a common monster,
-occurring at very shallow depths.
-It is very weak, not one little bit dangerous,
-and has no magical powers.
-
-The Flesh golem is a common monster,
-occurring at very shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Warg is an uncommon animal,
-occurring at very shallow depths.
-It is laughably weak, just a little bit dangerous,
-and has no magical powers.
-
-The Giant black louse is a common monster,
-occurring at very shallow depths.
-It is laughably weak, not at all dangerous,
-and has no magical powers.
-
-The Lurker is a somewhat rare monster,
-occurring at very shallow depths.
-It is very weak, somewhat dangerous,
-and has no magical powers.
-
-The Wererat is an uncommon animal,
-occurring at very shallow depths.
-It is extremely weak, not one little bit dangerous,
-and has simple magical powers.
-
-The Black ogre is an uncommon giant,
-occurring at very shallow depths.
-It is very weak, just a little bit dangerous,
-and has no magical powers.
-
-The Magic mushroom patch is an uncommon monster,
-occurring at very shallow depths.
-It is laughably weak, not at all dangerous,
-and has arcane magical powers.
-
-The Guardian naga is an uncommon monster,
-occurring at very shallow depths.
-She is somewhat weak, not one little bit dangerous,
-and has no magical powers.
-
-The Light hound is a common monster,
-occurring at very shallow depths.
-It is laughably weak, just a little bit dangerous,
-and has an inkling of magical powers.
-
-The Dark hound is a common monster,
-occurring at very shallow depths.
-It is laughably weak, just a little bit dangerous,
-and has an inkling of magical powers.
-
-The Half-orc is a somewhat rare orc,
-occurring at very shallow depths.
-He is very weak, just a small bit dangerous,
-and has no magical powers.
-
-The Giant tarantula is a somewhat rare animal,
-occurring at very shallow depths.
-It is extremely weak, moderately dangerous,
-and has no magical powers.
-
-The Giant clear centipede is an uncommon monster,
-occurring at very shallow depths.
-It is laughably weak, just a small bit dangerous,
-and has no magical powers.
-
-The Mirkwood spider is an uncommon animal,
-occurring at very shallow depths.
-It is laughably weak, moderately dangerous,
-and has no magical powers.
-
diff --git a/lib/file/book-13.txt b/lib/file/book-13.txt
deleted file mode 100644
index b8a15e3f..00000000
--- a/lib/file/book-13.txt
+++ /dev/null
@@ -1,250 +0,0 @@
-The Frost giant is a common giant,
-occurring at very shallow depths.
-It is very weak, not at all dangerous,
-and has no magical powers.
-
-The Griffon is a common animal,
-occurring at very shallow depths.
-It is very weak, not one little bit dangerous,
-and has no magical powers.
-
-The Homonculous is a somewhat rare monster,
-occurring at very shallow depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Gnome mage is an uncommon monster,
-occurring at very shallow depths.
-He is laughably weak, just a little bit dangerous,
-and has unremarkable magical powers.
-
-The Clear hound is an uncommon monster,
-occurring at very shallow depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Clay golem is an uncommon monster,
-occurring at very shallow depths.
-It is extremely weak, moderately dangerous,
-and has no magical powers.
-
-The Umber hulk is a common animal,
-occurring at very shallow depths.
-It is very weak, somewhat dangerous,
-and has no magical powers.
-
-The Orc captain is a somewhat rare orc,
-occurring at very shallow depths.
-He is very weak, not one little bit dangerous,
-and has no magical powers.
-
-The Gelatinous cube is a rare monster,
-occurring at very shallow depths.
-It is somewhat weak, hellishly dangerous,
-and has no magical powers.
-
-The Giant green dragon fly is an uncommon animal,
-occurring at very shallow depths.
-It is laughably weak, just a little bit dangerous,
-and has no magical powers.
-
-The Fire giant is an uncommon giant,
-occurring at very shallow depths.
-It is very weak, somewhat dangerous,
-and has no magical powers.
-
-The Hummerhorn is an extremely rare animal,
-occurring at very shallow depths.
-It is laughably weak, just a little bit dangerous,
-and has no magical powers.
-
-Ulfast, Son of Ulfang is a unique monster,
-occurring at very shallow depths.
-He is somewhat weak, just a little bit dangerous,
-and has no magical powers.
-
-The Quasit is an uncommon monster,
-occurring at very shallow depths.
-It is laughably weak, somewhat dangerous,
-and has average magical powers.
-
-The Imp is an uncommon monster,
-occurring at very shallow depths.
-It is laughably weak, moderately dangerous,
-and has average magical powers.
-
-The Forest troll is a common troll,
-occurring at very shallow depths.
-He is very weak, just a little bit dangerous,
-and has no magical powers.
-
-Nar, the Dwarf is a unique monster,
-occurring at very shallow depths.
-He is somewhat strong, moderately dangerous,
-and has simple magical powers.
-
-The 2-headed hydra is an uncommon monster,
-occurring at very shallow depths.
-It is somewhat weak, not one little bit dangerous,
-and has no magical powers.
-
-The Water spirit is a common monster,
-occurring at very shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Giant pink scorpion is a common monster,
-occurring at very shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Earth spirit is an uncommon monster,
-occurring at very shallow depths.
-It is extremely weak, moderately dangerous,
-and has no magical powers.
-
-The Fire spirit is an uncommon monster,
-occurring at very shallow depths.
-It is extremely weak, moderately dangerous,
-and has no magical powers.
-
-The Fire hound is a common animal,
-occurring at very shallow depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Cold hound is a common animal,
-occurring at very shallow depths.
-It is laughably weak, just a small bit dangerous,
-and has no magical powers.
-
-The Energy hound is a common animal,
-occurring at very shallow depths.
-It is laughably weak, moderately dangerous,
-and has no magical powers.
-
-The Mimic (potion) is a somewhat rare monster,
-occurring at very shallow depths.
-It is extremely weak, somewhat dangerous,
-and has small magical powers.
-
-The Blink dog is an uncommon monster,
-occurring at very shallow depths.
-It is laughably weak, just a little bit dangerous,
-and has rudimentary magical powers.
-
-The Uruk is a common orc,
-occurring at very shallow depths.
-He is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-Shagrat, the Orc Captain is a unique orc,
-occurring at very shallow depths.
-He is moderately strong, somewhat dangerous,
-and has no magical powers.
-
-Gorbag, the Orc Captain is a unique orc,
-occurring at very shallow depths.
-He is moderately strong, somewhat dangerous,
-and has no magical powers.
-
-The Shambling mound is an uncommon monster,
-occurring at very shallow depths.
-It is extremely weak, just a small bit dangerous,
-and has an inkling of magical powers.
-
-The Stone giant is a common monster,
-occurring at very shallow depths.
-It is very weak, not one little bit dangerous,
-and has no magical powers.
-
-The Giant black dragon fly is an uncommon animal,
-occurring at very shallow depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Stone golem is an uncommon monster,
-occurring at very shallow depths.
-It is very weak, moderately dangerous,
-and has no magical powers.
-
-The Red mold is a common monster,
-occurring at very shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Giant gold dragon fly is an uncommon animal,
-occurring at very shallow depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-Bolg, Son of Azog is a unique orc,
-occurring at somewhat shallow depths.
-He is somewhat strong, somewhat dangerous,
-and has no magical powers.
-
-The Phase spider is an uncommon animal,
-occurring at somewhat shallow depths.
-It is laughably weak, moderately dangerous,
-and has rudimentary magical powers.
-
-The 3-headed hydra is an uncommon monster,
-occurring at somewhat shallow depths.
-It is somewhat strong, not one little bit dangerous,
-and has no magical powers.
-
-The Earth hound is a common monster,
-occurring at somewhat shallow depths.
-It is extremely weak, just a little bit dangerous,
-and has no magical powers.
-
-The Air hound is a common animal,
-occurring at somewhat shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Sabre-tooth tiger is an uncommon monster,
-occurring at somewhat shallow depths.
-It is somewhat weak, not one little bit dangerous,
-and has no magical powers.
-
-The Water hound is an uncommon animal,
-occurring at somewhat shallow depths.
-It is extremely weak, moderately dangerous,
-and has no magical powers.
-
-The Chimera is a common monster,
-occurring at somewhat shallow depths.
-It is extremely weak, not at all dangerous,
-and has no magical powers.
-
-The Quylthulg is a common monster,
-occurring at somewhat shallow depths.
-It is laughably weak, just a small bit dangerous,
-and has rudimentary magical powers.
-
-The Sasquatch is a somewhat rare animal,
-occurring at somewhat shallow depths.
-It is moderately strong, not one little bit dangerous,
-and has no magical powers.
-
-The Werewolf is a common animal,
-occurring at somewhat shallow depths.
-It is moderately strong, not one little bit dangerous,
-and has no magical powers.
-
-The Dark elven lord is an uncommon monster,
-occurring at somewhat shallow depths.
-He is somewhat weak, not one little bit dangerous,
-and has average magical powers.
-
-The Cloud giant is a common giant,
-occurring at somewhat shallow depths.
-It is somewhat weak, somewhat dangerous,
-and has no magical powers.
-
-Ugluk, the Uruk is a unique orc,
-occurring at somewhat shallow depths.
-He is very strong, somewhat dangerous,
-and has no magical powers.
-
diff --git a/lib/file/book-14.txt b/lib/file/book-14.txt
deleted file mode 100644
index b987ea99..00000000
--- a/lib/file/book-14.txt
+++ /dev/null
@@ -1,250 +0,0 @@
-Lugdush, the Uruk is a unique orc,
-occurring at somewhat shallow depths.
-He is extremely strong, moderately dangerous,
-and has no magical powers.
-
-The Blue dragon bat is a common animal,
-occurring at somewhat shallow depths.
-It is laughably weak, not at all dangerous,
-and has an inkling of magical powers.
-
-The Mimic (scroll) is a somewhat rare monster,
-occurring at somewhat shallow depths.
-It is extremely weak, moderately dangerous,
-and has average magical powers.
-
-The Fire vortex is a common monster,
-occurring at somewhat shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Water vortex is a common monster,
-occurring at somewhat shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Cold vortex is a common monster,
-occurring at somewhat shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Energy vortex is a common monster,
-occurring at somewhat shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Mummified orc is a common undead monster,
-occurring at somewhat shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Killer stag beetle is a common monster,
-occurring at somewhat shallow depths.
-It is very weak, not one little bit dangerous,
-and has no magical powers.
-
-The Iron golem is an uncommon monster,
-occurring at somewhat shallow depths.
-It is unimaginably strong, moderately dangerous,
-and has no magical powers.
-
-The Giant yellow scorpion is a common monster,
-occurring at somewhat shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Black ooze is a common monster,
-occurring at somewhat shallow depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Hardened warrior is a common monster,
-occurring at somewhat shallow depths.
-He is very weak, not one little bit dangerous,
-and has no magical powers.
-
-Azog, King of the Uruk-Hai is a unique orc,
-occurring at somewhat shallow depths.
-He is alarmingly strong, moderately dangerous,
-and has no magical powers.
-
-The Master rogue is an uncommon monster,
-occurring at somewhat shallow depths.
-He is extremely weak, not one little bit dangerous,
-and has no magical powers.
-
-The Red dragon bat is a common animal,
-occurring at somewhat shallow depths.
-It is laughably weak, not one little bit dangerous,
-and has an inkling of magical powers.
-
-The Killer white beetle is a common monster,
-occurring at somewhat shallow depths.
-It is very weak, not one little bit dangerous,
-and has no magical powers.
-
-The Giant bronze dragon fly is a common animal,
-occurring at very shallow depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Forest wight is a common undead monster,
-occurring at somewhat shallow depths.
-It is extremely weak, just a little bit dangerous,
-and has an inkling of magical powers.
-
-Ibun, Son of Mim is a unique monster,
-occurring at somewhat shallow depths.
-He is alarmingly strong, somewhat dangerous,
-and has small magical powers.
-
-Khim, Son of Mim is a unique monster,
-occurring at somewhat shallow depths.
-He is alarmingly strong, somewhat dangerous,
-and has small magical powers.
-
-The 4-headed hydra is an uncommon monster,
-occurring at somewhat shallow depths.
-It is strong, not one little bit dangerous,
-and has no magical powers.
-
-The Mummified human is a common undead monster,
-occurring at somewhat shallow depths.
-It is extremely weak, somewhat dangerous,
-and has no magical powers.
-
-The Vampire bat is an uncommon undead monster,
-occurring at somewhat shallow depths.
-It is extremely weak, moderately dangerous,
-and has no magical powers.
-
-Sangahyando of Umbar is a unique monster,
-occurring at somewhat shallow depths.
-He is extremely strong, somewhat dangerous,
-and has rudimentary magical powers.
-
-Angamaite of Umbar is a unique monster,
-occurring at somewhat shallow depths.
-He is extremely strong, somewhat dangerous,
-and has rudimentary magical powers.
-
-The Banshee is an uncommon undead monster,
-occurring at somewhat shallow depths.
-She is laughably weak, somewhat dangerous,
-and has rudimentary magical powers.
-
-The Pukelman is a somewhat rare monster,
-occurring at somewhat shallow depths.
-It is unimaginably strong, moderately dangerous,
-and has small magical powers.
-
-The Dark elven druid is a somewhat rare monster,
-occurring at somewhat shallow depths.
-He is moderately strong, just a little bit dangerous,
-and has unremarkable magical powers.
-
-The Stone troll is a common troll,
-occurring at somewhat shallow depths.
-He is very weak, just a little bit dangerous,
-and has no magical powers.
-
-The Troll priest is a common troll,
-occurring at somewhat shallow depths.
-He is somewhat weak, just a little bit dangerous,
-and has unremarkable magical powers.
-
-The Wereworm is a somewhat rare animal,
-occurring at somewhat shallow depths.
-It is hellishly strong, somewhat dangerous,
-and has no magical powers.
-
-The Carrion crawler is an uncommon animal,
-occurring at somewhat shallow depths.
-It is very weak, somewhat dangerous,
-and has no magical powers.
-
-The Killer pink beetle is an uncommon monster,
-occurring at somewhat shallow depths.
-It is very weak, just a small bit dangerous,
-and has no magical powers.
-
-The Giant grey ant is a common monster,
-occurring at somewhat shallow depths.
-It is extremely weak, not one little bit dangerous,
-and has no magical powers.
-
-Ulwarth, Son of Ulfang is a unique monster,
-occurring at somewhat shallow depths.
-He is extremely strong, just a little bit dangerous,
-and has no magical powers.
-
-The Displacer beast is an uncommon monster,
-occurring at somewhat shallow depths.
-It is somewhat weak, just a little bit dangerous,
-and has no magical powers.
-
-The Giant red tick is a common animal,
-occurring at somewhat shallow depths.
-It is extremely weak, just a small bit dangerous,
-and has no magical powers.
-
-The Cave ogre is a common monster,
-occurring at somewhat shallow depths.
-It is somewhat weak, just a small bit dangerous,
-and has no magical powers.
-
-The White wraith is a common undead monster,
-occurring at somewhat shallow depths.
-It is extremely weak, somewhat dangerous,
-and has rudimentary magical powers.
-
-The Monadic Deva is a legendary monster,
-occurring at somewhat shallow depths.
-It is somewhat weak, moderately dangerous,
-and has small magical powers.
-
-Mim, Betrayer of Turin is a unique monster,
-occurring at somewhat shallow depths.
-He is hellishly strong, moderately dangerous,
-and has unremarkable magical powers.
-
-The Killer red beetle is a common animal,
-occurring at somewhat shallow depths.
-It is extremely weak, just a little bit dangerous,
-and has no magical powers.
-
-The Creeping adamantite coins is a rare animal,
-occurring at somewhat shallow depths.
-It is somewhat strong, moderately dangerous,
-and has no magical powers.
-
-The Algroth is a common monster,
-occurring at somewhat shallow depths.
-It is somewhat weak, moderately dangerous,
-and has no magical powers.
-
-The Vibration hound is a somewhat rare animal,
-occurring at somewhat shallow depths.
-It is very weak, just a small bit dangerous,
-and has an inkling of magical powers.
-
-The Nexus hound is a somewhat rare animal,
-occurring at somewhat shallow depths.
-It is very weak, just a small bit dangerous,
-and has an inkling of magical powers.
-
-The Ogre mage is an uncommon giant,
-occurring at somewhat shallow depths.
-It is moderately strong, not one little bit dangerous,
-and has arcane magical powers.
-
-Lokkak, the Ogre Chieftain is a unique giant,
-occurring at somewhat shallow depths.
-He is hellishly strong, somewhat dangerous,
-and has no magical powers.
-
-The Vampire is a common undead monster,
-occurring at somewhat shallow depths.
-It is somewhat weak, moderately dangerous,
-and has arcane magical powers.
-
diff --git a/lib/file/book-15.txt b/lib/file/book-15.txt
deleted file mode 100644
index 5f33444b..00000000
--- a/lib/file/book-15.txt
+++ /dev/null
@@ -1,250 +0,0 @@
-The Gorgimera is an uncommon monster,
-occurring at somewhat shallow depths.
-It is somewhat strong, just a small bit dangerous,
-and has no magical powers.
-
-The Colbran is an uncommon monster,
-occurring at somewhat shallow depths.
-It is unimaginably strong, moderately dangerous,
-and has an inkling of magical powers.
-
-The Spirit naga is an uncommon monster,
-occurring at somewhat shallow depths.
-She is somewhat strong, somewhat dangerous,
-and has unremarkable magical powers.
-
-The 5-headed hydra is an uncommon animal,
-occurring at somewhat shallow depths.
-It is extremely strong, moderately dangerous,
-and has rudimentary magical powers.
-
-The Black knight is a common monster,
-occurring at somewhat shallow depths.
-He is somewhat weak, not one little bit dangerous,
-and has rudimentary magical powers.
-
-Uldor the Accursed is a unique monster,
-occurring at somewhat shallow depths.
-He is unimaginably strong, just a little bit dangerous,
-and has no magical powers.
-
-The Mage is a common monster,
-occurring at somewhat shallow depths.
-He is extremely weak, not one little bit dangerous,
-and has unimaginably powerful magical powers.
-
-The Mind flayer is a common monster,
-occurring at somewhat shallow depths.
-It is very weak, moderately dangerous,
-and has remarkable magical powers.
-
-Draebor, the Imp is a unique monster,
-occurring at somewhat shallow depths.
-It is somewhat strong, very dangerous,
-and has arcane magical powers.
-
-The Basilisk is a somewhat rare animal,
-occurring at somewhat shallow depths.
-It is strong, not at all dangerous,
-and has no magical powers.
-
-The Ice troll is a common troll,
-occurring at somewhat shallow depths.
-He is very weak, somewhat dangerous,
-and has no magical powers.
-
-The Giant purple worm is a somewhat rare animal,
-occurring at somewhat shallow depths.
-It is somewhat strong, somewhat dangerous,
-and has no magical powers.
-
-The Movanic Deva is a legendary monster,
-occurring at somewhat shallow depths.
-It is moderately strong, moderately dangerous,
-and has unremarkable magical powers.
-
-The Catoblepas is an uncommon animal,
-occurring at somewhat shallow depths.
-It is somewhat weak, just a small bit dangerous,
-and has no magical powers.
-
-The Mimic (ring) is a somewhat rare monster,
-occurring at somewhat shallow depths.
-It is moderately strong, extremely dangerous,
-and has hellishly powerful magical powers.
-
-The Young blue dragon is a common dragon,
-occurring at somewhat shallow depths.
-It is somewhat weak, just a small bit dangerous,
-and has an inkling of magical powers.
-
-The Young white dragon is a common dragon,
-occurring at somewhat shallow depths.
-It is somewhat weak, just a small bit dangerous,
-and has an inkling of magical powers.
-
-The Young green dragon is a common dragon,
-occurring at somewhat shallow depths.
-It is somewhat weak, just a small bit dangerous,
-and has an inkling of magical powers.
-
-The Young bronze dragon is a somewhat rare dragon,
-occurring at somewhat shallow depths.
-It is somewhat weak, just a small bit dangerous,
-and has an inkling of magical powers.
-
-The Mithril golem is a rare monster,
-occurring at shallow depths.
-It is hellishly strong, moderately dangerous,
-and has no magical powers.
-
-The Shadow drake is an uncommon dragon,
-occurring at shallow depths.
-It is very weak, just a small bit dangerous,
-and has simple magical powers.
-
-The Skeleton troll is a common undead monster,
-occurring at shallow depths.
-It is very weak, somewhat dangerous,
-and has no magical powers.
-
-The Manticore is an uncommon monster,
-occurring at shallow depths.
-It is very weak, not at all dangerous,
-and has an inkling of magical powers.
-
-The Giant blue ant is an uncommon animal,
-occurring at shallow depths.
-It is extremely weak, just a little bit dangerous,
-and has no magical powers.
-
-The Giant army ant is a somewhat rare monster,
-occurring at shallow depths.
-It is extremely weak, just a small bit dangerous,
-and has no magical powers.
-
-The Grave wight is a common undead monster,
-occurring at shallow depths.
-It is extremely weak, just a little bit dangerous,
-and has rudimentary magical powers.
-
-The Killer slicer beetle is an uncommon monster,
-occurring at shallow depths.
-It is very weak, not at all dangerous,
-and has no magical powers.
-
-The Ghost is a common undead monster,
-occurring at shallow depths.
-It is extremely weak, alarmingly dangerous,
-and has an inkling of magical powers.
-
-The Death watch beetle is a somewhat rare monster,
-occurring at shallow depths.
-It is somewhat weak, just a small bit dangerous,
-and has no magical powers.
-
-The Ogre shaman is an uncommon giant,
-occurring at shallow depths.
-It is extremely weak, not one little bit dangerous,
-and has advanced magical powers.
-
-The Nexus quylthulg is a common monster,
-occurring at shallow depths.
-It is extremely weak, not at all dangerous,
-and has average magical powers.
-
-Shelob, Spider of Darkness is a unique animal,
-occurring at shallow depths.
-She is hellishly strong, unimaginably dangerous,
-and has very powerful magical powers.
-
-The Ninja is an uncommon monster,
-occurring at shallow depths.
-He is very weak, moderately dangerous,
-and has no magical powers.
-
-The Memory moss is a somewhat rare monster,
-occurring at shallow depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Storm giant is a common giant,
-occurring at shallow depths.
-It is moderately strong, moderately dangerous,
-and has average magical powers.
-
-The Cave troll is a common troll,
-occurring at shallow depths.
-He is somewhat weak, somewhat dangerous,
-and has no magical powers.
-
-The Half-troll is an uncommon troll,
-occurring at shallow depths.
-He is moderately strong, somewhat dangerous,
-and has no magical powers.
-
-The Mystic is a somewhat rare monster,
-occurring at shallow depths.
-He is moderately strong, moderately dangerous,
-and has rudimentary magical powers.
-
-The Barrow wight is a somewhat rare undead monster,
-occurring at shallow depths.
-It is extremely weak, somewhat dangerous,
-and has small magical powers.
-
-The Giant skeleton troll is a common undead monster,
-occurring at shallow depths.
-It is somewhat strong, moderately dangerous,
-and has no magical powers.
-
-The Chaos drake is a somewhat rare dragon,
-occurring at shallow depths.
-It is strong, somewhat dangerous,
-and has remarkable magical powers.
-
-The Law drake is a somewhat rare dragon,
-occurring at shallow depths.
-It is strong, somewhat dangerous,
-and has average magical powers.
-
-The Balance drake is a somewhat rare dragon,
-occurring at shallow depths.
-It is very strong, somewhat dangerous,
-and has hellishly powerful magical powers.
-
-The Ethereal drake is a somewhat rare dragon,
-occurring at shallow depths.
-It is somewhat strong, somewhat dangerous,
-and has unremarkable magical powers.
-
-Bert the Stone Troll is a unique troll,
-occurring at shallow depths.
-He is hellishly strong, somewhat dangerous,
-and has no magical powers.
-
-Bill the Stone Troll is a unique troll,
-occurring at shallow depths.
-He is hellishly strong, somewhat dangerous,
-and has no magical powers.
-
-Tom the Stone Troll is a unique troll,
-occurring at shallow depths.
-He is hellishly strong, somewhat dangerous,
-and has no magical powers.
-
-The Shade is a somewhat rare undead monster,
-occurring at shallow depths.
-It is somewhat weak, moderately dangerous,
-and has small magical powers.
-
-The Spectre is a somewhat rare undead monster,
-occurring at shallow depths.
-It is somewhat weak, moderately dangerous,
-and has small magical powers.
-
-The Water troll is a common troll,
-occurring at shallow depths.
-He is moderately strong, moderately dangerous,
-and has no magical powers.
-
diff --git a/lib/file/book-16.txt b/lib/file/book-16.txt
deleted file mode 100644
index d2b36408..00000000
--- a/lib/file/book-16.txt
+++ /dev/null
@@ -1,250 +0,0 @@
-The Fire elemental is an uncommon monster,
-occurring at shallow depths.
-It is very weak, moderately dangerous,
-and has no magical powers.
-
-The Astral Deva is a legendary monster,
-occurring at shallow depths.
-It is somewhat strong, alarmingly dangerous,
-and has advanced magical powers.
-
-The Water elemental is an uncommon monster,
-occurring at shallow depths.
-It is very weak, somewhat dangerous,
-and has no magical powers.
-
-The Invisible stalker is a somewhat rare monster,
-occurring at shallow depths.
-It is very weak, moderately dangerous,
-and has no magical powers.
-
-The Carrion crawler is an uncommon animal,
-occurring at shallow depths.
-It is very weak, somewhat dangerous,
-and has no magical powers.
-
-The Master thief is an uncommon monster,
-occurring at shallow depths.
-He is very weak, not at all dangerous,
-and has no magical powers.
-
-Ulfang the Black is a unique monster,
-occurring at shallow depths.
-He is unimaginably strong, just a little bit dangerous,
-and has no magical powers.
-
-The Lich is a somewhat rare undead monster,
-occurring at shallow depths.
-It is somewhat weak, very dangerous,
-and has very powerful magical powers.
-
-The Master vampire is a somewhat rare undead monster,
-occurring at shallow depths.
-It is moderately strong, moderately dangerous,
-and has very powerful magical powers.
-
-The Giant grey scorpion is a rare monster,
-occurring at shallow depths.
-It is moderately strong, somewhat dangerous,
-and has no magical powers.
-
-The Earth elemental is an uncommon monster,
-occurring at shallow depths.
-It is somewhat weak, very dangerous,
-and has no magical powers.
-
-The Air elemental is an uncommon monster,
-occurring at shallow depths.
-It is very weak, alarmingly dangerous,
-and has no magical powers.
-
-The Hell hound is a somewhat rare animal,
-occurring at shallow depths.
-It is moderately strong, just a small bit dangerous,
-and has an inkling of magical powers.
-
-The Eog golem is a rare monster,
-occurring at shallow depths.
-It is hellishly strong, moderately dangerous,
-and has no magical powers.
-
-The Olog is a common troll,
-occurring at shallow depths.
-It is moderately strong, somewhat dangerous,
-and has no magical powers.
-
-The Dagashi is a rare monster,
-occurring at shallow depths.
-He is somewhat weak, extremely dangerous,
-and has no magical powers.
-
-The Gravity hound is an uncommon animal,
-occurring at shallow depths.
-It is somewhat weak, somewhat dangerous,
-and has an inkling of magical powers.
-
-The Acidic cytoplasm is an extremely rare monster,
-occurring at shallow depths.
-It is moderately strong, hellishly dangerous,
-and has no magical powers.
-
-The Inertia hound is an uncommon animal,
-occurring at shallow depths.
-It is somewhat weak, just a small bit dangerous,
-and has an inkling of magical powers.
-
-The Impact hound is an uncommon animal,
-occurring at shallow depths.
-It is somewhat weak, just a small bit dangerous,
-and has no magical powers.
-
-The Dread is an uncommon undead monster,
-occurring at shallow depths.
-It is somewhat strong, moderately dangerous,
-and has simple magical powers.
-
-The Ooze elemental is a somewhat rare monster,
-occurring at shallow depths.
-It is very weak, hellishly dangerous,
-and has small magical powers.
-
-The Smoke elemental is a somewhat rare monster,
-occurring at shallow depths.
-It is very weak, moderately dangerous,
-and has rudimentary magical powers.
-
-The Young black dragon is a common dragon,
-occurring at shallow depths.
-It is somewhat weak, just a small bit dangerous,
-and has an inkling of magical powers.
-
-The Mumak is a somewhat rare monster,
-occurring at shallow depths.
-It is alarmingly strong, not one little bit dangerous,
-and has no magical powers.
-
-The Giant red ant is a common animal,
-occurring at shallow depths.
-It is very weak, moderately dangerous,
-and has no magical powers.
-
-The Mature white dragon is a common dragon,
-occurring at shallow depths.
-It is moderately strong, somewhat dangerous,
-and has an inkling of magical powers.
-
-The Xorn is an uncommon monster,
-occurring at shallow depths.
-It is very weak, very dangerous,
-and has no magical powers.
-
-The Shadow is a somewhat rare undead monster,
-occurring at shallow depths.
-It is very weak, extremely dangerous,
-and has an inkling of magical powers.
-
-The Phantom is a somewhat rare undead monster,
-occurring at shallow depths.
-It is somewhat strong, extremely dangerous,
-and has an inkling of magical powers.
-
-The Grey wraith is a common undead monster,
-occurring at shallow depths.
-It is very weak, somewhat dangerous,
-and has small magical powers.
-
-The Young multi-hued dragon is a common dragon,
-occurring at shallow depths.
-It is somewhat weak, very dangerous,
-and has very powerful magical powers.
-
-The Colossus is a rare monster,
-occurring at shallow depths.
-It is hellishly strong, extremely dangerous,
-and has no magical powers.
-
-The Young gold dragon is an uncommon dragon,
-occurring at shallow depths.
-It is somewhat weak, not at all dangerous,
-and has an inkling of magical powers.
-
-Rogrog the Black Troll is a unique troll,
-occurring at shallow depths.
-He is hellishly strong, moderately dangerous,
-and has no magical powers.
-
-The Mature blue dragon is a common dragon,
-occurring at shallow depths.
-It is moderately strong, somewhat dangerous,
-and has an inkling of magical powers.
-
-The Mature green dragon is a common dragon,
-occurring at shallow depths.
-It is moderately strong, somewhat dangerous,
-and has an inkling of magical powers.
-
-The Mature bronze dragon is an uncommon dragon,
-occurring at shallow depths.
-It is somewhat strong, just a small bit dangerous,
-and has rudimentary magical powers.
-
-The Young red dragon is a common dragon,
-occurring at shallow depths.
-It is somewhat weak, just a small bit dangerous,
-and has an inkling of magical powers.
-
-The Trapper is a somewhat rare monster,
-occurring at shallow depths.
-It is strong, moderately dangerous,
-and has no magical powers.
-
-The Bodak is an uncommon monster,
-occurring at shallow depths.
-It is moderately strong, somewhat dangerous,
-and has average magical powers.
-
-The Ice elemental is an uncommon monster,
-occurring at shallow depths.
-It is moderately strong, moderately dangerous,
-and has unremarkable magical powers.
-
-The Necromancer is an uncommon monster,
-occurring at shallow depths.
-He is somewhat weak, just a little bit dangerous,
-and has unimaginably powerful magical powers.
-
-Lorgan, Chief of the Easterlings is a unique monster,
-occurring at shallow depths.
-He is hellishly strong, very dangerous,
-and has rudimentary magical powers.
-
-The Demonologist is an uncommon monster,
-occurring at shallow depths.
-He is somewhat weak, not at all dangerous,
-and has unremarkable magical powers.
-
-The Mummified troll is a common undead monster,
-occurring at shallow depths.
-It is very weak, moderately dangerous,
-and has no magical powers.
-
-The Queen Ant is a unique animal,
-occurring at shallow depths.
-She is hellishly strong, moderately dangerous,
-and has rudimentary magical powers.
-
-The Will o' the Wisp is a rare monster,
-occurring at shallow depths.
-It is somewhat weak, hellishly dangerous,
-and has average magical powers.
-
-The Magma elemental is an uncommon monster,
-occurring at shallow depths.
-It is moderately strong, extremely dangerous,
-and has simple magical powers.
-
-The Black pudding is an extremely rare monster,
-occurring at shallow depths.
-It is moderately strong, hellishly dangerous,
-and has no magical powers.
-
diff --git a/lib/file/book-17.txt b/lib/file/book-17.txt
deleted file mode 100644
index 18f2b663..00000000
--- a/lib/file/book-17.txt
+++ /dev/null
@@ -1,250 +0,0 @@
-The Killer blue beetle is an uncommon animal,
-occurring at shallow depths.
-It is somewhat weak, somewhat dangerous,
-and has no magical powers.
-
-The Nexus vortex is a common monster,
-occurring at shallow depths.
-It is somewhat weak, not one little bit dangerous,
-and has no magical powers.
-
-The Plasma vortex is a common monster,
-occurring at shallow depths.
-It is somewhat weak, somewhat dangerous,
-and has no magical powers.
-
-The Mature red dragon is a common dragon,
-occurring at shallow depths.
-It is somewhat strong, somewhat dangerous,
-and has rudimentary magical powers.
-
-The Mature gold dragon is an uncommon dragon,
-occurring at shallow depths.
-It is strong, just a small bit dangerous,
-and has rudimentary magical powers.
-
-The Crystal drake is an uncommon dragon,
-occurring at shallow depths.
-It is strong, somewhat dangerous,
-and has small magical powers.
-
-The Mature black dragon is a common dragon,
-occurring at shallow depths.
-It is somewhat strong, somewhat dangerous,
-and has an inkling of magical powers.
-
-The Mature multi-hued dragon is an uncommon dragon,
-occurring at shallow depths.
-It is very strong, extremely dangerous,
-and has extremely powerful magical powers.
-
-The Death knight is a common monster,
-occurring at shallow depths.
-It is very strong, somewhat dangerous,
-and has remarkable magical powers.
-
-Castamir the Usurper is a unique monster,
-occurring at shallow depths.
-He is alarmingly strong, not at all dangerous,
-and has extremely powerful magical powers.
-
-The Time vortex is a rare monster,
-occurring at shallow depths.
-It is somewhat weak, not one little bit dangerous,
-and has no magical powers.
-
-The Shimmering vortex is a rare monster,
-occurring at shallow depths.
-It is extremely weak, not one little bit dangerous,
-and has small magical powers.
-
-The Ancient blue dragon is a common dragon,
-occurring at shallow depths.
-It is very strong, somewhat dangerous,
-and has rudimentary magical powers.
-
-The Ancient bronze dragon is an uncommon dragon,
-occurring at shallow depths.
-It is extremely strong, somewhat dangerous,
-and has rudimentary magical powers.
-
-The Beholder is a rare monster,
-occurring at shallow depths.
-It is hellishly strong, hellishly dangerous,
-and has hellishly powerful magical powers.
-
-The Emperor wight is an uncommon undead monster,
-occurring at shallow depths.
-It is moderately strong, somewhat dangerous,
-and has small magical powers.
-
-The Planetar is a legendary monster,
-occurring at shallow depths.
-It is somewhat strong, extremely dangerous,
-and has hellishly powerful magical powers.
-
-Vargo, Tyrant of Fire is a unique monster,
-occurring at shallow depths.
-It is hellishly strong, moderately dangerous,
-and has unremarkable magical powers.
-
-The Black wraith is an uncommon undead monster,
-occurring at shallow depths.
-It is somewhat strong, somewhat dangerous,
-and has small magical powers.
-
-The Erinyes is an uncommon monster,
-occurring at shallow depths.
-She is very weak, moderately dangerous,
-and has an inkling of magical powers.
-
-The Nether wraith is an uncommon undead monster,
-occurring at shallow depths.
-It is somewhat strong, moderately dangerous,
-and has unremarkable magical powers.
-
-The Eldrak is a somewhat rare troll,
-occurring at shallow depths.
-It is extremely strong, somewhat dangerous,
-and has no magical powers.
-
-The Ettin is a somewhat rare troll,
-occurring at shallow depths.
-It is hellishly strong, somewhat dangerous,
-and has no magical powers.
-
-Waldern, King of Water is a unique monster,
-occurring at shallow depths.
-It is hellishly strong, somewhat dangerous,
-and has unimaginably powerful magical powers.
-
-Kavlax the Many-Headed is a unique dragon,
-occurring at shallow depths.
-He is hellishly strong, moderately dangerous,
-and has hellishly powerful magical powers.
-
-The Ancient white dragon is a common dragon,
-occurring at shallow depths.
-It is very strong, somewhat dangerous,
-and has rudimentary magical powers.
-
-The Ancient green dragon is a common dragon,
-occurring at shallow depths.
-It is extremely strong, somewhat dangerous,
-and has rudimentary magical powers.
-
-The 7-headed hydra is an uncommon animal,
-occurring at shallow depths.
-It is unimaginably strong, moderately dangerous,
-and has unremarkable magical powers.
-
-The Night mare is a somewhat rare undead monster,
-occurring at shallow depths.
-It is hellishly strong, very dangerous,
-and has no magical powers.
-
-The Vampire lord is a somewhat rare undead monster,
-occurring at shallow depths.
-It is hellishly strong, unimaginably dangerous,
-and has very powerful magical powers.
-
-The Ancient black dragon is a common dragon,
-occurring at shallow depths.
-It is extremely strong, somewhat dangerous,
-and has rudimentary magical powers.
-
-The Disenchanter worm mass is a somewhat rare animal,
-occurring at shallow-to-moderate depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Rotting quylthulg is a common animal,
-occurring at shallow-to-moderate depths.
-It is extremely weak, just a small bit dangerous,
-and has unremarkable magical powers.
-
-The Spirit troll is a somewhat rare troll,
-occurring at shallow-to-moderate depths.
-It is unimaginably strong, very dangerous,
-and has no magical powers.
-
-The Lesser titan is a somewhat rare monster,
-occurring at shallow-to-moderate depths.
-It is unimaginably strong, moderately dangerous,
-and has unremarkable magical powers.
-
-The 9-headed hydra is an uncommon animal,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, just a small bit dangerous,
-and has simple magical powers.
-
-The Enchantress is a rare monster,
-occurring at shallow-to-moderate depths.
-She is somewhat strong, somewhat dangerous,
-and has rudimentary magical powers.
-
-The Archpriest is an uncommon monster,
-occurring at shallow-to-moderate depths.
-He is somewhat strong, somewhat dangerous,
-and has arcane magical powers.
-
-The Sorcerer is an uncommon monster,
-occurring at shallow-to-moderate depths.
-He is somewhat strong, somewhat dangerous,
-and has hellishly powerful magical powers.
-
-The Xaren is a common monster,
-occurring at shallow-to-moderate depths.
-It is moderately strong, very dangerous,
-and has no magical powers.
-
-The Giant roc is a somewhat rare animal,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, somewhat dangerous,
-and has no magical powers.
-
-Uvatha the Horseman is a unique undead monster,
-occurring at shallow-to-moderate depths.
-He is hellishly strong, extremely dangerous,
-and has no magical powers.
-
-The Minotaur is an uncommon monster,
-occurring at shallow-to-moderate depths.
-It is unimaginably strong, not one little bit dangerous,
-and has no magical powers.
-
-Medusa, the Gorgon is a unique monster,
-occurring at shallow-to-moderate depths.
-She is hellishly strong, moderately dangerous,
-and has hellishly powerful magical powers.
-
-The Death drake is an uncommon dragon,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, hellishly dangerous,
-and has small magical powers.
-
-The Ancient red dragon is a common dragon,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, somewhat dangerous,
-and has rudimentary magical powers.
-
-The Ancient gold dragon is an uncommon dragon,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, somewhat dangerous,
-and has rudimentary magical powers.
-
-The Great crystal drake is an uncommon dragon,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, somewhat dangerous,
-and has small magical powers.
-
-The Vrock is an uncommon monster,
-occurring at shallow-to-moderate depths.
-It is moderately strong, moderately dangerous,
-and has no magical powers.
-
-The Death quasit is a somewhat rare monster,
-occurring at shallow-to-moderate depths.
-It is somewhat strong, alarmingly dangerous,
-and has unremarkable magical powers.
-
diff --git a/lib/file/book-18.txt b/lib/file/book-18.txt
deleted file mode 100644
index c36b205f..00000000
--- a/lib/file/book-18.txt
+++ /dev/null
@@ -1,250 +0,0 @@
-Adunaphel the Quiet is a unique undead monster,
-occurring at shallow-to-moderate depths.
-She is hellishly strong, moderately dangerous,
-and has hellishly powerful magical powers.
-
-The Dark elven sorceror is an uncommon monster,
-occurring at shallow-to-moderate depths.
-He is extremely strong, just a small bit dangerous,
-and has hellishly powerful magical powers.
-
-The Master lich is an uncommon undead monster,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, extremely dangerous,
-and has hellishly powerful magical powers.
-
-The Hezrou is a somewhat rare monster,
-occurring at shallow-to-moderate depths.
-It is somewhat strong, moderately dangerous,
-and has rudimentary magical powers.
-
-Akhorahil the Blind is a unique undead monster,
-occurring at shallow-to-moderate depths.
-He is hellishly strong, somewhat dangerous,
-and has hellishly powerful magical powers.
-
-Gorlim, Betrayer of Barahir is a unique monster,
-occurring at shallow-to-moderate depths.
-He is hellishly strong, hellishly dangerous,
-and has remarkable magical powers.
-
-The Solar is a legendary monster,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, alarmingly dangerous,
-and has advanced magical powers.
-
-The Glabrezu is an uncommon monster,
-occurring at shallow-to-moderate depths.
-It is strong, somewhat dangerous,
-and has rudimentary magical powers.
-
-Ren the Unclean is a unique undead monster,
-occurring at shallow-to-moderate depths.
-He is hellishly strong, moderately dangerous,
-and has hellishly powerful magical powers.
-
-The Nalfeshnee is an uncommon monster,
-occurring at shallow-to-moderate depths.
-It is very strong, somewhat dangerous,
-and has small magical powers.
-
-The Undead beholder is a rare undead monster,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, hellishly dangerous,
-and has hellishly powerful magical powers.
-
-The Dread is a common undead monster,
-occurring at shallow-to-moderate depths.
-It is somewhat strong, extremely dangerous,
-and has simple magical powers.
-
-The Mumak is an uncommon monster,
-occurring at shallow-to-moderate depths.
-It is alarmingly strong, just a small bit dangerous,
-and has no magical powers.
-
-The Ancient multi-hued dragon is a common dragon,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, alarmingly dangerous,
-and has extremely powerful magical powers.
-
-The Ethereal dragon is an uncommon dragon,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, moderately dangerous,
-and has average magical powers.
-
-Ji Indur Dawndeath is a unique undead monster,
-occurring at shallow-to-moderate depths.
-He is hellishly strong, moderately dangerous,
-and has very powerful magical powers.
-
-The Marilith is an uncommon monster,
-occurring at shallow-to-moderate depths.
-She is hellishly strong, somewhat dangerous,
-and has an inkling of magical powers.
-
-Quaker, Master of Earth is a unique monster,
-occurring at shallow-to-moderate depths.
-He is hellishly strong, hellishly dangerous,
-and has rudimentary magical powers.
-
-The Lesser Balrog is a somewhat rare monster,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, moderately dangerous,
-and has simple magical powers.
-
-Ariel, Queen of Air is a unique monster,
-occurring at shallow-to-moderate depths.
-She is hellishly strong, hellishly dangerous,
-and has average magical powers.
-
-The 11-headed hydra is an uncommon animal,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, just a small bit dangerous,
-and has extremely powerful magical powers.
-
-The Patriarch is an uncommon monster,
-occurring at shallow-to-moderate depths.
-He is extremely strong, somewhat dangerous,
-and has extremely powerful magical powers.
-
-The Dreadmaster is an uncommon undead monster,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, unimaginably dangerous,
-and has very powerful magical powers.
-
-The Drolem is a somewhat rare dragon,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, hellishly dangerous,
-and has small magical powers.
-
-Scatha the Worm is a unique dragon,
-occurring at shallow-to-moderate depths.
-He is hellishly strong, somewhat dangerous,
-and has small magical powers.
-
-Dwar, Dog Lord of Waw is a unique undead monster,
-occurring at shallow-to-moderate depths.
-He is hellishly strong, moderately dangerous,
-and has hellishly powerful magical powers.
-
-Smaug the Golden is a unique dragon,
-occurring at shallow-to-moderate depths.
-He is hellishly strong, somewhat dangerous,
-and has small magical powers.
-
-The Dracolich is an uncommon undead monster,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, alarmingly dangerous,
-and has simple magical powers.
-
-The Greater titan is a somewhat rare monster,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, moderately dangerous,
-and has simple magical powers.
-
-The Dracolisk is an uncommon dragon,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, somewhat dangerous,
-and has simple magical powers.
-
-The Death mold is a common monster,
-occurring at shallow-to-moderate depths.
-It is hellishly strong, hellishly dangerous,
-and has no magical powers.
-
-Itangast the Fire Drake is a unique dragon,
-occurring at shallow-to-moderate depths.
-He is hellishly strong, somewhat dangerous,
-and has small magical powers.
-
-Glaurung, Father of the Dragons is a unique dragon,
-occurring at shallow-to-moderate depths.
-He is hellishly strong, somewhat dangerous,
-and has unremarkable magical powers.
-
-The Master mystic is a somewhat rare monster,
-occurring at moderate depths.
-He is hellishly strong, hellishly dangerous,
-and has small magical powers.
-
-Durin's Bane is a unique monster,
-occurring at moderate depths.
-He is hellishly strong, moderately dangerous,
-and has remarkable magical powers.
-
-The Nightwing is a rare undead monster,
-occurring at moderate depths.
-It is hellishly strong, hellishly dangerous,
-and has hellishly powerful magical powers.
-
-The Nether hound is an uncommon animal,
-occurring at moderate depths.
-It is very strong, just a small bit dangerous,
-and has an inkling of magical powers.
-
-The Time hound is a rare animal,
-occurring at moderate depths.
-It is very strong, just a small bit dangerous,
-and has no magical powers.
-
-The Plasma hound is an uncommon animal,
-occurring at moderate depths.
-It is very strong, somewhat dangerous,
-and has an inkling of magical powers.
-
-The Demonic quylthulg is a common animal,
-occurring at moderate depths.
-It is moderately strong, just a small bit dangerous,
-and has unremarkable magical powers.
-
-The Great storm wyrm is an uncommon dragon,
-occurring at moderate depths.
-It is hellishly strong, somewhat dangerous,
-and has rudimentary magical powers.
-
-Baphomet the Minotaur Lord is a unique monster,
-occurring at moderate depths.
-He is hellishly strong, somewhat dangerous,
-and has hellishly powerful magical powers.
-
-Harowen the Black Hand is a unique monster,
-occurring at moderate depths.
-He is hellishly strong, moderately dangerous,
-and has no magical powers.
-
-Hoarmurath of Dir is a unique undead monster,
-occurring at moderate depths.
-He is hellishly strong, somewhat dangerous,
-and has hellishly powerful magical powers.
-
-The Grand master mystic is a somewhat rare monster,
-occurring at moderate depths.
-He is hellishly strong, hellishly dangerous,
-and has arcane magical powers.
-
-Khamul the Easterling is a unique undead monster,
-occurring at moderate depths.
-He is hellishly strong, moderately dangerous,
-and has hellishly powerful magical powers.
-
-The Ethereal hound is a somewhat rare animal,
-occurring at moderate depths.
-It is unimaginably strong, somewhat dangerous,
-and has an inkling of magical powers.
-
-The Great ice wyrm is an uncommon dragon,
-occurring at moderate depths.
-It is hellishly strong, somewhat dangerous,
-and has rudimentary magical powers.
-
-The Phoenix is a unique animal,
-occurring at moderate depths.
-It is hellishly strong, alarmingly dangerous,
-and has hellishly powerful magical powers.
-
-The Nightcrawler is a rare undead monster,
-occurring at moderate depths.
-It is hellishly strong, unimaginably dangerous,
-and has hellishly powerful magical powers.
-
diff --git a/lib/file/book-19.txt b/lib/file/book-19.txt
deleted file mode 100644
index 62ecebc9..00000000
--- a/lib/file/book-19.txt
+++ /dev/null
@@ -1,250 +0,0 @@
-The Hand druj is a rare undead monster,
-occurring at moderate depths.
-It is very strong, somewhat dangerous,
-and has extremely powerful magical powers.
-
-The Eye druj is a rare undead monster,
-occurring at moderate depths.
-It is unimaginably strong, moderately dangerous,
-and has hellishly powerful magical powers.
-
-The Skull druj is a rare undead monster,
-occurring at moderate depths.
-It is hellishly strong, hellishly dangerous,
-and has hellishly powerful magical powers.
-
-The Chaos vortex is a common monster,
-occurring at moderate depths.
-It is very strong, not one little bit dangerous,
-and has no magical powers.
-
-The Aether vortex is an uncommon monster,
-occurring at moderate depths.
-It is strong, unimaginably dangerous,
-and has hellishly powerful magical powers.
-
-The Lernean Hydra is a unique animal,
-occurring at moderate depths.
-It is hellishly strong, alarmingly dangerous,
-and has hellishly powerful magical powers.
-
-Thuringwethil is a unique undead monster,
-occurring at moderate depths.
-She is hellishly strong, alarmingly dangerous,
-and has very powerful magical powers.
-
-The Great hell wyrm is an uncommon dragon,
-occurring at moderate depths.
-It is hellishly strong, somewhat dangerous,
-and has rudimentary magical powers.
-
-The Draconic quylthulg is a somewhat rare animal,
-occurring at moderate depths.
-It is very strong, just a small bit dangerous,
-and has unremarkable magical powers.
-
-Fundin Bluecloak is a unique monster,
-occurring at moderate depths.
-It is hellishly strong, extremely dangerous,
-and has unimaginably powerful magical powers.
-
-Uriel, Angel of Fire is a unique monster,
-occurring at moderate depths.
-He is hellishly strong, alarmingly dangerous,
-and has hellishly powerful magical powers.
-
-Azriel, Angel of Death is a unique monster,
-occurring at moderate depths.
-He is hellishly strong, extremely dangerous,
-and has hellishly powerful magical powers.
-
-Ancalagon the Black is a unique dragon,
-occurring at moderate depths.
-He is hellishly strong, moderately dangerous,
-and has extremely powerful magical powers.
-
-The Nightwalker is a rare undead monster,
-occurring at moderate depths.
-It is hellishly strong, hellishly dangerous,
-and has hellishly powerful magical powers.
-
-Gabriel, the Messenger is a unique monster,
-occurring at moderate depths.
-He is hellishly strong, hellishly dangerous,
-and has remarkable magical powers.
-
-Saruman of Many Colours is a unique monster,
-occurring at moderate-to-deep depths.
-He is hellishly strong, hellishly dangerous,
-and has hellishly powerful magical powers.
-
-The Dreadlord is an uncommon undead monster,
-occurring at moderate-to-deep depths.
-It is hellishly strong, unimaginably dangerous,
-and has arcane magical powers.
-
-The Cat Lord is a unique monster,
-occurring at moderate-to-deep depths.
-He is hellishly strong, hellishly dangerous,
-and has an inkling of magical powers.
-
-The Chaos beetle is a rare monster,
-occurring at moderate-to-deep depths.
-It is hellishly strong, not at all dangerous,
-and has rudimentary magical powers.
-
-The Chaos hound is a common animal,
-occurring at moderate-to-deep depths.
-It is hellishly strong, just a small bit dangerous,
-and has an inkling of magical powers.
-
-The Great Wyrm of Chaos is an uncommon dragon,
-occurring at moderate-to-deep depths.
-It is hellishly strong, somewhat dangerous,
-and has very powerful magical powers.
-
-The Great Wyrm of Law is an uncommon dragon,
-occurring at moderate-to-deep depths.
-It is hellishly strong, somewhat dangerous,
-and has very powerful magical powers.
-
-The Great Wyrm of Balance is a rare dragon,
-occurring at moderate-to-deep depths.
-It is hellishly strong, somewhat dangerous,
-and has hellishly powerful magical powers.
-
-Tselakus, the Dreadlord is a unique undead monster,
-occurring at moderate-to-deep depths.
-He is hellishly strong, hellishly dangerous,
-and has hellishly powerful magical powers.
-
-Tiamat, Celestial Dragon of Evil is a unique dragon,
-occurring at deep depths.
-She is hellishly strong, unimaginably dangerous,
-and has hellishly powerful magical powers.
-
-The Black reaver is a somewhat rare undead monster,
-occurring at deep depths.
-It is hellishly strong, hellishly dangerous,
-and has hellishly powerful magical powers.
-
-The Master quylthulg is a somewhat rare animal,
-occurring at deep depths.
-It is hellishly strong, just a small bit dangerous,
-and has hellishly powerful magical powers.
-
-The Greater draconic quylthulg is a somewhat rare animal,
-occurring at deep depths.
-It is hellishly strong, just a small bit dangerous,
-and has simple magical powers.
-
-The Greater rotting quylthulg is a somewhat rare animal,
-occurring at deep depths.
-It is hellishly strong, just a small bit dangerous,
-and has simple magical powers.
-
-Vecna, the Emperor Lich is a unique undead monster,
-occurring at deep depths.
-He is hellishly strong, unimaginably dangerous,
-and has hellishly powerful magical powers.
-
-Omarax the Eye Tyrant is a unique monster,
-occurring at deep depths.
-He is hellishly strong, hellishly dangerous,
-and has hellishly powerful magical powers.
-
-Ungoliant, the Unlight is a unique animal,
-occurring at deep depths.
-She is hellishly strong, hellishly dangerous,
-and has hellishly powerful magical powers.
-
-The Aether hound is an uncommon animal,
-occurring at deep depths.
-It is hellishly strong, very dangerous,
-and has hellishly powerful magical powers.
-
-The Mouth of Sauron is a unique monster,
-occurring at deep depths.
-He is hellishly strong, hellishly dangerous,
-and has hellishly powerful magical powers.
-
-The Emperor Quylthulg is a unique animal,
-occurring at deep depths.
-It is hellishly strong, just a little bit dangerous,
-and has unimaginably powerful magical powers.
-
-Qlzqqlzuup, the Lord of Flesh is a unique animal,
-occurring at deep depths.
-It is hellishly strong, just a little bit dangerous,
-and has hellishly powerful magical powers.
-
-Murazor, the Witch-King of Angmar is a unique undead monster,
-occurring at very deep depths.
-He is hellishly strong, extremely dangerous,
-and has hellishly powerful magical powers.
-
-Pazuzu, Lord of Air is a unique monster,
-occurring at very deep depths.
-He is hellishly strong, hellishly dangerous,
-and has advanced magical powers.
-
-The Hell hound is a rare animal,
-occurring at very deep depths.
-It is somewhat strong, moderately dangerous,
-and has an inkling of magical powers.
-
-Cantoras, the Skeletal Lord is a unique undead monster,
-occurring at very deep depths.
-He is hellishly strong, unimaginably dangerous,
-and has hellishly powerful magical powers.
-
-The Tarrasque is a unique monster,
-occurring at very deep depths.
-It is hellishly strong, somewhat dangerous,
-and has average magical powers.
-
-Lungorthin, the Balrog of White Fire is a unique monster,
-occurring at very deep depths.
-He is hellishly strong, extremely dangerous,
-and has advanced magical powers.
-
-Draugluin, Sire of All Werewolves is a unique animal,
-occurring at very deep depths.
-He is hellishly strong, moderately dangerous,
-and has simple magical powers.
-
-Feagwath the Undead Sorceror is a unique undead monster,
-occurring at extremely deep depths.
-He is hellishly strong, hellishly dangerous,
-and has hellishly powerful magical powers.
-
-Carcharoth, the Jaws of Thirst is a unique animal,
-occurring at extremely deep depths.
-He is hellishly strong, moderately dangerous,
-and has advanced magical powers.
-
-Cerberus, Guardian of Hades is a unique animal,
-occurring at extremely deep depths.
-It is hellishly strong, moderately dangerous,
-and has very powerful magical powers.
-
-Gothmog, the High Captain of Balrogs is a unique monster,
-occurring at extremely deep depths.
-He is hellishly strong, unimaginably dangerous,
-and has advanced magical powers.
-
-Sauron, the Sorcerer is a unique monster,
-occurring at extremely deep depths.
-He is hellishly strong, hellishly dangerous,
-and has hellishly powerful magical powers.
-
-Morgoth, Lord of Darkness is a unique monster,
-occurring at bottomless depths.
-He is hellishly strong, hellishly dangerous,
-and has hellishly powerful magical powers.
-
-The Haughty noble is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
diff --git a/lib/file/book-9.txt b/lib/file/book-9.txt
deleted file mode 100644
index 2c37a3aa..00000000
--- a/lib/file/book-9.txt
+++ /dev/null
@@ -1,240 +0,0 @@
-The Filthy street urchin is an uncommon monster,
-occurring at surface depths.
-He is laughably weak, just a little bit dangerous,
-and has no magical powers.
-
-The Scrawny cat is a somewhat rare animal,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Scruffy little dog is a somewhat rare animal,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-Farmer Maggot is a unique monster,
-occurring at surface depths.
-He is somewhat weak, somewhat dangerous,
-and has no magical powers.
-
-The Blubbering idiot is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Boil-covered wretch is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Village idiot is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Pitiful looking beggar is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Mangy looking leper is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Squint eyed rogue is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Singing, happy drunk is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Aimless looking merchant is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Mean looking mercenary is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Town Guardsman is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Grey mold is a common monster,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Grey mushroom patch is a common monster,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Giant yellow centipede is a common monster,
-occurring at surface depths.
-It is laughably weak, not at all dangerous,
-and has no magical powers.
-
-The Giant white centipede is a common monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The White icky thing is a common monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Clear icky thing is a common monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Giant white mouse is a common monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Large brown snake is a common monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Large white snake is a common monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Small kobold is a common monster,
-occurring at surface depths.
-It is laughably weak, just a little bit dangerous,
-and has no magical powers.
-
-The Kobold is a common monster,
-occurring at surface depths.
-It is laughably weak, just a little bit dangerous,
-and has no magical powers.
-
-The White worm mass is a common animal,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Floating eye is a common monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Rock lizard is a common animal,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Jackal is a common animal,
-occurring at surface depths.
-It is laughably weak, just a small bit dangerous,
-and has no magical powers.
-
-The Soldier ant is a common monster,
-occurring at surface depths.
-It is laughably weak, not at all dangerous,
-and has no magical powers.
-
-The Fruit bat is a common animal,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Shrieker mushroom patch is a common monster,
-occurring at surface depths.
-It is laughably weak, not at all dangerous,
-and has an inkling of magical powers.
-
-The Blubbering icky thing is a common monster,
-occurring at surface depths.
-It is laughably weak, just a little bit dangerous,
-and has no magical powers.
-
-The Metallic green centipede is a common monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Novice warrior is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Novice rogue is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Novice priest is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has small magical powers.
-
-The Novice mage is a common monster,
-occurring at surface depths.
-He is laughably weak, not one little bit dangerous,
-and has rudimentary magical powers.
-
-The Yellow mushroom patch is a common monster,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The White jelly is a common monster,
-occurring at surface depths.
-It is laughably weak, somewhat dangerous,
-and has no magical powers.
-
-The Giant green frog is a common animal,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Giant black ant is a common monster,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Salamander is a common animal,
-occurring at surface depths.
-It is laughably weak, just a little bit dangerous,
-and has no magical powers.
-
-The White harpy is a common animal,
-occurring at surface depths.
-She is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-The Blue yeek is a common animal,
-occurring at surface depths.
-It is laughably weak, not one little bit dangerous,
-and has no magical powers.
-
-Grip, Farmer Maggot's dog is a unique animal,
-occurring at surface depths.
-It is laughably weak, just a small bit dangerous,
-and has no magical powers.
-
-Fang, Farmer Maggot's dog is a unique animal,
-occurring at surface depths.
-It is laughably weak, just a small bit dangerous,
-and has no magical powers.
-
-The Green worm mass is a common animal,
-occurring at surface depths.
-It is laughably weak, just a small bit dangerous,
-and has no magical powers.
-
diff --git a/lib/help/debug.txt b/lib/help/debug.txt
index 8aea13ee..afe71920 100644
--- a/lib/help/debug.txt
+++ b/lib/help/debug.txt
@@ -17,13 +17,13 @@ will not be scored if you use debug commands.
*****debug.txt*5[c Create object] *****debug.txt*6[C Create artifact]
*****debug.txt*7[d Detect all] *****debug.txt*8[D Teleport to the wilderness]
*****debug.txt*9[e Edit character attributes] *****debug.txt*10[E Change grid's mana]
- *****debug.txt*11[f *IDENTIFY*] *****debug.txt*12[F Features]
+ f (unused) *****debug.txt*12[F Features]
*****debug.txt*13[g Create good item] G (unused)
*****debug.txt*15[h Change life rating] *****debug.txt*16[H Hostile monster creation]
- *****debug.txt*17[i Identify] I (unused)
+ i (unused) I (unused)
*****debug.txt*19[j Jump to other level] J (unused)
*****debug.txt*21[k Check attributes] K (unused)
- *****debug.txt*23[l Learn about objects] L (unused)
+ l (unused) L (unused)
*****debug.txt*25[m Magic Mapping] *****debug.txt*26[M Gain corruption]
*****debug.txt*27[n Summon named monster] *****debug.txt*28[N Summon _friendly_ named monster]
*****debug.txt*29[o Edit object attributes] O (unused)
@@ -118,9 +118,6 @@ maximal legal value.
Alter how much mana a grid has.
Use the "Command count", aka 0, to specify the amount of mana
that you want.
-~~~~~11
-[[[[[G*IDENTIFY* (f)]
- Like a Scroll of *Identify*.
~~~~~12
[[[[[GFeatures (F)]
Use the "Command count", aka 0, to specify a number from
@@ -135,9 +132,6 @@ maximal legal value.
~~~~~16
[[[[[GHostile monster creation (H)]
Summons a Pack of Creatures of the same kind.
-~~~~~17
-[[[[[GIdentify (i)]
- Like a Scroll of Identify.
~~~~~19
[[[[[GJump to other level (j)]
Jump to other dungeon level. This does not work in the
@@ -145,9 +139,6 @@ maximal legal value.
~~~~~21
[[[[[GCheck attributes (k)]
Displays your characters attributes.
-~~~~~23
-[[[[[GLearn about objects (l)]
- Make you know about all objects. Not sure how this works.
~~~~~25
[[[[[GMagic Mapping (m)]
Like a Scroll of Magic mapping.
diff --git a/lib/help/g_eru.txt b/lib/help/g_eru.txt
index 113875b3..f7e0406f 100644
--- a/lib/help/g_eru.txt
+++ b/lib/help/g_eru.txt
@@ -34,7 +34,7 @@ in asking for his help without offending him!
There is a special book called the "Holy Tome of Eru Iluvatar" which
contains instructions for the procedure for each of the prayers Eru will
-grant. There are four prayers all told, which are:
+grant. There are three prayers all told, which are:
1. [[[[[BSee the Music] (Level 1)
Allows you to 'see' the Great Music from which the world originates,
allowing you to see unseen things, and can be cast while blind.
@@ -46,11 +46,7 @@ grant. There are four prayers all told, which are:
allowing you to understand the meaning of things.
At spell level 14 it allows you to identify all your pack.
At spell level 30 it allows you to identify all items on the level.
-3. [[[[[BKnow the Music] (Level 30)
- Allows you to understand the Great Music from which the world originates,
- allowing you to know the full abilities of things.
- At spell level 10 it allows you to *identify* all your pack.
-4. [[[[[BLay of Protection] (Level 35)
+3. [[[[[BLay of Protection] (Level 35)
Creates a circle of safety around you.
Each of these spells can be increased in level both by improving your Prayer
diff --git a/lib/help/m_divin.txt b/lib/help/m_divin.txt
index e6490df8..ee480b10 100644
--- a/lib/help/m_divin.txt
+++ b/lib/help/m_divin.txt
@@ -21,17 +21,8 @@ There are six spells available for the divination school. These Spells are:
2. [[[[[sSense Hidden] (school level 5)
Detects the traps in a certain radius around you.
At spell level 15 it allows you to sense invisible monsters for a while.
-3. [[[[[sIdentify] (school level 8)
- Asks for an object and identifies it.
- At spell level 17 it identifies all objects in the inventory.
- At spell level 27 it identifies all objects in the inventory and in a
- radius on the floor.
-4. [[[[[sReveal Ways] (school level 9)
+3. [[[[[sReveal Ways] (school level 9)
Detects the doors/stairs/ways in a certain radius around you.
-5. [[[[[sVision] (school level 15)
+4. [[[[[sVision] (school level 15)
Detects the layout of the surrounding area.
At spell level 25 it maps and lights the whole level.
-6. [[[[[sGreater Identify] (school level 35)
- Asks for an object and fully identifies it, providing the full list of
- powers (as with a scroll of *Identify*).
- Cast at yourself, it will reveal your powers (Self Knowledge).
diff --git a/lib/help/macrofaq.txt b/lib/help/macrofaq.txt
index a82074c1..7488165e 100644
--- a/lib/help/macrofaq.txt
+++ b/lib/help/macrofaq.txt
@@ -1784,13 +1784,7 @@ AND - logical AND
IOR - inclusive OR
EQU - (string) equals
NOT - logical negation
-LEQ - (string) less than or equal to
-GEQ - (string) greater than or equal to
[,] - group expressions
-$CLASS - current class
-$GRAF - 3-letter graphics abbr in "graf-***.prf" (old, new)
-$PLAYER - current player name
-$RACE - current race
$SYS - 3-letter system abbr in "pref-***.prf" (ami, mac, win,...)
0 - false
@@ -1801,10 +1795,10 @@ encountered until the next conditional pref line are skipped.
This isn't an actual command. It only works in pref files.
-The variables $CLASS, $GRAF, $PLAYER, $RACE, $PLAYER, $SYS and the
-string values they take on are case sensitive. The values also can't
-contain spaces. These constraints on the values hold when they are
-used in a pref file, but might not when used as pref filenames.
+The variable $SYS and the string value it may take on are case
+sensitive. The values also can't contain spaces. These constraints on
+the values hold when they are used in a pref file, but might not when
+used as pref filenames.
This can be "turned back on" using the pref line "?:1", which is
generally the last line in a file which contains conditional macros,
diff --git a/lib/help/wishing.txt b/lib/help/wishing.txt
index d16f5ae9..29fcab24 100644
--- a/lib/help/wishing.txt
+++ b/lib/help/wishing.txt
@@ -10,11 +10,12 @@ Due to the powerful nature of wishes, there are some rules that govern
what is able to be wished for. These rules are as follows:
1. You cannot wish for a wish, or any other item which would grant more
wishes.
-2. A wish will always generate *one* object. So, never put a number, "a"
+2. A wish will always generate *one* object. The name must be typed EXACTLY
+ as it would appear as an item (case insensitive). So, never put a number, "a"
or "an" in front of the object you are wishing for.
3. It is not possible to wish for the magical +'s to the object (i.e. you
- cannot wish for "gloves of slaying (+10,+10)", but you can wish for
- "gloves of slaying").
+ cannot wish for "set of leather gloves of slaying (+10,+10)", but you can wish for
+ "set of leather gloves of slaying").
4. You cannot wish for artifacts, but you *can* wish for excellent (ego)
items.
5. You can wish for monsters and ego monsters (e.g. "cave orc", "rogue cave
diff --git a/lib/mods/theme/CMakeLists.txt b/lib/mods/theme/CMakeLists.txt
index f1160786..eb729375 100644
--- a/lib/mods/theme/CMakeLists.txt
+++ b/lib/mods/theme/CMakeLists.txt
@@ -1,7 +1,6 @@
INSTALL(DIRECTORY
apex
data
- dngn
edit
file
help
diff --git a/lib/mods/theme/dngn/dun1.14 b/lib/mods/theme/dngn/dun1.14
deleted file mode 100644
index 6421e80b..00000000
--- a/lib/mods/theme/dngn/dun1.14
+++ /dev/null
@@ -1,2 +0,0 @@
-# On this level there is a stairway leading to the Heart of the Earth
-B:10
diff --git a/lib/mods/theme/dngn/dun1.22 b/lib/mods/theme/dngn/dun1.22
deleted file mode 100644
index cbf78046..00000000
--- a/lib/mods/theme/dngn/dun1.22
+++ /dev/null
@@ -1,2 +0,0 @@
-# On this level there is a stairway leading to a trail left by a purposeful dwarf
-B:40 \ No newline at end of file
diff --git a/lib/mods/theme/dngn/dun10.0 b/lib/mods/theme/dngn/dun10.0
deleted file mode 100644
index b89ce05e..00000000
--- a/lib/mods/theme/dngn/dun10.0
+++ /dev/null
@@ -1,3 +0,0 @@
-# Father branch is Mirkwood(1), on level 14
-A:1
-L:14
diff --git a/lib/mods/theme/dngn/dun11.20 b/lib/mods/theme/dngn/dun11.20
deleted file mode 100644
index 9cc611d3..00000000
--- a/lib/mods/theme/dngn/dun11.20
+++ /dev/null
@@ -1,2 +0,0 @@
-# On this level there is a stairway leading to the Nether Realm
-B:6
diff --git a/lib/mods/theme/dngn/dun11.22 b/lib/mods/theme/dngn/dun11.22
deleted file mode 100644
index 149e2c33..00000000
--- a/lib/mods/theme/dngn/dun11.22
+++ /dev/null
@@ -1,2 +0,0 @@
-#I'm downright evil
-F:NO_GENO |
diff --git a/lib/mods/theme/dngn/dun17.15 b/lib/mods/theme/dngn/dun17.15
deleted file mode 100644
index d08bf5e7..00000000
--- a/lib/mods/theme/dngn/dun17.15
+++ /dev/null
@@ -1,5 +0,0 @@
-N:Machine
-U:s_factory.map
-D:The clatter of strange machinery surrounds you.
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT
diff --git a/lib/mods/theme/dngn/dun18.0 b/lib/mods/theme/dngn/dun18.0
deleted file mode 100644
index da1b6c27..00000000
--- a/lib/mods/theme/dngn/dun18.0
+++ /dev/null
@@ -1,2 +0,0 @@
-# The level is SAVED in the playername.mz? file
-#S:mz0
diff --git a/lib/mods/theme/dngn/dun18.1 b/lib/mods/theme/dngn/dun18.1
deleted file mode 100644
index 70f27718..00000000
--- a/lib/mods/theme/dngn/dun18.1
+++ /dev/null
@@ -1,2 +0,0 @@
-# The level is SAVED in the playername.mz? file
-#S:mz1
diff --git a/lib/mods/theme/dngn/dun19.11 b/lib/mods/theme/dngn/dun19.11
deleted file mode 100644
index 7fba690d..00000000
--- a/lib/mods/theme/dngn/dun19.11
+++ /dev/null
@@ -1,5 +0,0 @@
-N:Deathwatch
-U:s_death.map
-D:This level looks filled with evilness.
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT
diff --git a/lib/mods/theme/dngn/dun2.31 b/lib/mods/theme/dngn/dun2.31
deleted file mode 100644
index dd8669a5..00000000
--- a/lib/mods/theme/dngn/dun2.31
+++ /dev/null
@@ -1,2 +0,0 @@
-# On this level there is a stairway leading to the Mount Doom
-B:5
diff --git a/lib/mods/theme/dngn/dun20.1 b/lib/mods/theme/dngn/dun20.1
deleted file mode 100644
index 61bc6a65..00000000
--- a/lib/mods/theme/dngn/dun20.1
+++ /dev/null
@@ -1,5 +0,0 @@
-U:s_smaug.map
-N:Lower Halls
-D:You can just make out a malevolent red glow at the end of the corridor.
-F:DESC
-F:NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR | ASK_LEAVE \ No newline at end of file
diff --git a/lib/mods/theme/dngn/dun22.10 b/lib/mods/theme/dngn/dun22.10
deleted file mode 100644
index e7eb116e..00000000
--- a/lib/mods/theme/dngn/dun22.10
+++ /dev/null
@@ -1,2 +0,0 @@
-# On this level there is a stairway leading to the Small Water Cave
-B:24
diff --git a/lib/mods/theme/dngn/dun22.20 b/lib/mods/theme/dngn/dun22.20
deleted file mode 100644
index a04a2788..00000000
--- a/lib/mods/theme/dngn/dun22.20
+++ /dev/null
@@ -1,5 +0,0 @@
-N:The Bridge
-U:s_bridge.map
-D:You hear the beating of drums in the Deep.
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT \ No newline at end of file
diff --git a/lib/mods/theme/dngn/dun22.5 b/lib/mods/theme/dngn/dun22.5
deleted file mode 100644
index 11d8e51f..00000000
--- a/lib/mods/theme/dngn/dun22.5
+++ /dev/null
@@ -1,5 +0,0 @@
-N:Orc Town
-U:s_orc.map
-D:You hear orc warcries.
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT
diff --git a/lib/mods/theme/dngn/dun24.0 b/lib/mods/theme/dngn/dun24.0
deleted file mode 100644
index bbb93f85..00000000
--- a/lib/mods/theme/dngn/dun24.0
+++ /dev/null
@@ -1,3 +0,0 @@
-# Father branch is the Moria(22), on level 10
-A:22
-L:10
diff --git a/lib/mods/theme/dngn/dun29.15 b/lib/mods/theme/dngn/dun29.15
deleted file mode 100644
index 4df873b5..00000000
--- a/lib/mods/theme/dngn/dun29.15
+++ /dev/null
@@ -1,6 +0,0 @@
-N:Galleon
-U:s_ship.map
-D:A ship of antique design lies jammed in the ice here.
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT
-
diff --git a/lib/mods/theme/dngn/dun3.18 b/lib/mods/theme/dngn/dun3.18
deleted file mode 100644
index 84c0a74a..00000000
--- a/lib/mods/theme/dngn/dun3.18
+++ /dev/null
@@ -1,5 +0,0 @@
-N:Dim Gates
-U:s_gates.map
-D:Visions of death fill your mind.
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT
diff --git a/lib/mods/theme/dngn/dun3.28 b/lib/mods/theme/dngn/dun3.28
deleted file mode 100644
index 0acd4193..00000000
--- a/lib/mods/theme/dngn/dun3.28
+++ /dev/null
@@ -1,5 +0,0 @@
-N:Nameless
-U:s_name.map
-D:You sense a powerful artifact here.
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT
diff --git a/lib/mods/theme/dngn/dun3.3 b/lib/mods/theme/dngn/dun3.3
deleted file mode 100644
index 710ef5f8..00000000
--- a/lib/mods/theme/dngn/dun3.3
+++ /dev/null
@@ -1,5 +0,0 @@
-N:Crypt
-U:s_crypt.map
-D:Looks like a forgotten crypt...
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT
diff --git a/lib/mods/theme/dngn/dun36.5 b/lib/mods/theme/dngn/dun36.5
deleted file mode 100644
index 9fddd4dd..00000000
--- a/lib/mods/theme/dngn/dun36.5
+++ /dev/null
@@ -1,5 +0,0 @@
-N:Orthanc
-U:s_orthanc.map
-D:#BAnd here you shall stay, foolish adventurer, and die quickly. For I am Saruman the Wise, Saruman the Ring-maker, Saruman of Many Colours!#w
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT \ No newline at end of file
diff --git a/lib/mods/theme/dngn/dun39.0 b/lib/mods/theme/dngn/dun39.0
deleted file mode 100644
index 57fa485e..00000000
--- a/lib/mods/theme/dngn/dun39.0
+++ /dev/null
@@ -1,9 +0,0 @@
-# Father branch is Barrow-Downs(4), on level 10
-A:4
-L:9
-
-N:Bilbo's trail
-U:s_bilbo.map
-D:#yYou hear someone shout, "I am in a frightful hurry, but Gandalf told me to leave this map for you! Find it, then seek Thorin in Mirkwood!"#w
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT \ No newline at end of file
diff --git a/lib/mods/theme/dngn/dun4.9 b/lib/mods/theme/dngn/dun4.9
deleted file mode 100644
index e09273d6..00000000
--- a/lib/mods/theme/dngn/dun4.9
+++ /dev/null
@@ -1,2 +0,0 @@
-# On this level there is a stairway leading to a trail left by a fleeing hobbit
-B:39 \ No newline at end of file
diff --git a/lib/mods/theme/dngn/dun40.0 b/lib/mods/theme/dngn/dun40.0
deleted file mode 100644
index 0cd769c4..00000000
--- a/lib/mods/theme/dngn/dun40.0
+++ /dev/null
@@ -1,9 +0,0 @@
-# Father branch is Mirkwood(1), on level 33
-A:1
-L:22
-
-N:Thorin's trail
-U:s_thorin.map
-D:#yYou hear someone shout, "My mad kinsmen have taken the key to the Lonely Mountain! Get the key, then find that fool hobbit and my map! If you haven't already."#w
-F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:ASK_LEAVE | NO_TELEPORT \ No newline at end of file
diff --git a/lib/mods/theme/dngn/dun5.0 b/lib/mods/theme/dngn/dun5.0
deleted file mode 100644
index 48a7bea6..00000000
--- a/lib/mods/theme/dngn/dun5.0
+++ /dev/null
@@ -1,3 +0,0 @@
-# Father branch is the Mordor, on level 32
-A:2
-L:31
diff --git a/lib/mods/theme/dngn/dun5.14 b/lib/mods/theme/dngn/dun5.14
deleted file mode 100644
index 3d7a3080..00000000
--- a/lib/mods/theme/dngn/dun5.14
+++ /dev/null
@@ -1,14 +0,0 @@
-# The level is SAVED in the playername.mdm file
-S:mdm
-
-# Use the map in s_doom.map file
-U:s_doom.map
-
-# Use Mt Doom as level name
-N:Mt Doom
-
-D:You finally reach the top of Mount Doom, here must lie the Great Fire.
-F:DESC
-F:NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR
-F:NO_TELEPORT
-
diff --git a/lib/mods/theme/dngn/dun6.0 b/lib/mods/theme/dngn/dun6.0
deleted file mode 100644
index c750ea67..00000000
--- a/lib/mods/theme/dngn/dun6.0
+++ /dev/null
@@ -1,3 +0,0 @@
-# Father branch is Void(11), on level 20
-A:11
-L:20
diff --git a/lib/mods/theme/edit/a_info.txt b/lib/mods/theme/edit/a_info.txt
index 5d2e4bdf..b416a069 100644
--- a/lib/mods/theme/edit/a_info.txt
+++ b/lib/mods/theme/edit/a_info.txt
@@ -58,7 +58,6 @@ F:LITE3
F:SEE_INVIS
F:SPEED
a:MAP_LIGHT
-Z:detect curses
D:The shining Star of the West, a famed heirloom of Elendil's house.
D:A white diamond set as a star in a silver fillet to be bound at the
D:forehead.
@@ -412,17 +411,13 @@ N:15:of Orthanc
I:39:106:0
W:15:12:15:20000
P:0:1d1:0:0:0
-F:ACTIVATE
-F:EASY_USE
F:INSTA_ART
F:LITE1
F:SPECIAL_GENE
-a:STONE_LORE
-D:The key to the tower of Saruman, which fills your mind
-D:with images of knowledge and dreadful understanding. It
-D:is not a regular key - it is a perfectly round stone
-D:that is meant to fit into a hole. It can be used to
-D:light your way in the dungeon as well.
+D:The key to the tower of Saruman. It is not a regular
+D:key - it is a perfectly round stone that is meant
+D:to fit into a hole. It can be used to light your
+D:way in the dungeon as well.
# The Multi-Hued Dragon Scale Mail 'Lothronfaun'
@@ -2808,7 +2803,7 @@ F:SLAY_EVIL
F:SPELL_CONTAIN
F:WIELD_CAST
F:WIS
-a:ID_PLAIN
+a:DETECT_ALL
D:The radiant golden staff of an Istari of legend, this wizard's companion
D:grants keen sight and the knowledge of many hidden things.
@@ -3690,23 +3685,6 @@ D:Crafted of purest ice and held solid by powerful spells, this icy axe
D:delivers a chill of death to its victims.
-# The Iron Helm of Knowledge
-
-N:160:of Knowledge
-I:32:5:-6
-W:20:5:75:100000
-P:6:1d3:0:0:20
-F:ACTIVATE
-F:AUTO_ID
-F:HIDE_TYPE
-F:LITE1
-F:LUCK
-F:SPECIAL_GENE
-a:KNOWLEDGE
-D:This helm, designed by Petty-Dwarves ages ago to act as the brain of a
-D:long lost project, is made of finest glass. Its light banishes all secrets,
-D:and makes audible whispers from the deceased.
-
# The Broken Sword 'Narsil'
N:164:'Narsil'
@@ -4553,7 +4531,6 @@ F:SEE_INVIS
F:WATER_BREATH
F:WIS
a:PALANTIR
-Z:detect curses
D:This holy lamp once belonged to a seeress who warned Ar-Pharazon of
D:the dire fate Numenor would suffer for daring to break the ban against
D:mortals' entering the Blessed Realms alive. The king had the seeress
diff --git a/lib/mods/theme/edit/ba_info.txt b/lib/mods/theme/edit/ba_info.txt
index c8c7f9c5..2e853040 100644
--- a/lib/mods/theme/edit/ba_info.txt
+++ b/lib/mods/theme/edit/ba_info.txt
@@ -69,10 +69,6 @@ N:13:Game rules
C:0:0:0
I:13:0:r
-N:14:Research item
-C:1400:1300:1200
-I:1:0:a
-
N:15:Town history
C:0:0:0
I:2:0:h
@@ -109,10 +105,6 @@ N:26:Recharge item
C:350:300:75
I:25:0:r
-N:27:Identify possessions
-C:900:800:100
-I:26:0:i
-
N:28:Healing prayer
C:600:400:0
I:28:0:h
@@ -162,16 +154,6 @@ N:43:View fate
C:500:500:500
I:42:0:v
-#for The Mirror
-N:44:Research item
-C:1500:1500:1500
-I:1:0:a
-
-#for Star-Dome
-N:46:Identify possessions
-C:1200:1000:250
-I:26:0:i
-
#for Star-Dome
N:47:Recharge item
C:1200:1000:150
diff --git a/lib/mods/theme/edit/d_info.txt b/lib/mods/theme/edit/d_info.txt
index 0f8680af..5266090a 100644
--- a/lib/mods/theme/edit/d_info.txt
+++ b/lib/mods/theme/edit/d_info.txt
@@ -56,6 +56,8 @@ F:NO_DESTROY
F:NO_DOORS
F:PRINCIPAL
R:100:0
+@:14:B:10
+@:22:B:40
N:2:Barad-Dur
D:BDr:a door to the tower of Barad-Dur.
@@ -72,6 +74,7 @@ F:NO_RECALL
F:NO_STREAMERS
F:PRINCIPAL
R:100:0
+@:31:B:5
N:3:Angband
D:Ang:an entrance to the Pits of Angband.
@@ -87,6 +90,33 @@ F:NO_EASY_MOVE
F:NO_RECALL
F:PRINCIPAL
R:100:0
+@:3:N:Crypt
+@:3:U:s_crypt.map
+@:3:D:Looks like a forgotten crypt...
+@:3:F:NO_GENO
+@:3:F:NO_NEW_MONSTER
+@:3:F:SPECIAL
+@:3:F:NO_STAIR
+@:3:F:ASK_LEAVE
+@:3:F:NO_TELEPORT
+@:18:N:Dim Gates
+@:18:U:s_gates.map
+@:18:D:Visions of death fill your mind.
+@:18:F:NO_GENO
+@:18:F:NO_NEW_MONSTER
+@:18:F:SPECIAL
+@:18:F:NO_STAIR
+@:18:F:ASK_LEAVE
+@:18:F:NO_TELEPORT
+@:28:N:Nameless
+@:28:U:s_name.map
+@:28:D:You sense a powerful artifact here.
+@:28:F:NO_GENO
+@:28:F:NO_NEW_MONSTER
+@:28:F:SPECIAL
+@:28:F:NO_STAIR
+@:28:F:ASK_LEAVE
+@:28:F:NO_TELEPORT
N:4:Barrow-Downs
D:BDw:a way to the Barrow-Downs.
@@ -103,6 +133,7 @@ F:PRINCIPAL
R:25:1
M:UNDEAD
R:75:0
+@:9:B:39
# The Additional dungeons
@@ -123,6 +154,15 @@ F:NO_RECALL
F:NO_STREAMERS
R:100:1
M:IM_FIRE
+@:14:N:Mt Doom
+@:14:S:mdm
+@:14:U:s_doom.map
+@:14:D:You finally reach the top of Mount Doom, here must lie the Great Fire.
+@:14:F:NO_GENO
+@:14:F:NO_NEW_MONSTER
+@:14:F:SPECIAL
+@:14:F:NO_STAIR
+@:14:F:NO_TELEPORT
# Nether Realm
# Levels 666-696 (!!!)
@@ -274,6 +314,8 @@ M:DRAGON
M:NONLIVING
M:SPIRIT
M:UNDEAD
+@:20:B:6
+@:22:F:NO_GENO
# TEST dungeon
N:12:Test
@@ -312,7 +354,7 @@ M:UNDEAD
# The Illusory Castle
# levels 35-52
-# Guarded by The Glass Golem guarding The Helm of Knowledge
+# Guarded by The Glass Golem
N:17:Illusory Castle
D:Ill:an entrance to the Illusory Castle.
W:35:52:10:24:100
@@ -321,7 +363,6 @@ A:56:50:189:50:56:0:57:58
O:50:10:20:20
E:6d2:6:CONFUSION
F:FILL_METHOD_1
-F:FINAL_ARTIFACT_160
F:FINAL_GUARDIAN_1033
F:NO_STREAMERS
F:RANDOM_TOWNS
@@ -344,6 +385,15 @@ S:BR_CONF
S:CONF
S:FORGET
S:MULTIPLY
+@:15:N:Machine
+@:15:U:s_factory.map
+@:15:D:The clatter of strange machinery surrounds you.
+@:15:F:NO_GENO
+@:15:F:NO_NEW_MONSTER
+@:15:F:SPECIAL
+@:15:F:NO_STAIR
+@:15:F:ASK_LEAVE
+@:15:F:NO_TELEPORT
# The Maze
# Levels 25-37
@@ -386,6 +436,15 @@ R:50:3
M:ORC
M:R_CHAR_O
M:R_CHAR_o
+@:11:N:Deathwatch
+@:11:U:s_death.map
+@:11:D:This level looks filled with evilness.
+@:11:F:NO_GENO
+@:11:F:NO_NEW_MONSTER
+@:11:F:SPECIAL
+@:11:F:NO_STAIR
+@:11:F:ASK_LEAVE
+@:11:F:NO_TELEPORT
# Erebor
# levels 60-72
@@ -412,6 +471,14 @@ M:R_CHAR_D
R:30:1
M:DRAGON
M:R_CHAR_d
+@:1:N:Lower Halls
+@:1:U:s_smaug.map
+@:1:D:You can just make out a malevolent red glow at the end of the corridor.
+@:1:F:NO_GENO
+@:1:F:NO_NEW_MONSTER
+@:1:F:SPECIAL
+@:1:F:NO_STAIR
+@:1:F:ASK_LEAVE
# The Old Forest
# levels 13-25
@@ -463,6 +530,25 @@ M:TROLL
R:20:3
M:DEMON
R:10:0
+@:5:N:Orc Town
+@:5:U:s_orc.map
+@:5:D:You hear orc warcries.
+@:5:F:NO_GENO
+@:5:F:NO_NEW_MONSTER
+@:5:F:SPECIAL
+@:5:F:NO_STAIR
+@:5:F:ASK_LEAVE
+@:5:F:NO_TELEPORT
+@:10:B:24
+@:20:N:The Bridge
+@:20:U:s_bridge.map
+@:20:D:You hear the beating of drums in the Deep.
+@:20:F:NO_GENO
+@:20:F:NO_NEW_MONSTER
+@:20:F:SPECIAL
+@:20:F:NO_STAIR
+@:20:F:ASK_LEAVE
+@:20:F:NO_TELEPORT
# The tower of Dol Guldur
# Levels 57-70
@@ -609,6 +695,15 @@ F:NO_STREAMERS
F:WATER_RIVER
R:100:1
M:IM_COLD
+@:15:N:Galleon
+@:15:U:s_ship.map
+@:15:D:A ship of antique design lies jammed in the ice here.
+@:15:F:NO_GENO
+@:15:F:NO_NEW_MONSTER
+@:15:F:SPECIAL
+@:15:F:NO_STAIR
+@:15:F:ASK_LEAVE
+@:15:F:NO_TELEPORT
# The Lost Temple of "..player.pgod.."
# Generated in god quest.
@@ -797,6 +892,15 @@ R:50:3
M:ORC
M:R_CHAR_O
M:R_CHAR_o
+@:5:N:Orthanc
+@:5:U:s_orthanc.map
+@:5:D:#BAnd here you shall stay, foolish adventurer, and die quickly. For I am Saruman the Wise, Saruman the Ring-maker, Saruman of Many Colours!#w
+@:5:F:NO_GENO
+@:5:F:NO_NEW_MONSTER
+@:5:F:SPECIAL
+@:5:F:NO_STAIR
+@:5:F:ASK_LEAVE
+@:5:F:NO_TELEPORT
# Tol Eressea - of course you never actually set foot on Tol Eressea ;)
# levels 40-45
@@ -857,6 +961,15 @@ F:FLAT
R:25:1
M:UNDEAD
R:75:0
+@:0:N:Bilbo's trail
+@:0:U:s_bilbo.map
+@:0:D:#yYou hear someone shout, "I am in a frightful hurry, but Gandalf told me to leave this map for you! Find it, then seek Thorin in Mirkwood!"#w
+@:0:F:NO_GENO
+@:0:F:NO_NEW_MONSTER
+@:0:F:SPECIAL
+@:0:F:NO_STAIR
+@:0:F:ASK_LEAVE
+@:0:F:NO_TELEPORT
# Thorin's trail in Mirkwood
# just one special level that later becomes a different one, sans princess.
@@ -871,6 +984,15 @@ F:FLAT
F:NO_DESTROY
F:NO_DOORS
R:100:0
+@:0:N:Thorin's trail
+@:0:U:s_thorin.map
+@:0:D:#yYou hear someone shout, "My mad kinsmen have taken the key to the Lonely Mountain! Get the key, then find that fool hobbit and my map! If you haven't already."#w
+@:0:F:NO_GENO
+@:0:F:NO_NEW_MONSTER
+@:0:F:SPECIAL
+@:0:F:NO_STAIR
+@:0:F:ASK_LEAVE
+@:0:F:NO_TELEPORT
# N:<index>:<name>
# D:<3 letter short name>:<long name>
diff --git a/lib/mods/theme/edit/k_info.txt b/lib/mods/theme/edit/k_info.txt
index 6cfe4dee..302759f2 100644
--- a/lib/mods/theme/edit/k_info.txt
+++ b/lib/mods/theme/edit/k_info.txt
@@ -1771,22 +1771,6 @@ A:15/1
D:This scroll will try to enchant a piece of armour in your possession, making it more effective
D:in protecting you. Highly enchanted armour is likely not to accept this enchantment, however.
-N:176:Identify
-G:?:d
-I:70:12:0
-W:1:0:5:50
-A:1/1:5/1:10/1:30/1
-D:If you read this scroll, the identity of an item you specify will be laid open to you.
-
-N:177:*Identify*
-G:?:d
-I:70:13:0
-W:30:0:5:1000
-A:30/1:50/2:80/1:100/1
-D:This scroll will allow you to gain insight into an object's special properties.
-D:Only the highly magical objects, like rare rings and amulets or very unusual weapons
-D:and armour possess abilities which warrant the use of this magic.
-
N:178:Rumour
G:?:d
I:70:51:0
@@ -2895,13 +2879,6 @@ W:30:0:50:100
A:30/1
P:0:1d2:0:0:0
-N:313:Identify
-G:_:d
-I:55:14:-1:SPELL=Identify
-W:10:0:50:100
-A:10/1
-P:0:1d2:0:0:0
-
N:314:Sense Hidden
G:_:d
I:55:15:-1:SPELL=Sense Hidden
@@ -3067,65 +3044,6 @@ D:A thick book with solid leather binding. It looks entirely
D:unremarkable, but as you hold it, you feel strangely able
D:to learn the inner workings of things and creatures.
-##### Chests #####
-
-N:338:& Small wooden chest~
-G:~:s
-I:7:1:0
-W:5:0:250:20
-A:5/1
-P:0:2d3:0:0:0
-D:A small wooden box, locked and possibly trapped.
-
-N:339:& Large wooden chest~
-G:~:s
-I:7:5:0
-W:15:0:500:60
-A:15/1
-P:0:2d5:0:0:0
-D:A large wooden box, locked and possibly trapped
-
-N:340:& Small iron chest~
-G:~:s
-I:7:2:0
-W:25:0:300:100
-A:25/1
-P:0:2d4:0:0:0
-D:A small rectangular container made of wood and reinforced with iron corners and latches.
-D:It is locked and possibly trapped.
-
-N:341:& Large iron chest~
-G:~:s
-I:7:6:0
-W:35:0:1000:150
-A:35/1
-P:0:2d6:0:0:0
-D:A large container made of wood, with a heavy iron lock, and probably a trap.
-
-N:342:& Small steel chest~
-G:~:s
-I:7:3:0
-W:45:0:500:200
-A:45/1
-P:0:2d4:0:0:0
-D:A small wooden box with strong steel locks and reinforcements. It's likely to be trapped.
-
-N:343:& Large steel chest~
-G:~:s
-I:7:7:0
-W:55:0:1000:250
-A:55/1
-P:0:2d6:0:0:0
-D:A nearly indestructible chest of wood and steel. The lock doesn't look impenetrable, but it
-D:might be trapped.
-
-N:344:& Ruined chest~
-G:~:s
-I:7:0:0
-W:0:0:250:0
-A:75/1
-D:A broken, empty chest.
-
##### Various Stuff #####
N:345:& Iron Spike~
@@ -3417,18 +3335,6 @@ F:IGNORE_ELEC
F:IGNORE_FIRE
D:This rod grants you knowledge of your surroundings.
-N:372:Perception
-G:-:d
-I:66:2:20
-W:50:0:15:13000
-A:50/8:100/8
-P:0:1d1:0:0:0
-F:IGNORE_ACID
-F:IGNORE_COLD
-F:IGNORE_ELEC
-F:IGNORE_FIRE
-D:This rod makes you insightful, laying open the identity of your possessions.
-
N:373:Curing
G:-:d
I:66:8:35
@@ -5167,94 +5073,6 @@ A:40/3
D:This parchment contains information about unique
D:artifacts that are rumoured to exist upon Arda.
-N:594:Monstrous Compendium 1
-G:?:o
-I:8:9:0
-W:10:0:5:100
-A:10/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:595:Monstrous Compendium 2
-G:?:o
-I:8:10:0
-W:11:0:5:200
-A:11/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:596:Monstrous Compendium 3
-G:?:o
-I:8:11:0
-W:12:0:5:300
-A:12/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:597:Monstrous Compendium 4
-G:?:o
-I:8:12:0
-W:13:0:5:400
-A:13/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:598:Monstrous Compendium 5
-G:?:o
-I:8:13:0
-W:14:0:5:500
-A:14/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:599:Monstrous Compendium 6
-G:?:o
-I:8:14:0
-W:15:0:5:600
-A:15/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:600:Monstrous Compendium 7
-G:?:o
-I:8:15:0
-W:16:0:5:700
-A:16/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:601:Monstrous Compendium 8
-G:?:o
-I:8:16:0
-W:17:0:5:800
-A:17/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:602:Monstrous Compendium 9
-G:?:o
-I:8:17:0
-W:18:0:5:900
-A:18/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:603:Monstrous Compendium 10
-G:?:o
-I:8:18:0
-W:19:0:5:1000
-A:19/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
-N:604:Monstrous Compendium 11
-G:?:o
-I:8:19:0
-W:20:0:5:1200
-A:20/2
-D:This parchment contains a small part of the collected
-D:lore concerning monsters inhabiting Arda.
-
#### Here come the shape-shifting potions. ####
N:605:& Morphic Oil~ of #
diff --git a/lib/mods/theme/edit/p_info.txt b/lib/mods/theme/edit/p_info.txt
index f8a3e25e..a78258d2 100644
--- a/lib/mods/theme/edit/p_info.txt
+++ b/lib/mods/theme/edit/p_info.txt
@@ -607,7 +607,7 @@ C:a:O:36:6:1d1
C:a:k:+0:-100:Combat
C:a:k:+0:-100:Weaponmastery
C:a:k:+0:-300:Archery
-C:a:k:-1000:-700:Barehand-combat
+C:a:k:+0:-100:Barehand-combat
C:a:k:+0:-200:Spirituality
C:a:k:+1000:+300:Possession
C:a:k:+0:+200:Corpse-preservation
@@ -806,7 +806,6 @@ C:D:1:Pope
C:S:-1:-3:3:-1:0:2:0:0
C:B:4:35:3
C:P:2:20
-C:Z:detect curses
C:G:GOD_FRIEND
C:E:0:0:0:0:0:0
C:k:+1000:+900:Magic
diff --git a/lib/mods/theme/edit/ra_info.txt b/lib/mods/theme/edit/ra_info.txt
index 5add55b4..99a675f0 100644
--- a/lib/mods/theme/edit/ra_info.txt
+++ b/lib/mods/theme/edit/ra_info.txt
@@ -1903,20 +1903,13 @@ C:0:0:0:0
Z:magic map
N:511
-X:30:1
-T:39:0:255
-W:20:1:24
-C:0:0:0:0
-Z:detect curses
-
-N:512
X:25:1
T:39:0:255
W:20:1:17
C:0:0:0:0
Z:dazzle
-N:513
+N:512
X:40:1
T:39:0:255
W:20:1:50
@@ -1924,7 +1917,7 @@ C:0:0:0:0
Z:detect doors and traps
# Magestaves can get % to life - Theme
-N:514
+N:513
X:10:1
T:6:0:255
W:10:1:45
@@ -1932,7 +1925,7 @@ C:-40:-40:0:3
F:LIFE
# Magestaves, armour, lights and jewelry can get ability to store a spell - Theme
-N:515
+N:514
X:10:1
T:6:0:255
T:30:0:255
@@ -1953,7 +1946,7 @@ F:SPELL_CONTAIN
F:WIELD_CAST
# High-level soft and hard armour and DSM can get nether immunity - Theme, adapted from FuryMod
-N:516
+N:515
X:50:1
T:36:11:255
T:37:15:255
@@ -1963,7 +1956,7 @@ C:0:0:0:0
F:IM_NETHER
# Light weapons (no broken ones) can gain sentience - Theme, adapted from FuryMod
-N:517
+N:516
X:20:1
T:21:1:3
T:22:2:4
diff --git a/lib/mods/theme/edit/set_info.txt b/lib/mods/theme/edit/set_info.txt
index 182618d4..a0c696e9 100644
--- a/lib/mods/theme/edit/set_info.txt
+++ b/lib/mods/theme/edit/set_info.txt
@@ -82,7 +82,6 @@ F:IM_FIRE
F:SH_ELEC
# The demonhorn of Gothmog
P:183:3:0
-F:AUTO_ID
F:ESP_EVIL
F:ESP_GOOD
@@ -174,7 +173,6 @@ F:RES_POIS
F:RES_SOUND
# The Palantir of Orthanc
P:202:3:0
-F:AUTO_ID
# Heirlooms of the House of Elendil - set suggested by Massimiliano Marangio in the forums
@@ -254,8 +252,6 @@ F:RES_NETHER
F:SLAY_DEMON
# The Mithril Helm of Gil-Galad
P:26:3:0
-#Why *shouldn't* warrior-types get a chance for AUTO_ID without penalties to luck before they kill Morgy?
-F:AUTO_ID
# Dwarven Heritage
# http://wiki.t-o-m-e.net/IdeaArchive_2fNew_20Item_20Set_3a_20Heritage_20of_20Khazad
@@ -293,8 +289,6 @@ F:SPEED
F:SUST_DEX
# The Quarterstaff of Thranduil
P:74:3:0
-# What can I say. I love archers. :P
-F:AUTO_ID
# Gimli's Gear (Gimli's shield, boots and axe)
diff --git a/lib/mods/theme/edit/st_info.txt b/lib/mods/theme/edit/st_info.txt
index 88303fff..17da3e7c 100644
--- a/lib/mods/theme/edit/st_info.txt
+++ b/lib/mods/theme/edit/st_info.txt
@@ -151,10 +151,6 @@ N:4:Alchemy shop
I:100:Enchant Weapon To-Hit
I:100:Enchant Weapon To-Dam
I:100:Enchant Armour
-I:100:Identify
-I:100:Identify
-I:100:Identify
-I:100:Identify
I:100:Light
I:100:Phase Door
I:100:Phase Door
@@ -180,13 +176,6 @@ I:100:Restore Dexterity
#I:100:Restore Constitution
T:100:71:46
I:100:Restore Charisma
-I:100:Identify
-I:100:*Identify*
-I:100:*Identify*
-I:100:*Identify*
-I:100:*Identify*
-I:100:*Identify*
-I:100:*Identify*
I:100:Light
#I:100:Restore Strength
T:100:71:42
@@ -214,7 +203,6 @@ I:100:Protection
I:100:Charisma
I:100:Slow Digestion
T:100:40:7
-I:100:Searching
I:100:Cure Light Wounds
# Rods
I:25:& Wooden Rod~ of#
@@ -313,11 +301,6 @@ F:RANDOM
W:2
N:13:Library
-I:100:Identify
-I:100:Identify
-I:100:Identify
-I:100:Identify
-I:100:Identify
# starting parchment
T:40:8:20
# Khuzdul
@@ -334,7 +317,7 @@ T:15:8:107
T:10:8:103
# Advanced Sindarin
T:5:8:104
-A:2:3:14:15:16:27
+A:2:3:0:15:16:0
O:86:87:88:89
G:+:U
W:2
@@ -353,28 +336,6 @@ G:+:s
W:0
N:16:Beastmaster Shanty
-# Monstrous Compendium 1
-T:100:8:9
-# Monstrous Compendium 2
-T:100:8:10
-# Monstrous Compendium 3
-T:95:8:11
-# Monstrous Compendium 4
-T:90:8:12
-# Monstrous Compendium 5
-T:85:8:13
-# Monstrous Compendium 6
-T:80:8:14
-# Monstrous Compendium 7
-T:75:8:15
-# Monstrous Compendium 8
-T:70:8:16
-# Monstrous Compendium 9
-T:65:8:17
-# Monstrous Compendium 10
-T:60:8:18
-# Monstrous Compendium 11
-T:55:8:19
A:0:2:21:22:3:0
O:94:95:96:97
G:+:g
@@ -387,7 +348,7 @@ G:+:s
W:0
N:18:Tower of Magery
-A:0:0:26:27:0:0
+A:0:0:26:0:0:0
O:102:103:104:105
G:+:b
W:0
@@ -425,7 +386,7 @@ G:+:U
W:0
N:23:The Mirror
-A:0:0:44:15:16:43
+A:0:0:15:16:43:0
O:51:51:51:51
G:+:U
W:0
@@ -437,7 +398,7 @@ G:+:U
W:0
N:25:Wizards Spire
-A:60:0:26:27:0:0
+A:60:0:26:0:0:0
O:54:54:54:54
G:+:U
W:0
@@ -463,7 +424,6 @@ G:+:U
W:0
N:28:Library
-I:100:Identify
# starting parchment
T:40:8:20
# Khuzdul
@@ -480,7 +440,7 @@ T:15:8:107
T:10:8:103
# Advanced Sindarin
T:5:8:104
-A:0:0:14:15:16:2
+A:0:0:0:15:16:2
O:58:58:58:58
G:+:U
W:12
@@ -523,7 +483,7 @@ G:+:U
W:0
N:33:Star-Dome
-A:0:0:46:47:0:0
+A:0:0:0:47:0:0
O:63:63:63:63
G:+:U
W:0
@@ -677,7 +637,7 @@ T:100:122:256
T:100:123:256
T:100:124:256
T:100:125:256
-A:27:0:1:2:3:4
+A:0:0:1:2:3:4
O:150:151:152:153
G:9:y
F:DEPEND_LEVEL
@@ -702,7 +662,7 @@ T:100:122:256
T:100:123:256
T:100:124:256
T:100:125:256
-A:27:0:1:2:3:4
+A:0:0:1:2:3:4
O:150:151:152:153
G:9:v
F:DEEP_LEVEL
@@ -850,12 +810,6 @@ W:24
## Library quest in Minas Anor
N:60:Library
-I:100:Identify
-I:100:Identify
-I:100:Identify
-I:100:Identify
-I:100:Identify
-I:100:Identify
# starting parchment
T:40:8:20
# Khuzdul
@@ -872,7 +826,7 @@ T:15:8:107
T:10:8:103
# Advanced Sindarin
T:5:8:104
-A:61:0:14:15:16:2
+A:61:0:0:15:16:2
O:210:210:210:210
G:+:U
W:12
@@ -914,8 +868,8 @@ W:24
# Music store
N:64:Music Store
-I:20:& Horn~
-I:20:& Drum~
+I:20:& Horn~
+I:20:& Drum~
I:20:& Harp~
A:0:0:1:2:3:4
O:194:195:196:197
diff --git a/lib/mods/theme/edit/t_bree.txt b/lib/mods/theme/edit/t_bree.txt
index c6b50340..6be8671a 100644
--- a/lib/mods/theme/edit/t_bree.txt
+++ b/lib/mods/theme/edit/t_bree.txt
@@ -126,12 +126,7 @@ D:# ^^^^^^^^^^^^^^ .
D:######################################################################################################################################################################################################
-############### Starting positions ###############
+############### Starting position ###############
-# Standard starting position for normal races
-?:[AND [EQU $LEAVING_QUEST 0] [NOT [EQU $RACE Vampire] ] ]
+?:[EQU $LEAVING_QUEST 0]
P:33:131
-
-# Standard starting position for vampires (at the dungeon entrance)
-?:[AND [EQU $LEAVING_QUEST 0] [EQU $RACE Vampire] ]
-P:31:150
diff --git a/lib/mods/theme/edit/t_d_bree.txt b/lib/mods/theme/edit/t_d_bree.txt
index 92fde41f..f9212b49 100644
--- a/lib/mods/theme/edit/t_d_bree.txt
+++ b/lib/mods/theme/edit/t_d_bree.txt
@@ -80,12 +80,7 @@ D:# ^^^^^^^^^^^^^^ HDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD .DDDD
D:######################################################################################################################################################################################################
-############### Starting positions ###############
+############### Starting position ###############
-# Standard starting position for normal races
-?:[AND [EQU $LEAVING_QUEST 0] [NOT [EQU $RACE Vampire] ] ]
+?:[EQU $LEAVING_QUEST 0]
P:33:131
-
-# Standard starting position for vampires (at the dungeon entrance)
-?:[AND [EQU $LEAVING_QUEST 0] [EQU $RACE Vampire] ]
-P:31:150
diff --git a/lib/mods/theme/file/book-10.txt b/lib/mods/theme/file/book-10.txt
deleted file mode 100644
index 995c2453..00000000
--- a/lib/mods/theme/file/book-10.txt
+++ /dev/null
@@ -1,75 +0,0 @@
- ------------------------
- | Monstrous Compendium 2 |
- | Mostly never-moving |
- ------------------------
-
- *** Floating eyes (e) ***
-
-Strange disembodied eyes, floating around the dungeon. Some
-of them are comparatively harmless (such as the [[[[[oFloating eyes],
-[[[[[RRadiation eyes], [[[[[rBloodshot eyes], and [[[[[vDisenchanter eyes]),
-others moderately dangerous (such as the [[[[[DEvil eyes], [[[[[sGauths],
-[[[[[gGas spores], and [[[[[BSpectators]), yet others extremely deadly -
-these include the [[[[[UBeholders], [[[[[uUndead beholders], [[[[[bEyes of the]
-[[[[[bdeep], and the [[[[[yBeholder hive-mothers]. Whatever you do, do
-not get too close to them
-
-
- *** Jellies (j) ***
-
-You will sometimes encounter large quavering piles of flesh
-just lying around the dungeon or making their way along the
-walls. They all have different defense mechanisms, which with
-time an adventurer will learn to recognise by looking at their
-colour. Among the less dangerous types are [[[[[wWhite jellies], [[[[[rRed]
-[[[[[rjellies], [[[[[bBlue jellies], [[[[[vGrape jellies], [[[[[gGreen jellies], [[[[[WSilver]
-[[[[[Wjellies], [[[[[yYellow jellies], [[[[[oSpotted jellies], and [[[[[uRot jellies].
-Considerably more dangerous are the [[[[[DUndead masses] and [[[[[UOchre]
-[[[[[Ujellies], as well as [[[[[DBlack puddings]. Among the moving jellies,
-watch out for [[[[[gGreen oozes], [[[[[bBlue oozes], [[[[[DBlack oozes], [[[[[GGelatinous]
-[[[[[Gcubes], [[[[[RGibbering mouthers], and [[[[[BAcidic cytoplasms].
-
- *** Molds (m) ***
-
-Molds are strange growths on the dungeon floor which have
-developed defense mechanisms to deal with anyone who tries
-to disturb them. They come in many varieties and prefer
-different habitats, and some of them can be quite dangerous
-because they have rudimentary mastery of the elements. The
-most common varieties of mold are the [[[[[sGrey mold], the [[[[[rRed]
-[[[[[rmold], the [[[[[oHairy mold], the [[[[[gGreen mold], the [[[[[uBrown mold],
-the [[[[[yYellow mold], the [[[[[wWhite mold], and the [[[[[WSilver mold].
-More rare are [[[[[vDisenchanter molds], [[[[[bShimmering molds], [[[[[RPink]
-[[[[[Rmolds], [[[[[GTree molds], and [[[[[BBlue molds]. A very rare and dire
-creature is the [[[[[DDeath mold] - unwary adventurers beware! The
-[[[[[UAdventurer molds] are friendly towards their fellows, but
-not very strong.
-
- *** Mushroom patches (,) ***
-
-You'd think it safe to eat them - you'd be wrong. Mushroom
-patches are masters of disguise and can cause quite a bit
-of damage to unwary adventurers. Fortunately, most of them
-are extremely weak and can be destroyed quickly if you can
-just get close enough. The commonly found varieties include
-the [[[[[sgrey], [[[[[Bclear], [[[[[vpurple], [[[[[ospotted], [[[[[yyellow], [[[[[Rshrieker], [[[[[Ddark],
-[[[[[wwhite], [[[[[ubrown], [[[[[Wsilver], and [[[[[Ggreen] mushroom patches. More rare
-are [[[[[gshambling mounds], [[[[[Bmagic mushroom patches], [[[[[rblood sprouts],
-and [[[[[bmemory mosses].
-
- *** Quylthulgs (Q) ***
-
-Strange pulsing mounds of flesh that looks utterly harmless.
-As with any other monster, however, looks are very deceiving
-when it comes to the [[[[[yQuylthulgs]. They are expert at asking
-for other creatures' help, as weall as conveyance magic. The
-only friendly type is the [[[[[wAdventurer quylthulg] - these have
-many friends among their own kin. The [[[[[vNexus quylthulg] is
-unmatched in conveyance magic; you will have trouble getting
-close to it. The other quylthulgs usually prefer to call for
-aid, and you can tell what kind of creatures are likely to
-come to its call, usually. There are [[[[[DSpider], [[[[[sCanine], [[[[[bAquatic],
-[[[[[uRotting], [[[[[gDraconic], [[[[[rDemonic], [[[[[UGreater rotting], [[[[[Ggreater]
-[[[[[GDraconic], [[[[[RGreater demonic], and [[[[[BMaster quylthulgs].
-
-
diff --git a/lib/mods/theme/file/book-11.txt b/lib/mods/theme/file/book-11.txt
deleted file mode 100644
index 5d211818..00000000
--- a/lib/mods/theme/file/book-11.txt
+++ /dev/null
@@ -1,51 +0,0 @@
- ------------------------
- | Monstrous Compendium 3 |
- | Insects |
- ------------------------
-
- *** Ants (a) ***
-
-Ants are worker six-legged insects, and adventurers will
-encounter many different kinds of these on their travels.
-The [[[[[uSoldier ants] and [[[[[oGiant army ants] are just your
-garden-variety ants, and there are also [[[[[UTermites], which
-breed very quickly, and [[[[[BAquatic ants], which have adapted
-to living underwater. The majority of ants, however, come
-from different families, with rudimentary mastery of the
-elements - they vary from [[[[[wwhite], [[[[[rred], [[[[[sgrey], [[[[[Wsilver],
-[[[[[Dblack], and [[[[[yyellow] to [[[[[bblue], [[[[[Rfire], [[[[[gtree], and
-[[[[[Ggreen].
-
- *** Flying insects (I) ***
-
-There are many different kinds of flying insects in Middle-
-earth - some, like [[[[[BButterflies], are harmless, others are
-only slightly dangerous (like [[[[[WMoths], [[[[[uInsect swarms], and
-[[[[[sGiant fleas]). Yet others are serious nuisances due to their
-explosive breeding, among them are [[[[[gNeekerbreekers], [[[[[GGiant]
-[[[[[Gfruit flies], [[[[[DGiant black midges] and [[[[[wGiant white midges].
-Adventurers should be wary of [[[[[yHummerhorns], [[[[[oKiller bees],
-[[[[[rGiant fireflies], and [[[[[UFlies of Mordor].
-
- *** Dragonflies (F) ***
-
-Large insects with dazzling wings, the dragonflies inhabit
-many different areas on Middle-earth. Among them are giant
-[[[[[Baquatic], [[[[[ygold], [[[[[sblack], [[[[[Ubronze], [[[[[Ggreen], [[[[[wwhite], [[[[[oswamp], [[[[[rred],
-[[[[[gforest], [[[[[bblue], [[[[[ubrown], [[[[[Wsilver], [[[[[vviolet], and [[[[[Rpink] ones -
-all with rudimentary command of some of the elements. The
-[[[[[DDeath dragonflies] are worth watching out for.
-
- *** Spiders (S) ***
-
-Ugly eight-legged creatures, the spiders tend to travel in
-packs, and are thus to be reckoned with. The weaker species
-include the [[[[[BPhase spiders], [[[[[DCave spiders], [[[[[WGiant spiders], and
-[[[[[UWood spiders] - these are only dangerous to very inexperienced
-adventurers. The [[[[[RGiant fire ticks], uGiant brown ticks], [[[[[oGiant]
-[[[[[otarantulas], [[[[[wGiant white ticks], [[[[[sGiant grey scorpions], [[[[[rGiant]
-[[[[[rred scorpions], and [[[[[yGiant yellow scorpions] are more dangerous
-than their smaller cousins. The most dangerous of all spiders
-are the aquatic [[[[[gMurk dwellers], the [[[[[rAraneas], the [[[[[bDriders], the
-dreadful [[[[[GMirkwood spiders], and the powerful [[[[[vElder araneas].
-
diff --git a/lib/mods/theme/file/book-12.txt b/lib/mods/theme/file/book-12.txt
deleted file mode 100644
index 07b5267d..00000000
--- a/lib/mods/theme/file/book-12.txt
+++ /dev/null
@@ -1,68 +0,0 @@
- ------------------------
- | Monstrous Compendium 4 |
- | Animals |
- ------------------------
-
-
- *** Cattle (c) ***
-
-Mostly domesticated four-legged beasts of burden, these
-animals will not bother you unless you bother them first.
-In fact, [[[[[wSheep], [[[[[uCows], [[[[[sHorses], [[[[[WMearas], [[[[[yPonies], [[[[[DOxen],
-[[[[[rKine of Araw], and [[[[[UDeer] will tend to ignore adventurers
-completely. [[[[[oBoars], however, are a different matter. They
-have strong legs and fierce tusks, which they will use
-against anyone who stumbles into their territory.
-
- *** Canines (C) ***
-
-Four-legged animals with shaggy fur. Most of them are not
-very dangerous - in fact, the [[[[[sScruffy little dogs] will
-not do much except growl, and [[[[[yJackals] can be deadly against
-very weak adventurers, but will not hold their own against
-even moderately experienced ones. [[[[[oFoxes], [[[[[uWolves], [[[[[wWhite]
-[[[[[wwolves], and [[[[[BBlink dogs] can be a nuisance, but not overmuch.
-The evil [[[[[gWolf chieftains], [[[[[DWerewolves], [[[[[DWargs], [[[[[RHellhounds],
-and [[[[[rGreater Hellhounds], however, are very dangerous.
-
- *** Felines (f) ***
-
-Lithe, four-legged animals with sleek fur and sharp claws.
-The [[[[[WScrawny cat] lives in the town and tends to walk by
-itself. The [[[[[UWild cats], [[[[[gTree cats], and [[[[[bNight cats] are all
-quite menacing, but only dangerous in packs. The powerful
-[[[[[DPanthers], [[[[[oTigers], [[[[[wSnow tigers], and [[[[[ySabre-tooth tigers]
-are not to be toyed with. The [[[[[uLeopards] and [[[[[RLions] are the
-strongest of all the feline monsters.
-
- *** Quadrupeds (q) ***
-
-Four-legged creatures of varying breeds, these monsters
-are all quite large and fierce - their bulk alone is
-enough to intimidate you. The weakest are the [[[[[yApes], who
-make a lot of noise but aren't very dangerous. The [[[[[WOld]
-[[[[[Wbears] just want everyone to leave them alone. There are
-many other different kinds of bears, among them the
-[[[[[uCave bears], [[[[[rWar bears], [[[[[UGrizzly bears], [[[[[wPolar bears],
-[[[[[bBlue bears], [[[[[RFire bears], [[[[[BAquatic bears], and [[[[[DWerebears].
-The [[[[[sMumakil] are gigantic elephantine forms, stomping all
-over the dungeon and waving their tusks threateningly. The
-[[[[[GNight mares] are fearsome skeletal horses with glowing eyes.
-The [[[[[gCatoblepas] are strange ox-like forms with huge heads but
-thin, weak necks. The [[[[[oRust monsters] are weird, small animals
-that look perpetually hungry.
-
- *** Birds (B) ***
-
-There are many different types of birds on Middle-earth,
-and the [[[[[RChaffinches], [[[[[WSparrows], [[[[[BNightingales], [[[[[UThrushes],
-[[[[[WRavens], [[[[[oGulls], [[[[[rEagles], and [[[[[rGreat eagles] will not harm
-anyone who does not harm them first. The [[[[[wSwans] hold a very
-special place with the Valar, and woe be to anyone who
-knowingly harms a Swan. However, not all birds are harmless.
-The [[[[[RKirinki] can wake up entire towns with their shrill cry,
-The [[[[[sCrows] and [[[[[DCrebain] are ever hungry for carrion, as are
-[[[[[GGorcrows]. The [[[[[uHunting hawks] seek prey without regard for
-friend or foe. The [[[[[DWinged Horrors] are not quite birds, they
-are Great Eagles corrupted by Morgoth to serve his ends.
-
diff --git a/lib/mods/theme/file/book-13.txt b/lib/mods/theme/file/book-13.txt
deleted file mode 100644
index faa7071b..00000000
--- a/lib/mods/theme/file/book-13.txt
+++ /dev/null
@@ -1,54 +0,0 @@
- ------------------------
- | Monstrous Compendium 5 |
- | Fliers and Crawlers |
- ------------------------
-
-
- *** Bats (b) ***
-
-Small flying creatures with webbed wings and sharp teeth.
-The [[[[[ofruit bats] are the weakest of them all. Other kinds
-include [[[[[Utan], [[[[[ubrown], [[[[[wsnow], [[[[[sgrey], [[[[[Wsilver], [[[[[yyellow], [[[[[Ggreen],
-[[[[[rred dragon], [[[[[bblue dragon], and [[[[[vdisenchanter bats]. The most
-dangerous of this race the [[[[[BMongbats], [[[[[dVampire bats], [[[[[gBats]
-[[[[[gof Gorgoroth], and [[[[[RDoombats].
-
- *** Rodents (R) ***
-
-Small chittering creatures with quick feet and sharp teeth.
-The [[[[[Uwild rabbits] are utterly harmless unless angered, as
-are [[[[[oSquirrels]. The various giant mice ([[[[[wwhite], [[[[[Bsilver], [[[[[rred],
-[[[[[bblue], and [[[[[yyellow]) and rats ([[[[[Wwhite], [[[[[sgrey], [[[[[Rpink], and [[[[[Gtree])
-are somewhat dangerous, as they tend to run in large packs.
-The [[[[[urock moles], [[[[[Dwererats], and [[[[[gsquirrels of Mirkwood] are
-among the more dangerous rodents.
-
-
- *** Snakes (J) ***
-
-Fast and stealthy creatures that slither along the floor. The
-[[[[[Ueels] are harmless, except when angered. The large [[[[[bblue], [[[[[Wsilver],
-[[[[[vpurple], [[[[[Rred], [[[[[sgrey], [[[[[yyellow], [[[[[ubrown], and [[[[[wwhite] snakes are
-somewhat dangerous. The [[[[[rRattlesnakes], [[[[[oCopperhead] snakes,
-[[[[[DBlack mambas], and [[[[[gKing cobras] are quite dangerous and fierce.
-The aquatic [[[[[BElectric eels] and [[[[[GLimlugs] (sea serpents) are
-among the most dangerous of their kind.
-
- *** Beetles (K) ***
-
-Very large insects with tough carapaces. Most of them are not
-too dangerous. They come in the following varieties: [[[[[wwhite],
-[[[[[ubrown], [[[[[rred], [[[[[sgray], [[[[[oorange], [[[[[bblue], [[[[[Wsilver], [[[[[Ggreen], [[[[[Utree],
-[[[[[Rfire], [[[[[gstag], [[[[[Baquatic], [[[[[yslicer], [[[[[viridescent], and [[[[[Ddeath watch].
-
-
- *** Reptiles (R) ***
-
-The majority of reptiles found on Middle-earth are not very
-dangerous - these include the [[[[[ynewts], [[[[[ucave lizards], [[[[[Urock lizards],
-[[[[[bnight lizards], [[[[[Bblue lizards], [[[[[oswamp lizards], [[[[[rgiant pink frogs],
-[[[[[ggiant green frogs], [[[[[wsnow-frogs], and [[[[[Wgiant silver frogs]. The
-[[[[[Rgiant salamanders] and [[[[[Ggiant turtles] should be approached
-with caution, while the [[[[[sbasilisks] and [[[[[Dgreater basilisks] are
-extremely dangerous and should not be toyed with!
-
diff --git a/lib/mods/theme/file/book-14.txt b/lib/mods/theme/file/book-14.txt
deleted file mode 100644
index eb79aa38..00000000
--- a/lib/mods/theme/file/book-14.txt
+++ /dev/null
@@ -1,55 +0,0 @@
- ------------------------
- | Monstrous Compendium 6 |
- | Morgoth's minions |
- ------------------------
-
- *** Orcs (o) ***
-
-Squat, swarthy creatures rumoured to have been Elves once.
-The [[[[[Usnotlings] and [[[[[osnaga] are the lowest form of Orc, weak
-but dangerous in packs. There are different breeds of Orc,
-depending on their dwelling-place: [[[[[uHill orcs], [[[[[GCave orcs],
-and [[[[[Dblack orcs]. The [[[[[sHalf-orcs] are a cross-breed of Orcs
-and humans. The [[[[[BUruk-hai] are a stronger breed, they can
-bear the light of the sun. The [[[[[wElite] uruks are the most
-dangerous kind of Orc there is.
-
- *** Ogres (O) ***
-
-Monstrous and destructive creatures of legend and folklore.
-The [[[[[wOgrillon] is a cross-breed of an Orc and an Ogre, and
-the [[[[[oHalf-ogre] is a cross between an Ogre and a human. The
-garden-variety [[[[[UOgres] are more common than their [[[[[gForest]-
-dwelling, [[[[[sMountain]-dwelling, and [[[[[uCave]-dwelling cousins.
-The [[[[[DBlack ogres] shy away from the sun, the [[[[[BMerrows] live
-in or near water. There are some [[[[[yRebel ogres] who have
-turned against their plundering fellows and will try to aid
-adventurers.
-
- *** Giants (P) ***
-
-Enormous humanoids with powerful muscles, aligned with evil.
-There are [[[[[WStone giants], [[[[[BStorm giants], [[[[[rFire giants], [[[[[wFrost]
-[[[[[wgiants], and [[[[[UHill giants] - while very large and dangerous,
-they pale in comparison to the much stronger [[[[[uCyclops], [[[[[bCloud]
-[[[[[bgiants], and the terrifying [[[[[sRock giants]. The [[[[[yLesser titans]
-and [[[[[oGreater titans] are in a class of their own, their power
-and magical abilities unmatched by any. The [[[[[RRebel giants] are
-those who have broken with the forces of Darkness.
-
- *** Trolls (T) ***
-
-Lumbering evil creatures originated in mockery of the Ents.
-The [[[[[UHalf-trolls] are bizarre crosses between trolls and Men.
-The [[[[[uCave-trolls], [[[[[wSnow-trolls], [[[[[sHill trolls], [[[[[gForest trolls],
-[[[[[BWater trolls], and [[[[[WStone trolls] are dangerous and usually
-move in large groups. Even more dangerous are the [[[[[oAlgroths],
-the [[[[[yOlog-hai], and the [[[[[BScrags]. The [[[[[RWar trolls], [[[[[rEldraks], and
-[[[[[bEttins] can only be described as killing machines.
-
- *** Yeeks (y) ***
-
-Small humanoid figures whose origin lies outside Middle-earth.
-There are [[[[[Bblue], [[[[[ubrown], [[[[[Ddark], [[[[[wwhite], [[[[[sgray], and [[[[[yyellow]
-Yeeks. The [[[[[gmaster yeeks] are somewhat proficient at magic, and
-[[[[[Uadventurer yeeks] will try to help you. \ No newline at end of file
diff --git a/lib/mods/theme/file/book-15.txt b/lib/mods/theme/file/book-15.txt
deleted file mode 100644
index 21983f48..00000000
--- a/lib/mods/theme/file/book-15.txt
+++ /dev/null
@@ -1,68 +0,0 @@
- ------------------------
- | Monstrous Compendium 7 |
- | Dragons and Worms |
- ------------------------
-
- *** Worms (w) ***
-
-Large slimy masses of worms crawl all around dungeons.
-There are [[[[[Bclear], [[[[[rred], [[[[[bblue], [[[[[ggreen], [[[[[wwhite], [[[[[yyellow],
-[[[[[Dnether], and [[[[[vdisenchanter] worm masses. Additionally,
-there are [[[[[Ugiant slugs] and [[[[[ugiant leeches] which are more
-dangerous than the worm masses. The [[[[[vpurple worms] and
-[[[[[ysandworms] are even more dangerous, and then there are
-the [[[[[uwereworms], huge wormlike shapes dripping acid.
-
- *** Dragon worms (w) ***
-
-These will eventually grow into dragons, unless killed.
-There are [[[[[Rred], [[[[[Bblue], [[[[[Ggreen], [[[[[Wwhite], [[[[[sblack], [[[[[ygold],
-[[[[[ubronze], and [[[[[vmulti-hued ones].
-
- *** Hatchling dragons (d) ***
-
-The [[[[[opseudo-dragon] is a small relative of the dragon that
-inhabits dark caves. The hatchling dragons are newly-born,
-still soft, with eyes unaccustomed to light and scales
-shimmering with a hint of colour: [[[[[rred], [[[[[bblue], [[[[[ggreen],
-[[[[[wwhite], [[[[[sblack], [[[[[Ubronze], [[[[[ygold], and [[[[[vmulti-hued]. There are
-also the aquatic [[[[[WHatchling dragon turtles].
-
-
- *** Young dragons (d) ***
-
-The young dragons sport still-tender scales, coloured more
-brightly than those of the Hatchling dragons: [[[[[rred], [[[[[bblue],
-[[[[[ggreen], [[[[[wwhite], [[[[[sblack], [[[[[Ubronze], [[[[[ygold], and [[[[[vmulti-hued].
-The [[[[[Wyoung dragon turtles] live in or near water.
-
- *** Drakes (d) ***
-
-These dragons are already mature, and their scales are very
-brightly covered, according to the elements each dragon
-draws its power from. There are [[[[[rFire-drakes], [[[[[bBlue drakes],
-[[[[[gGreen drakes], [[[[[wCold-drakes], [[[[[sBlack drakes], [[[[[UBronze drakes],
-[[[[[yGolden drakes], [[[[[vMulti-hued drakes], [[[[[vBalance drakes], [[[[[vLaw]
-[[[[[vdrakes], [[[[[vChaos drakes], [[[[[uCrystal drakes], [[[[[oEthereal drakes],
-[[[[[GShadow drakes], and [[[[[sMature dragon turtles].
-
-
- *** Ancient dragons (D) ***
-
-These dragons are very old, cunning, and powerful. They are
-considerably larger than the drakes, and they too draw their
-colouring from their elements: [[[[[rred], [[[[[bblue], [[[[[ggreen], [[[[[wwhite],
-[[[[[sblack], [[[[[Ubronze], [[[[[ygold], and [[[[[vmulti-hued]. In addition, there
-are the [[[[[GDeath drakes], [[[[[UGreat crystal drakes], [[[[[oAncient ethereal]
-[[[[[odrakes], [[[[[BSky drakes], and [[[[[WAncient dragon turtles].
-
- *** Greater dragons (D) ***
-
-The mightiest and most powerful of dragonkind, these beasts
-are older than time itself. Their very names instill fear into
-your very soul: the [[[[[rGreat Worm of Fire], the [[[[[bGreat Storm Worm],
-the [[[[[gGreat Swamp Worm], the [[[[[wGreat Ice Worm], the [[[[[sGreat Bile Worm],
-the [[[[[UGreat Worm of Perplexity], the [[[[[yGreat Worm of Thunder],
-the [[[[[vGreat Worm of Many Colours], the [[[[[GFastitocalon], the [[[[[vGreat]
-[[[[[vWorm of Balance], the [[[[[RDracolisk], the [[[[[vGreat Worm of Chaos], the
-[[[[[GDracolich], the [[[[[BGreat Worm of Law], and the [[[[[vGreat Wyrm of Power].
diff --git a/lib/mods/theme/file/book-16.txt b/lib/mods/theme/file/book-16.txt
deleted file mode 100644
index e19b7b0b..00000000
--- a/lib/mods/theme/file/book-16.txt
+++ /dev/null
@@ -1,43 +0,0 @@
- -------------------------
- | Monstrous Compendium 8 |
- | Depth dwellers, hybrids |
- -------------------------
-
- *** Nagas (n) ***
-
-Giant snake-like figures with a woman's torso. There are
-[[[[[ggreen], [[[[[Rred], [[[[[Dblack], [[[[[Bwater], [[[[[oswamp], [[[[[ubrown], [[[[[Wsilver],
-[[[[[vnight], [[[[[Gtree], [[[[[sdark], [[[[[bocean], [[[[[yguardian], and [[[[[wspirit nagas].
-The [[[[[Uadventurer nagas] are friendly to their fellows.
-
- *** Hydras (M) ***
-
-Strange reptilian creatures with several heads, guarding
-treasure hoards. There are [[[[[u2-headed], [[[[[o3-headed], [[[[[y4-headed],
-[[[[[g5-headed], [[[[[w6-headed], [[[[[G7-headed], [[[[[s8-headed], [[[[[r9-headed],
-[[[[[b10-headed], [[[[[R11-headed], [[[[[W12-headed], [[[[[v13-headed], [[[[[B14-headed],
-[[[[[U15-headed], as well as [[[[[DKiller hydras].
-
- *** Hybrids (H) ***
-
-These creatures are all crosses between two (or sometimes
-more) different beings. The [[[[[wWhite harpies], [[[[[DBlack harpies],
-and [[[[[oOwlbears] are not very dangerous. The [[[[[UHippogryphs],
-[[[[[uGriffons], [[[[[RGorgimaerae], [[[[[BBehemoths], [[[[[rChimaerae], [[[[[yManticores],
-and [[[[[GSphinxes] are more dangerous and deadly. The [[[[[bGorgons],
-[[[[[WHeadless], [[[[[gSwamp things], and [[[[[vJabberwocks] are the deadliest.
-
- *** Depth dwellers (~) ***
-
-These creatures inhabit the oceans, lakes, and seas of Arda.
-Along with the [[[[[BSand mites], [[[[[BBox jellyfish], [[[[[GBarracudas], and
-[[[[[RPiranhas] there are [[[[[yStargazers], [[[[[gOctopi], [[[[[WGlobefish], [[[[[sPikes],
-[[[[[sSwordfish], and [[[[[sFlounders]. More dangerous are [[[[[rGiant crayfish],
-[[[[[RGiant piranhas], and [[[[[gGiant squid]. Among the larger depth-
-dwellers, there are the [[[[[WHammerhead sharks], [[[[[oTiger sharks],
-[[[[[wWhite sharks], [[[[[oSeahorses], and [[[[[gGiant octopi]. The largest and
-more dangerous creatures include the [[[[[DWhales], [[[[[UElder stargazers],
-[[[[[wGreat white sharks], [[[[[uUndead stargazers], [[[[[GLesser Krakens],
-[[[[[wKiller whales], and [[[[[GGreater Krakens]. The most dangerous ocean
-dweller is the [[[[[vLeviathan].
-
diff --git a/lib/mods/theme/file/book-17.txt b/lib/mods/theme/file/book-17.txt
deleted file mode 100644
index 13aa439f..00000000
--- a/lib/mods/theme/file/book-17.txt
+++ /dev/null
@@ -1,47 +0,0 @@
- ------------------------
- | Monstrous Compendium 9 |
- | Undead Creatures |
- ------------------------
-
- *** Mewlips (i) ***
-
-Mewlips are evil cannibal spirits from the marshlands.
-They come in different varieties: [[[[[wclear], [[[[[sgray], [[[[[oorange],
-[[[[[rbloodshot], [[[[[ggreen], [[[[[bblue], [[[[[ubrown], [[[[[Wstone], [[[[[yyellow], [[[[[Rpink],
-[[[[[Gtree], [[[[[Bair], [[[[[Uplague], and [[[[[Ddeath].
-
-
- *** Golems (g) ***
-
-Massive animated statues made from different materials.
-There are [[[[[obronze], [[[[[wbone], [[[[[ueog], [[[[[Bmithril], [[[[[siron], [[[[[baquatic],
-[[[[[Wstone], [[[[[Uclay], [[[[[Rflesh], and [[[[[ffire golems], in addition to the
-more cunning [[[[[ycolbrans], [[[[[DPukelmen], [[[[[gdrolems], [[[[[Gcolossus], and
-[[[[[ssilent watchers].
-
- *** Skeletons (s) ***
-
-There are skeletal forms of just about any monster that once
-inhabited Middle-earth. Some such forms, however, have never
-been alive in the first place - they are horrible abominations
-animated by powerful wizards. Among them are the [[[[[wice skeletons],
-[[[[[sflying skulls], [[[[[Dcrypt creeps], [[[[[yhand druj], [[[[[oskull druj], and
-[[[[[reye druj].
-
- *** Zombies (z) ***
-
-Zombie forms of all living creatures may appear in the dungeons.
-However, some zombie-like undead from before the First Age do
-exist: [[[[[Ughouls], [[[[[ygreater mummies], [[[[[Dghoulkings], [[[[[ughasts], and
-[[[[[Rrotting corpses].
-
- *** Vampires (V) ***
-
-There are vampire forms of just about any race - [[[[[Whuman], [[[[[Gelf], [[[[[Dorc],
-[[[[[wyeek], [[[[[oogre], [[[[[utroll], [[[[[Rdwarf], and [[[[[Bgnome]. The [[[[[sOriental vampires]
-come from beyond the land of Rhun. There are [[[[[bVampire lords], [[[[[rElder]
-[[[[[rvampires], and [[[[[gMaster vampires]. The [[[[[UAdventurer vampires] are those
-who have denounced the way of the Dark and attempt to follow a path
-of Light as best they can.
-
-
diff --git a/lib/mods/theme/file/book-18.txt b/lib/mods/theme/file/book-18.txt
deleted file mode 100644
index 36cbee04..00000000
--- a/lib/mods/theme/file/book-18.txt
+++ /dev/null
@@ -1,55 +0,0 @@
- --------------------------
- | Monstrous Compendium 10 |
- | Demons and other Horrors |
- --------------------------
-
- *** Minor Demons (u) ***
-
-These demons (roeg) are corrupted forms of natural creatures.
-The individual types of demons are as follows: [[[[[bLimrog] (fish),
-[[[[[UCaborrog] (frog), [[[[[DLygrog] (snake), [[[[[oDraugrog] (wolf), [[[[[rHurog] (dog),
-[[[[[sSarnrog] (stone), [[[[[gNarrog] (rat), [[[[[yAewrog] (bird), [[[[[BRawrog] (lion),
-and [[[[[RAdanrog] (human).
-
- *** Major Demons (u) ***
-
-The major demons are of two kinds - the spider demons, spawn of
-Ungoliant, and the Balroeg, corrupted Maiar. The spider demons
-are as follows: [[[[[gUngorrog] (power spider demon), [[[[[WHelcungol] (ice),
-[[[[[rNaurungol] (fire), [[[[[sMornungol] (black), and [[[[[BFaunungol] (cloud).
-There are also the [[[[[BGaurroeg] (water demons), [[[[[oMorgulroeg] (magic
-demons), [[[[[uDagorrog] (war demons), [[[[[ySererrog] (blood demons), and
-the [[[[[UMenelroeg] (sky demons). The Balroeg can be [[[[[RRed], [[[[[DBlack],
-[[[[[wWhite], and [[[[[bBlue] - commanded by [[[[[GBalrog Captains] and [[[[[vGreater]
-[[[[[vBalroeg].
-
- *** Greater Undead (G) ***
-
-The ghosts are incorporeal beings with awesome magical powers.
-Some of them aren't very impressive, like the [[[[[gGreen glutton]
-[[[[[gghost] and the [[[[[sPoltergeist]. Others are deadlier - [[[[[wGhosts],
-[[[[[BPhantom beasts], [[[[[BDrowned souls], [[[[[BPhantom warriors], the [[[[[DShadows],
-[[[[[DPossessors], [[[[[DShades], and [[[[[USpectres]. The friendly [[[[[WSpirits] will
-try to help adventurers. The [[[[[bBanshee], [[[[[GSpirit troll], [[[[[vPhantom],
-[[[[[uHeadless ghost], and [[[[[uMoaning spirit] are all to be reckoned with.
-In a class of their own are the [[[[[oDreads], [[[[[rDreadlords], and the
-[[[[[yDreadmasters].
-
- *** Liches (L) ***
-
-Yet another kind of powerful undead. Many things can take the form
-of a lich, but the [[[[[oLich], [[[[[GCrypt thing], [[[[[WIron lich], [[[[[rMaster lich],
-[[[[[uMonastic lich], [[[[[UDemilich], [[[[[BArchlich], [[[[[DBlack reaver], and [[[[[sLesser]
-[[[[[sblack reaver] all deserve special mention.
-
-
- *** Wraiths (W) ***
-
-Wraiths are incorporeal beings frequently found in graveyards and
-at the sites of unavenged murders. There are [[[[[wWhite wraiths], [[[[[sGrey]
-[[[[[swraiths], [[[[[WSilver wraiths], [[[[[GNether wraiths], and [[[[[DBlack wraiths].
-The [[[[[UAdventurer wraiths] will try to help you. Fierce and magical
-are the many wights: [[[[[BBarrow wights], [[[[[gForest wights], [[[[[bGrave wights],
-[[[[[oSwamp wights], and [[[[[rEmperor wights]. The most dangerous among the
-wraith beings are the [[[[[uRevenant], [[[[[DNightwalker], [[[[[DNightcrawler], and
-[[[[[DNightwing]. \ No newline at end of file
diff --git a/lib/mods/theme/file/book-19.txt b/lib/mods/theme/file/book-19.txt
deleted file mode 100644
index a36285f0..00000000
--- a/lib/mods/theme/file/book-19.txt
+++ /dev/null
@@ -1,47 +0,0 @@
- -------------------------
- | Monstrous Compendium 11 |
- | Elemental creatures |
- -------------------------
-
- *** Vortices (v) ***
-
-These strange creatures are like localised tornadoes,
-carrying with them the various elements: [[[[[rfire], [[[[[benergy],
-[[[[[ggas], [[[[[wcold], [[[[[sacid], [[[[[ushards], [[[[[vnexus], [[[[[ymana], [[[[[Uconfusion],
-[[[[[Wslowness], [[[[[vchaos], [[[[[Gnether], [[[[[Rplasma], and [[[[[Btime]. Among
-these, the nastiest by far are the [[[[[vstorms of unmagic],
-as well as [[[[[oshimmering], [[[[[Ddeath], and [[[[[vaether] vortices.
-
- *** Spirits (E) ***
-
-These are the spirits contained in various elements, they
-are weaker than the proper elementals. There are [[[[[rFire]
-[[[[[rspirits], [[[[[bWater spirits], [[[[[uEarth spirits], and [[[[[BAir spirits]
-alongside [[[[[WWill'o the wisps] and [[[[[yInvisible stalkers].
-
- *** Elementals (E) ***
-
-Towering masses of raw elements, twisting and shaking all
-in their wake: [[[[[rfire], [[[[[bwater], [[[[[uearth], [[[[[Bair], [[[[[wice], [[[[[omagma],
-[[[[[Uconfusion], [[[[[Ddark], [[[[[Rsmoke], [[[[[gooze], [[[[[sslowness], [[[[[Gtime], and
-[[[[[vchaos].
-
- *** Hulking figures (X, Y) ***
-
-These are strange hulking shapes that puzzle anyone who
-comes across them. They include the [[[[[sXaren], the [[[[[uXorn],
-[[[[[UUmber hulk], [[[[[DDeath hulk], [[[[[wWhite hulk], [[[[[oOrange hulk], [[[[[rFire]
-[[[[[rhulk], [[[[[gForest hulk], [[[[[bNight hulk], [[[[[WSilver hulk], [[[[[vChaos hulk],
-[[[[[yYellow hulk], [[[[[RRed hulk], [[[[[GGreen hulk], and [[[[[Bblue hulk]. The
-[[[[[sSasquatch] and [[[[[wYeti] resemble humans, but they are still
-quite strange.
-
- *** Zephyr Hounds (Z) ***
-
-They are dog-like figures wreathed in the elements. They
-tend to move in packs, and are among the most vicious of
-all dungeon dwellers. The hounds may be: [[[[[Bclear], [[[[[rfire],
-[[[[[benergy], [[[[[gair], [[[[[wcold], [[[[[sacid], [[[[[vmulti-hued], [[[[[Ddark], [[[[[olight],
-[[[[[uearth], [[[[[Baquatic], [[[[[vnexus], [[[[[rwater], [[[[[Rplasma], [[[[[yvibration],
-[[[[[vchaos], [[[[[Gnether], [[[[[uimpact], [[[[[Winertia], [[[[[Ugravity], [[[[[Gethereal],
-[[[[[Btime], and [[[[[vaether]. \ No newline at end of file
diff --git a/lib/mods/theme/file/book-9.txt b/lib/mods/theme/file/book-9.txt
deleted file mode 100644
index 878d4b74..00000000
--- a/lib/mods/theme/file/book-9.txt
+++ /dev/null
@@ -1,99 +0,0 @@
- ------------------------
- | Monstrous Compendium 1 |
- | Humanoids |
- ------------------------
-
- *** Townsfolk (t) ***
-
-These are the monsters you will find in the various towns all across
-Middle-earth. Most of them are neutral to the player, though those who
-are not neutral are quite harmless, unless you take them on before you
-are strong enough. The townsfolk include [[[[[oAimless-looking merchants],
-[[[[[UPitiful-looking beggars], [[[[[ySinging, happy drunks], [[[[[uMangy-looking lepers],
-[[[[[GVillage idiots], [[[[[WBlubbering idiots], [[[[[RBoil-covered wretches], [[[[[gWoodsmen],
-[[[[[wSanctimonious-looking preachers], [[[[[vWeary-looking travellers],
-[[[[[DFilthy street urchins], [[[[[rMean-looking mercenaries],
-[[[[[bAgents of the black market], and [[[[[BBattle-scarred veterans].
-
- *** Humans (p) ***
-
-These are the various humans inhabiting Middle-earth, from all trades
-and professions, of varying degrees of experience. The novices and
-apprentices are just what their titles imply: new to the craft and thus
-easier to deal with than more advanced masters. Depending on the
-player's race, some of these may be neutral or even coaligned. The
-trades include [[[[[brogues], [[[[[uwarriors], [[[[[rmages], [[[[[omystics], [[[[[Rsorcerers], [[[[[Wrangers],
-[[[[[Gdruids], [[[[[wpaladins], [[[[[ymindcrafters], and [[[[[gpriests].
-
-These also include various subraces of humans from different parts of
-Middle-earth, including the moderately dangerous [[[[[Ueasterlings], [[[[[rVariags],
-[[[[[UCorsairs of Umbar], [[[[[uHaradrim], [[[[[sWainriders], and [[[[[gDunlendings], the very
-dangerous [[[[[DBlack Numenoreans] and [[[[[DOathbreakers], as well as the friendly
-(yet deadly when roused) [[[[[BWavelords].
-
-
- *** Elves and Halflings (h) ***
-
-The Halflings are a shy race, so there are not that many of them - only
-the [[[[[sScruffy-looking hobbits] and [[[[[UHalfling slingers]. Very stealthy and
-good shots, Halflings. They make excellent burglars.
-
-The [[[[[BMermaids] are an enigma, some argue that they are simply drowned
-Elven maidens, others say they're half-human, half-fish. Whatever they
-are, they are quite dangerous to the unwary adventurer. Another odd
-race are the [[[[[yMind flayers], whose mind powers are legendary and ability
-to deprive others of their sanity unmatched.
-
-The majority of Elven monsters an adventurer will encounter in the
-dungeons will be Dark Elves, all good at a particular profession, and
-much better at these professions than their human counterparts. There
-are simple [[[[[DDark elves] who live by their wits and a bit of magic, and
-then there are [[[[[vDark elven warlocks], [[[[[RDark elven sorcerers], [[[[[GDark elven]
-[[[[[Gdruids], [[[[[gDark elven priests], [[[[[uDark elven warriors], and [[[[[rDark elven]
-[[[[[rmages], all commanded by [[[[[DDark elven lords].
-
-Not all Elves you meet will be hostile and expert at the Dark arts,
-however, among them the [[[[[bAquatic elven warriors], [[[[[WElven archers],
-[[[[[wHigh-elven rangers], and [[[[[oAquatic elven mages].
-
- *** Dwarves (k) ***
-
-A hardy and stout race, the Dwarves make formidable opponents to any
-adventurer who encounters them. They, too, practice a variety of trades,
-though their spectrum is not as wide-ranging as that of humans or elves.
-The [[[[[DDark dwarven lords] rule over the [[[[[gDark dwarven priests], [[[[[uDark dwarven]
-[[[[[uwarriors], and [[[[[wDark dwarven smiths].
-
-The Dwarves do not trust magic, but a subrace of them - the Petty-dwarves
-- do practice it, you will see both plain [[[[[sPetty-dwarves] and [[[[[RPetty-dwarf]
-[[[[[Rmages].
-
-Some adventurers who know the correct incantation will be able to summon
-[[[[[Udwarven warriors] to their aid.
-
- *** Gnomes, leprawns, and their kin (l) ***
-
-The gnomes are a less-well-known race on Middle-earth; they are related
-to the Petty-dwarves, but they are not nearly as stout as Dwarves. The
-gnomes are quite cunning and smart, but not very strong. Their [[[[[sgnome lords]
-command the [[[[[ugnome warriors], [[[[[bgnome rogues], [[[[[rgnome priests], [[[[[Rgnome mages],
-[[[[[wgnome paladins], and [[[[[ognome mystics].
-
-A race closely related to gnomes are the leprawns - they are even smaller
-than gnomes, and much weaker. However, leprawns breed very quickly and an
-unwary adventurer might be overrun if he is not careful! The [[[[[vmalicious]
-[[[[[vleprawns] are a nuisance, the [[[[[Wwizard leprawns] are a dangerous nuisance,
-and one is not advised to underestimate the [[[[[Ddeath leprawns].
-
-There also exist [[[[[Gcheerful leprawns] and [[[[[Uadventurer gnomes], who have broken
-with the traditions of their races, and might agree to help other adventurers.
-
-A strange race from the depths are the [[[[[glizard men] with their [[[[[rlizard kings] -
-they are quite strong and command powerful magic. These creatures prefer to
-live in swamps and shallow water areas, however, so you will not encounter
-them in the dungeons often.
-
-
-
-
-
diff --git a/lib/mods/theme/help/debug.txt b/lib/mods/theme/help/debug.txt
index 8aea13ee..afe71920 100644
--- a/lib/mods/theme/help/debug.txt
+++ b/lib/mods/theme/help/debug.txt
@@ -17,13 +17,13 @@ will not be scored if you use debug commands.
*****debug.txt*5[c Create object] *****debug.txt*6[C Create artifact]
*****debug.txt*7[d Detect all] *****debug.txt*8[D Teleport to the wilderness]
*****debug.txt*9[e Edit character attributes] *****debug.txt*10[E Change grid's mana]
- *****debug.txt*11[f *IDENTIFY*] *****debug.txt*12[F Features]
+ f (unused) *****debug.txt*12[F Features]
*****debug.txt*13[g Create good item] G (unused)
*****debug.txt*15[h Change life rating] *****debug.txt*16[H Hostile monster creation]
- *****debug.txt*17[i Identify] I (unused)
+ i (unused) I (unused)
*****debug.txt*19[j Jump to other level] J (unused)
*****debug.txt*21[k Check attributes] K (unused)
- *****debug.txt*23[l Learn about objects] L (unused)
+ l (unused) L (unused)
*****debug.txt*25[m Magic Mapping] *****debug.txt*26[M Gain corruption]
*****debug.txt*27[n Summon named monster] *****debug.txt*28[N Summon _friendly_ named monster]
*****debug.txt*29[o Edit object attributes] O (unused)
@@ -118,9 +118,6 @@ maximal legal value.
Alter how much mana a grid has.
Use the "Command count", aka 0, to specify the amount of mana
that you want.
-~~~~~11
-[[[[[G*IDENTIFY* (f)]
- Like a Scroll of *Identify*.
~~~~~12
[[[[[GFeatures (F)]
Use the "Command count", aka 0, to specify a number from
@@ -135,9 +132,6 @@ maximal legal value.
~~~~~16
[[[[[GHostile monster creation (H)]
Summons a Pack of Creatures of the same kind.
-~~~~~17
-[[[[[GIdentify (i)]
- Like a Scroll of Identify.
~~~~~19
[[[[[GJump to other level (j)]
Jump to other dungeon level. This does not work in the
@@ -145,9 +139,6 @@ maximal legal value.
~~~~~21
[[[[[GCheck attributes (k)]
Displays your characters attributes.
-~~~~~23
-[[[[[GLearn about objects (l)]
- Make you know about all objects. Not sure how this works.
~~~~~25
[[[[[GMagic Mapping (m)]
Like a Scroll of Magic mapping.
diff --git a/lib/mods/theme/help/g_eru.txt b/lib/mods/theme/help/g_eru.txt
index 113875b3..f7e0406f 100644
--- a/lib/mods/theme/help/g_eru.txt
+++ b/lib/mods/theme/help/g_eru.txt
@@ -34,7 +34,7 @@ in asking for his help without offending him!
There is a special book called the "Holy Tome of Eru Iluvatar" which
contains instructions for the procedure for each of the prayers Eru will
-grant. There are four prayers all told, which are:
+grant. There are three prayers all told, which are:
1. [[[[[BSee the Music] (Level 1)
Allows you to 'see' the Great Music from which the world originates,
allowing you to see unseen things, and can be cast while blind.
@@ -46,11 +46,7 @@ grant. There are four prayers all told, which are:
allowing you to understand the meaning of things.
At spell level 14 it allows you to identify all your pack.
At spell level 30 it allows you to identify all items on the level.
-3. [[[[[BKnow the Music] (Level 30)
- Allows you to understand the Great Music from which the world originates,
- allowing you to know the full abilities of things.
- At spell level 10 it allows you to *identify* all your pack.
-4. [[[[[BLay of Protection] (Level 35)
+3. [[[[[BLay of Protection] (Level 35)
Creates a circle of safety around you.
Each of these spells can be increased in level both by improving your Prayer
diff --git a/lib/mods/theme/help/m_divin.txt b/lib/mods/theme/help/m_divin.txt
index e03bd334..ee7eec62 100644
--- a/lib/mods/theme/help/m_divin.txt
+++ b/lib/mods/theme/help/m_divin.txt
@@ -22,17 +22,8 @@ There are six spells available for the divination school. These Spells are:
2. [[[[[sSense Hidden] (school level 5)
Detects the traps in a certain radius around you.
At spell level 15 it allows you to sense invisible monsters for a while.
-3. [[[[[sIdentify] (school level 8)
- Asks for an object and identifies it.
- At spell level 17 it identifies all objects in the inventory.
- At spell level 27 it identifies all objects in the inventory and in a
- radius on the floor.
-4. [[[[[sReveal Ways] (school level 9)
+3. [[[[[sReveal Ways] (school level 9)
Detects the doors/stairs/ways in a certain radius around you.
-5. [[[[[sVision] (school level 15)
+4. [[[[[sVision] (school level 15)
Detects the layout of the surrounding area.
At spell level 25 it maps and lights the whole level.
-6. [[[[[sGreater Identify] (school level 35)
- Asks for an object and fully identifies it, providing the full list of
- powers (as with a scroll of *Identify*).
- Cast at yourself, it will reveal your powers (Self Knowledge).
diff --git a/lib/mods/theme/help/macrofaq.txt b/lib/mods/theme/help/macrofaq.txt
index d285194c..624f35f9 100644
--- a/lib/mods/theme/help/macrofaq.txt
+++ b/lib/mods/theme/help/macrofaq.txt
@@ -1788,13 +1788,7 @@ AND - logical AND
IOR - inclusive OR
EQU - (string) equals
NOT - logical negation
-LEQ - (string) less than or equal to
-GEQ - (string) greater than or equal to
[,] - group expressions
-$CLASS - current class
-$GRAF - 3-letter graphics abbr in "graf-***.prf" (old, new)
-$PLAYER - current player name
-$RACE - current race
$SYS - 3-letter system abbr in "pref-***.prf" (ami, mac, win,...)
0 - false
@@ -1805,10 +1799,10 @@ encountered until the next conditional pref line are skipped.
This isn't an actual command. It only works in pref files.
-The variables $CLASS, $GRAF, $PLAYER, $RACE, $PLAYER, $SYS and the
-string values they take on are case sensitive. The values also can't
-contain spaces. These constraints on the values hold when they are
-used in a pref file, but might not when used as pref filenames.
+The variable $SYS and the string value it may take on are case
+sensitive. The values also can't contain spaces. These constraints on
+the values hold when they are used in a pref file, but might not when
+used as pref filenames.
This can be "turned back on" using the pref line "?:1", which is
generally the last line in a file which contains conditional macros,
diff --git a/lib/mods/theme/help/wishing.txt b/lib/mods/theme/help/wishing.txt
index d16f5ae9..29fcab24 100644
--- a/lib/mods/theme/help/wishing.txt
+++ b/lib/mods/theme/help/wishing.txt
@@ -10,11 +10,12 @@ Due to the powerful nature of wishes, there are some rules that govern
what is able to be wished for. These rules are as follows:
1. You cannot wish for a wish, or any other item which would grant more
wishes.
-2. A wish will always generate *one* object. So, never put a number, "a"
+2. A wish will always generate *one* object. The name must be typed EXACTLY
+ as it would appear as an item (case insensitive). So, never put a number, "a"
or "an" in front of the object you are wishing for.
3. It is not possible to wish for the magical +'s to the object (i.e. you
- cannot wish for "gloves of slaying (+10,+10)", but you can wish for
- "gloves of slaying").
+ cannot wish for "set of leather gloves of slaying (+10,+10)", but you can wish for
+ "set of leather gloves of slaying").
4. You cannot wish for artifacts, but you *can* wish for excellent (ego)
items.
5. You can wish for monsters and ego monsters (e.g. "cave orc", "rogue cave
diff --git a/lib/mods/theme/pref/xtra-xxx.prf b/lib/mods/theme/pref/xtra-xxx.prf
deleted file mode 100644
index 0c6186de..00000000
--- a/lib/mods/theme/pref/xtra-xxx.prf
+++ /dev/null
@@ -1,137 +0,0 @@
-# File: xtra-xxx.prf
-
-#
-# This file defines special attr/char mappings for use in "graphics" mode
-#
-# See "lib/help/command.txt" and "src/files.c" for more information.
-#
-
-
-##### Remap the player icon #####
-
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Human] ]
-R:0:0x8C/0x80
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Half-Elf] ]
-R:0:0x8C/0x81
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Elf] ]
-R:0:0x8C/0x82
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Hobbit] ]
-R:0:0x8C/0x83
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Gnome] ]
-R:0:0x8C/0x84
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Dwarf] ]
-R:0:0x8C/0x85
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Half-Orc] ]
-R:0:0x8C/0x86
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Half-Troll] ]
-R:0:0x8C/0x87
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Dunadan] ]
-R:0:0x8C/0x88
-?:[AND [EQU $CLASS Warrior] [EQU $RACE High-Elf] ]
-R:0:0x8C/0x89
-
-?:[AND [EQU $CLASS Mage] [EQU $RACE Human] ]
-R:0:0x8C/0x8A
-?:[AND [EQU $CLASS Mage] [EQU $RACE Half-Elf] ]
-R:0:0x8C/0x8B
-?:[AND [EQU $CLASS Mage] [EQU $RACE Elf] ]
-R:0:0x8C/0x8C
-?:[AND [EQU $CLASS Mage] [EQU $RACE Hobbit] ]
-R:0:0x8C/0x8D
-?:[AND [EQU $CLASS Mage] [EQU $RACE Gnome] ]
-R:0:0x8C/0x8E
-?:[AND [EQU $CLASS Mage] [EQU $RACE Dwarf] ]
-R:0:0x8C/0x8F
-?:[AND [EQU $CLASS Mage] [EQU $RACE Half-Orc] ]
-R:0:0x8C/0x90
-?:[AND [EQU $CLASS Mage] [EQU $RACE Half-Troll] ]
-R:0:0x8C/0x91
-?:[AND [EQU $CLASS Mage] [EQU $RACE Dunadan] ]
-R:0:0x8C/0x92
-?:[AND [EQU $CLASS Mage] [EQU $RACE High-Elf] ]
-R:0:0x8C/0x93
-
-?:[AND [EQU $CLASS Priest] [EQU $RACE Human] ]
-R:0:0x8C/0x94
-?:[AND [EQU $CLASS Priest] [EQU $RACE Half-Elf] ]
-R:0:0x8C/0x95
-?:[AND [EQU $CLASS Priest] [EQU $RACE Elf] ]
-R:0:0x8C/0x96
-?:[AND [EQU $CLASS Priest] [EQU $RACE Hobbit] ]
-R:0:0x8C/0x97
-?:[AND [EQU $CLASS Priest] [EQU $RACE Gnome] ]
-R:0:0x8C/0x98
-?:[AND [EQU $CLASS Priest] [EQU $RACE Dwarf] ]
-R:0:0x8C/0x99
-?:[AND [EQU $CLASS Priest] [EQU $RACE Half-Orc] ]
-R:0:0x8C/0x9A
-?:[AND [EQU $CLASS Priest] [EQU $RACE Half-Troll] ]
-R:0:0x8C/0x9B
-?:[AND [EQU $CLASS Priest] [EQU $RACE Dunadan] ]
-R:0:0x8C/0x9C
-?:[AND [EQU $CLASS Priest] [EQU $RACE High-Elf] ]
-R:0:0x8C/0x9D
-
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Human] ]
-R:0:0x8C/0x9E
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Half-Elf] ]
-R:0:0x8C/0x9F
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Elf] ]
-R:0:0x8D/0x80
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Hobbit] ]
-R:0:0x8D/0x81
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Gnome] ]
-R:0:0x8D/0x82
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Dwarf] ]
-R:0:0x8D/0x83
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Half-Orc] ]
-R:0:0x8D/0x84
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Half-Troll] ]
-R:0:0x8D/0x85
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Dunadan] ]
-R:0:0x8D/0x86
-?:[AND [EQU $CLASS Rogue] [EQU $RACE High-Elf] ]
-R:0:0x8D/0x87
-
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Human] ]
-R:0:0x8D/0x88
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Half-Elf] ]
-R:0:0x8D/0x89
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Elf] ]
-R:0:0x8D/0x8A
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Hobbit] ]
-R:0:0x8D/0x8B
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Gnome] ]
-R:0:0x8D/0x8C
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Dwarf] ]
-R:0:0x8D/0x8D
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Half-Orc] ]
-R:0:0x8D/0x8E
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Half-Troll] ]
-R:0:0x8D/0x8F
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Dunadan] ]
-R:0:0x8D/0x90
-?:[AND [EQU $CLASS Ranger] [EQU $RACE High-Elf] ]
-R:0:0x8D/0x91
-
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Human] ]
-R:0:0x8D/0x92
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Half-Elf] ]
-R:0:0x8D/0x93
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Elf] ]
-R:0:0x8D/0x94
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Hobbit] ]
-R:0:0x8D/0x95
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Gnome] ]
-R:0:0x8D/0x96
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Dwarf] ]
-R:0:0x8D/0x97
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Half-Orc] ]
-R:0:0x8D/0x98
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Half-Troll] ]
-R:0:0x8D/0x99
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Dunadan] ]
-R:0:0x8D/0x9A
-?:[AND [EQU $CLASS Paladin] [EQU $RACE High-Elf] ]
-R:0:0x8D/0x9B
-
diff --git a/lib/pref/pref.prf b/lib/pref/pref.prf
index 310e5b8a..e41fb85e 100644
--- a/lib/pref/pref.prf
+++ b/lib/pref/pref.prf
@@ -246,6 +246,10 @@ C:1:)
A:$
C:1:S
+# Destroy floor item
+A:k--
+C:0:X
+
### Extended macros ###
diff --git a/lib/pref/xtra-xxx.prf b/lib/pref/xtra-xxx.prf
deleted file mode 100644
index 0c6186de..00000000
--- a/lib/pref/xtra-xxx.prf
+++ /dev/null
@@ -1,137 +0,0 @@
-# File: xtra-xxx.prf
-
-#
-# This file defines special attr/char mappings for use in "graphics" mode
-#
-# See "lib/help/command.txt" and "src/files.c" for more information.
-#
-
-
-##### Remap the player icon #####
-
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Human] ]
-R:0:0x8C/0x80
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Half-Elf] ]
-R:0:0x8C/0x81
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Elf] ]
-R:0:0x8C/0x82
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Hobbit] ]
-R:0:0x8C/0x83
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Gnome] ]
-R:0:0x8C/0x84
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Dwarf] ]
-R:0:0x8C/0x85
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Half-Orc] ]
-R:0:0x8C/0x86
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Half-Troll] ]
-R:0:0x8C/0x87
-?:[AND [EQU $CLASS Warrior] [EQU $RACE Dunadan] ]
-R:0:0x8C/0x88
-?:[AND [EQU $CLASS Warrior] [EQU $RACE High-Elf] ]
-R:0:0x8C/0x89
-
-?:[AND [EQU $CLASS Mage] [EQU $RACE Human] ]
-R:0:0x8C/0x8A
-?:[AND [EQU $CLASS Mage] [EQU $RACE Half-Elf] ]
-R:0:0x8C/0x8B
-?:[AND [EQU $CLASS Mage] [EQU $RACE Elf] ]
-R:0:0x8C/0x8C
-?:[AND [EQU $CLASS Mage] [EQU $RACE Hobbit] ]
-R:0:0x8C/0x8D
-?:[AND [EQU $CLASS Mage] [EQU $RACE Gnome] ]
-R:0:0x8C/0x8E
-?:[AND [EQU $CLASS Mage] [EQU $RACE Dwarf] ]
-R:0:0x8C/0x8F
-?:[AND [EQU $CLASS Mage] [EQU $RACE Half-Orc] ]
-R:0:0x8C/0x90
-?:[AND [EQU $CLASS Mage] [EQU $RACE Half-Troll] ]
-R:0:0x8C/0x91
-?:[AND [EQU $CLASS Mage] [EQU $RACE Dunadan] ]
-R:0:0x8C/0x92
-?:[AND [EQU $CLASS Mage] [EQU $RACE High-Elf] ]
-R:0:0x8C/0x93
-
-?:[AND [EQU $CLASS Priest] [EQU $RACE Human] ]
-R:0:0x8C/0x94
-?:[AND [EQU $CLASS Priest] [EQU $RACE Half-Elf] ]
-R:0:0x8C/0x95
-?:[AND [EQU $CLASS Priest] [EQU $RACE Elf] ]
-R:0:0x8C/0x96
-?:[AND [EQU $CLASS Priest] [EQU $RACE Hobbit] ]
-R:0:0x8C/0x97
-?:[AND [EQU $CLASS Priest] [EQU $RACE Gnome] ]
-R:0:0x8C/0x98
-?:[AND [EQU $CLASS Priest] [EQU $RACE Dwarf] ]
-R:0:0x8C/0x99
-?:[AND [EQU $CLASS Priest] [EQU $RACE Half-Orc] ]
-R:0:0x8C/0x9A
-?:[AND [EQU $CLASS Priest] [EQU $RACE Half-Troll] ]
-R:0:0x8C/0x9B
-?:[AND [EQU $CLASS Priest] [EQU $RACE Dunadan] ]
-R:0:0x8C/0x9C
-?:[AND [EQU $CLASS Priest] [EQU $RACE High-Elf] ]
-R:0:0x8C/0x9D
-
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Human] ]
-R:0:0x8C/0x9E
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Half-Elf] ]
-R:0:0x8C/0x9F
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Elf] ]
-R:0:0x8D/0x80
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Hobbit] ]
-R:0:0x8D/0x81
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Gnome] ]
-R:0:0x8D/0x82
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Dwarf] ]
-R:0:0x8D/0x83
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Half-Orc] ]
-R:0:0x8D/0x84
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Half-Troll] ]
-R:0:0x8D/0x85
-?:[AND [EQU $CLASS Rogue] [EQU $RACE Dunadan] ]
-R:0:0x8D/0x86
-?:[AND [EQU $CLASS Rogue] [EQU $RACE High-Elf] ]
-R:0:0x8D/0x87
-
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Human] ]
-R:0:0x8D/0x88
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Half-Elf] ]
-R:0:0x8D/0x89
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Elf] ]
-R:0:0x8D/0x8A
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Hobbit] ]
-R:0:0x8D/0x8B
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Gnome] ]
-R:0:0x8D/0x8C
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Dwarf] ]
-R:0:0x8D/0x8D
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Half-Orc] ]
-R:0:0x8D/0x8E
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Half-Troll] ]
-R:0:0x8D/0x8F
-?:[AND [EQU $CLASS Ranger] [EQU $RACE Dunadan] ]
-R:0:0x8D/0x90
-?:[AND [EQU $CLASS Ranger] [EQU $RACE High-Elf] ]
-R:0:0x8D/0x91
-
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Human] ]
-R:0:0x8D/0x92
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Half-Elf] ]
-R:0:0x8D/0x93
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Elf] ]
-R:0:0x8D/0x94
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Hobbit] ]
-R:0:0x8D/0x95
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Gnome] ]
-R:0:0x8D/0x96
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Dwarf] ]
-R:0:0x8D/0x97
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Half-Orc] ]
-R:0:0x8D/0x98
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Half-Troll] ]
-R:0:0x8D/0x99
-?:[AND [EQU $CLASS Paladin] [EQU $RACE Dunadan] ]
-R:0:0x8D/0x9A
-?:[AND [EQU $CLASS Paladin] [EQU $RACE High-Elf] ]
-R:0:0x8D/0x9B
-
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 30ceb76c..6c9ca9d6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,9 +1,10 @@
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../vendor/bandit)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../vendor/fmt)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../vendor/pcg-cpp/include)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../vendor/jsoncons)
+INCLUDE_DIRECTORIES(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/../vendor/bandit)
+INCLUDE_DIRECTORIES(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/../vendor/fmt)
+INCLUDE_DIRECTORIES(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/../vendor/pcg-cpp/include)
+INCLUDE_DIRECTORIES(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/../vendor/jsoncons)
+INCLUDE_DIRECTORIES(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/../vendor/CppQuickCheck/include)
# Add subdirectories
ADD_SUBDIRECTORY (squelch)
@@ -25,7 +26,10 @@ SET(SRCS_COMMON
dice.cc
dungeon.cc
files.cc
+ frontend.cc
+ format_ext.cc
game.cc
+ game_edit_data.cc
gen_evol.cc
gen_maze.cc
generate.cc
@@ -36,6 +40,8 @@ SET(SRCS_COMMON
init1.cc
init2.cc
joke.cc
+ key_queue.cc
+ level_data.cc
level_marker.cc
levels.cc
loadsave.cc
@@ -59,6 +65,7 @@ SET(SRCS_COMMON
options.cc
player_type.cc
powers.cc
+ program_args.cc
q_betwen.cc
q_bounty.cc
q_dragons.cc
@@ -108,14 +115,18 @@ SET(SRCS_COMMON
seed.cc
xtra1.cc
xtra2.cc
- z-form.c
+ z-form.cc
z-rand.cc
- z-term.c
- z-util.c
+ z-term.cc
+ z-util.cc
)
# Sources (TEST)
SET(SRCS_TESTS
+ # CppQuickCheck
+ ${CMAKE_CURRENT_SOURCE_DIR}/../vendor/CppQuickCheck/src/Arbitrary.cpp
+ # Own code
+ ../tests/arbitrary/boost_optional.cc
../tests/get_level_device.cc
../tests/harness.cc
../tests/lua_get_level.cc
@@ -132,7 +143,6 @@ ADD_LIBRARY(game_main
# Need a few additional source files for Windows.
IF(WIN32)
- SET(SRCS ${SRCS} main-win.c)
# Resource files require a little workaround.
IF(MINGW)
# Workaround for resource compilation for mingw on CMake.
@@ -146,7 +156,7 @@ IF(WIN32)
SET(SRCS ${SRCS} angband.rc)
ENDIF(MINGW)
# Executable for Win32
- ADD_EXECUTABLE(tome-win WIN32 main-win.c)
+ ADD_EXECUTABLE(tome-win WIN32 main-win.cc)
TARGET_LINK_LIBRARIES(tome-win game squelch ${LIBS} winmm wsock32)
INSTALL(TARGETS tome-win RUNTIME DESTINATION bin)
ENDIF(WIN32)
@@ -154,28 +164,21 @@ ENDIF(WIN32)
# tome executables
IF(X11_FOUND)
INCLUDE_DIRECTORIES(${X11_INCLUDE_DIR})
- ADD_EXECUTABLE(tome-x11 main-x11.c)
+ ADD_EXECUTABLE(tome-x11 main-x11.cc)
TARGET_LINK_LIBRARIES(tome-x11 game_main game squelch ${LIBS} ${X11_LIBRARIES})
INSTALL(TARGETS tome-x11 RUNTIME DESTINATION bin)
ENDIF()
-IF(SDL_FOUND AND SDLIMAGE_FOUND AND SDLTTF_FOUND)
- INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIR} ${SDLIMAGE_INCLUDE_DIR} ${SDLTTF_INCLUDE_DIR})
- ADD_EXECUTABLE(tome-sdl main-sdl.c)
- TARGET_LINK_LIBRARIES(tome-sdl game_main game squelch ${LIBS} ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} ${SDL_LIBRARY} m)
- INSTALL(TARGETS tome-sdl RUNTIME DESTINATION bin)
-ENDIF()
-
IF(CURSES_FOUND)
INCLUDE_DIRECTORIES(${CURSES_INCLUDE_DIR})
- ADD_EXECUTABLE(tome-gcu main-gcu.c)
+ ADD_EXECUTABLE(tome-gcu main-gcu.cc)
TARGET_LINK_LIBRARIES(tome-gcu game_main game squelch ${LIBS} ${CURSES_LIBRARIES})
INSTALL(TARGETS tome-gcu RUNTIME DESTINATION bin)
ENDIF()
IF(GTK2_FOUND)
INCLUDE_DIRECTORIES(${GTK2_INCLUDE_DIRS})
- ADD_EXECUTABLE(tome-gtk2 main-gtk2.c)
+ ADD_EXECUTABLE(tome-gtk2 main-gtk2.cc)
TARGET_LINK_LIBRARIES(tome-gtk2 game_main game squelch ${LIBS} ${GTK2_LIBRARIES})
INSTALL(TARGETS tome-gtk2 RUNTIME DESTINATION bin)
ENDIF()
diff --git a/src/ability_type.hpp b/src/ability_type.hpp
index 0ec596ba..61e6bc2c 100644
--- a/src/ability_type.hpp
+++ b/src/ability_type.hpp
@@ -3,7 +3,7 @@
#include <string>
#include <vector>
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* Abilities.
diff --git a/src/activation.hpp b/src/activation.hpp
index adb9d8bc..aec359a8 100644
--- a/src/activation.hpp
+++ b/src/activation.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* Activation descriptor.
diff --git a/src/alloc.hpp b/src/alloc.hpp
index 1d4ce815..1b0ede47 100644
--- a/src/alloc.hpp
+++ b/src/alloc.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "alloc_entry.hpp"
#include <vector>
diff --git a/src/alloc_entry.hpp b/src/alloc_entry.hpp
index 5e0e547f..fd24597e 100644
--- a/src/alloc_entry.hpp
+++ b/src/alloc_entry.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* An entry for the object/monster allocation functions
diff --git a/src/angband.h b/src/angband.h
deleted file mode 100644
index 5fbc94e5..00000000
--- a/src/angband.h
+++ /dev/null
@@ -1,94 +0,0 @@
-#pragma once
-
-/*
- * Copyright (c) 1989 James E. Wilson
- *
- * This software may be copied and distributed for educational, research, and
- * not for profit purposes provided that this copyright and statement are
- * included in all such copies.
- */
-
-/*
- * C++ guard.
- */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * First, include the low-level includes. Be sure to edit "h-config.h"
- * to reflect any hardware, operating system, or compiler nuances.
- */
-#include "h-basic.h"
-
-
-/*
- * Then, include the header files for the low-level code
- */
-#include "z-util.h"
-#include "z-form.h"
-#include "z-term.h"
-
-
-/*
- * Include the "Angband" configuration header
- */
-#include "config.h"
-
-
-/*
- * Now, include the defines and the types
- */
-#include "defines.h"
-
-/***** Some copyright messages follow below *****/
-
-/*
- * Note that these copyright messages apply to an ancient version
- * of Angband, as in, from pre-2.4.frog-knows days, and thus the
- * reference to "5.0" is rather misleading...
- */
-
-/*
- * UNIX ANGBAND Version 5.0
- */
-
-
-/* Original copyright message follows. */
-
-/*
- * ANGBAND Version 4.8 COPYRIGHT (c) Robert Alan Koeneke
- *
- * I lovingly dedicate this game to hackers and adventurers
- * everywhere...
- *
- * Designer and Programmer:
- * Robert Alan Koeneke
- * University of Oklahoma
- *
- * Assistant Programmer:
- * Jimmey Wayne Todd
- * University of Oklahoma
- *
- * Assistant Programmer:
- * Gary D. McAdoo
- * University of Oklahoma
- *
- * UNIX Port:
- * James E. Wilson
- * UC Berkeley
- * wilson@ernie.Berkeley.EDU
- * ucbvax!ucbernie!wilson
- */
-
-
-/*
- * ANGBAND may be copied and modified freely as long as the above
- * credits are retained. No one who-so-ever may sell or market
- * this software in any form without the expressed written consent
- * of the author Robert Alan Koeneke.
- */
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
diff --git a/src/artifact_type.hpp b/src/artifact_type.hpp
index 9f866aa7..df5d30c1 100644
--- a/src/artifact_type.hpp
+++ b/src/artifact_type.hpp
@@ -1,8 +1,10 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_flag_set.hpp"
+#include <boost/optional.hpp>
+
/**
* Artifact descriptor.
*
@@ -43,7 +45,7 @@ struct artifact_type
byte cur_num = 0; /* Number created (0 or 1) */
- s16b power = 0; /* Power granted, if any */
+ boost::optional<int> power; /* Power granted, if any */
s16b set = 0; /* Which set does it belong it, if any? */
diff --git a/src/between_exit.hpp b/src/between_exit.hpp
index 7ea686d7..45c5ad3a 100644
--- a/src/between_exit.hpp
+++ b/src/between_exit.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* Surface-level void gates descriptor.
@@ -8,9 +8,9 @@
struct between_exit
{
s16b corresp; /* Corresponding between gate */
- bool_ dungeon; /* Do we exit in a dungeon or in the wild ? */
- s16b wild_x, wild_y; /* Wilderness spot to land onto */
+ s16b wild_x; /* Wilderness spot to land onto */
+ s16b wild_y; /* Wilderness spot to land onto */
s16b px, py; /* Location of the map */
s16b d_idx; /* Dungeon to land onto */
diff --git a/src/birth.cc b/src/birth.cc
index f677e6e1..c29f7eed 100644
--- a/src/birth.cc
+++ b/src/birth.cc
@@ -14,7 +14,6 @@
#include "cmd5.hpp"
#include "dungeon_flag.hpp"
#include "dungeon_info_type.hpp"
-#include "files.h"
#include "files.hpp"
#include "game.hpp"
#include "gods.hpp"
@@ -48,20 +47,24 @@
#include "tables.hpp"
#include "town_type.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "wilderness_map.hpp"
#include "xtra1.hpp"
#include "xtra2.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
+#include "z-util.hpp"
#include <algorithm>
+#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem.hpp>
+#include <fcntl.h>
#include <fmt/format.h>
#include <numeric>
#include <string>
+using boost::algorithm::equals;
+
/*
* How often the autoroller will update the display and pause
* to check for user interuptions.
@@ -149,7 +152,7 @@ static std::string create_random_name()
}
-void print_desc_aux(cptr txt, int y, int xx)
+void print_desc_aux(const char *txt, int y, int xx)
{
int i = -1, x = xx;
@@ -168,7 +171,7 @@ void print_desc_aux(cptr txt, int y, int xx)
}
}
-void print_desc(cptr txt)
+void print_desc(const char *txt)
{
print_desc_aux(txt, 12, 1);
}
@@ -207,7 +210,7 @@ static void save_prev_data()
/*
* Load the previous data
*/
-static void load_prev_data(bool_ save)
+static void load_prev_data(bool save)
{
auto &previous_char = game->previous_char;
birther temp;
@@ -265,7 +268,7 @@ static void load_prev_data(bool_ save)
*
* The "p_ptr->maximize" code is important -BEN-
*/
-static int adjust_stat(int value, int amount, int auto_roll)
+static int adjust_stat(int value, int amount)
{
int i;
@@ -330,7 +333,7 @@ static void get_stats()
/* Roll and verify some stats */
- while (TRUE)
+ while (true)
{
/* Roll some dice */
for (j = i = 0; i < 18; i++)
@@ -484,7 +487,7 @@ static errr init_randart()
ra.name_full = get_line("rart_f.txt", ANGBAND_DIR_FILE, buf, i);
ra.attr = randint(15);
ra.activation = rand_int(MAX_T_ACT);
- ra.generated = FALSE;
+ ra.generated = false;
ra.cost = cost;
// Push
@@ -630,16 +633,11 @@ static void player_wipe()
}
/* Reset the "objects" */
- for (auto &k_ref: k_info)
+ for (auto &k_entry: k_info)
{
- /* Reset "tried" */
- k_ref.tried = FALSE;
-
- /* Reset "aware" */
- k_ref.aware = FALSE;
-
- /* Reset "artifact" */
- k_ref.artifact = 0;
+ auto k_ptr = k_entry.second;
+ k_ptr->aware = false;
+ k_ptr->artifact = false;
}
@@ -661,7 +659,7 @@ static void player_wipe()
r_ptr->r_pkills = 0;
/* Clear saved flag */
- r_ptr->on_saved = FALSE;
+ r_ptr->on_saved = false;
}
@@ -673,30 +671,30 @@ static void player_wipe()
/* Assume no winning game */
total_winner = 0;
- has_won = FALSE;
+ has_won = false;
/* Assume no cheating */
noscore = 0;
- wizard = 0;
+ wizard = false;
/* Clear the fate */
for (std::size_t i = 0; i < MAX_FATES; i++)
{
fates[i].fate = 0;
}
- p_ptr->no_mortal = FALSE;
+ p_ptr->no_mortal = false;
/* Player don't have the black breath from the beginning !*/
- p_ptr->black_breath = FALSE;
+ p_ptr->black_breath = false;
/* Default pet command settings */
p_ptr->pet_follow_distance = 6;
- p_ptr->pet_open_doors = FALSE;
- p_ptr->pet_pickup_items = FALSE;
+ p_ptr->pet_open_doors = false;
+ p_ptr->pet_pickup_items = false;
/* Body changing initialisation */
p_ptr->body_monster = 0;
- p_ptr->disembodied = FALSE;
+ p_ptr->disembodied = false;
/* Wipe xtra hp */
p_ptr->hp_mod = 0;
@@ -719,18 +717,15 @@ static void player_wipe()
inscription_known = false;
}
- /* Reset wild_mode to FALSE */
- p_ptr->wild_mode = FALSE;
- p_ptr->old_wild_mode = FALSE;
+ /* Reset wild_mode to false */
+ p_ptr->wild_mode = false;
+ p_ptr->old_wild_mode = false;
/* Initialize allow_one_death */
p_ptr->allow_one_death = 0;
/* Wipe the power list */
- for (std::size_t i = 0; i < POWER_MAX; i++)
- {
- p_ptr->powers_mod[i] = 0;
- }
+ p_ptr->powers_mod.clear();
/* No companions killed */
p_ptr->companion_killed = 0;
@@ -762,12 +757,9 @@ static void outfit_obj(object_proto const *proto)
}
/* These objects are "storebought" */
- q_ptr->ident |= IDENT_MENTAL;
q_ptr->number = damroll(proto->dd, proto->ds);
- object_aware(q_ptr);
- object_known(q_ptr);
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
}
@@ -789,23 +781,27 @@ static void player_outfit_object(int qty, int tval, int sval)
object_type *q_ptr = &forge;
object_prep(q_ptr, lookup_kind(tval, sval));
q_ptr->number = qty;
- object_aware(q_ptr);
- object_known(q_ptr);
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
}
/*
* Give player a spell book.
*/
-static void player_outfit_spellbook(cptr spell_name)
+static void player_outfit_spellbook(const char *spell_name)
{
- object_type forge;
- object_type *q_ptr = &forge;
- object_prep(q_ptr, lookup_kind(TV_BOOK, 255));
- q_ptr->pval = find_spell(spell_name);
- q_ptr->ident |= IDENT_MENTAL | IDENT_KNOWN;
- inven_carry(q_ptr, FALSE);
+ if (auto spell_idx = find_spell(spell_name))
+ {
+ object_type forge;
+ object_type *q_ptr = &forge;
+ object_prep(q_ptr, lookup_kind(TV_BOOK, 255));
+ q_ptr->pval = *spell_idx;
+ inven_carry(q_ptr, false);
+ }
+ else
+ {
+ quit_fmt("Couldn't find spell '%s'\n");
+ }
}
@@ -817,7 +813,7 @@ static void player_outfit_spellbook(cptr spell_name)
static void player_outfit()
{
// Shorthand names for convenience
- cptr class_name = spp_ptr->title;
+ const char *class_name = spp_ptr->title;
auto const &subrace_name = rmp_ptr->title;
/*
@@ -834,51 +830,51 @@ static void player_outfit()
*/
if (game_module_idx == MODULE_TOME)
{
- if (streq(class_name, "Ranger"))
+ if (equals(class_name, "Ranger"))
{
player_outfit_spellbook("Phase Door");
}
}
- if (streq(class_name, "Geomancer"))
+ if (equals(class_name, "Geomancer"))
{
player_outfit_spellbook("Geyser");
}
- if (streq(class_name, "Priest(Eru)"))
+ if (equals(class_name, "Priest(Eru)"))
{
player_outfit_spellbook("See the Music");
}
- if (streq(class_name, "Priest(Manwe)"))
+ if (equals(class_name, "Priest(Manwe)"))
{
player_outfit_spellbook("Manwe's Blessing");
}
- if (streq(class_name, "Druid"))
+ if (equals(class_name, "Druid"))
{
player_outfit_spellbook("Charm Animal");
}
- if (streq(class_name, "Dark-Priest"))
+ if (equals(class_name, "Dark-Priest"))
{
player_outfit_spellbook("Curse");
}
- if (streq(class_name, "Paladin"))
+ if (equals(class_name, "Paladin"))
{
player_outfit_spellbook("Divine Aim");
}
if (game_module_idx == MODULE_THEME)
{
/* Priests */
- if (streq(class_name, "Stonewright"))
+ if (equals(class_name, "Stonewright"))
{
player_outfit_spellbook("Firebrand");
}
- if (streq(class_name, "Priest(Varda)"))
+ if (equals(class_name, "Priest(Varda)"))
{
player_outfit_spellbook("Light of Valinor");
}
- if (streq(class_name, "Priest(Ulmo)"))
+ if (equals(class_name, "Priest(Ulmo)"))
{
player_outfit_spellbook("Song of Belegaer");
}
- if (streq(class_name, "Priest(Mandos)"))
+ if (equals(class_name, "Priest(Mandos)"))
{
player_outfit_spellbook("Tears of Luthien");
}
@@ -920,36 +916,32 @@ static void player_outfit()
}
/* Peace-mages */
- if (streq(class_name, "Peace-mage"))
+ if (equals(class_name, "Peace-mage"))
{
player_outfit_spellbook("Phase Door");
}
/* Wainriders */
- if (streq(class_name, "Wainrider"))
+ if (equals(class_name, "Wainrider"))
{
player_outfit_spellbook("Curse");
}
}
- if (streq(class_name, "Mimic"))
+ if (equals(class_name, "Mimic"))
{
object_type forge;
object_type *q_ptr = &forge;
object_prep(q_ptr, lookup_kind(TV_CLOAK, SV_MIMIC_CLOAK));
q_ptr->pval2 = resolve_mimic_name("Mouse");
- q_ptr->ident |= IDENT_MENTAL | IDENT_KNOWN;
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
}
if (game_module_idx == MODULE_THEME)
{
/* Give everyone a scroll of WoR. */
player_outfit_object(1, TV_SCROLL, SV_SCROLL_WORD_OF_RECALL);
-
- /* Identify everything in pack. */
- identify_pack_fully();
}
if (rmp_ptr->title == "Vampire")
@@ -975,9 +967,7 @@ static void player_outfit()
object_prep(q_ptr, lookup_kind(TV_LITE, SV_LITE_TORCH));
q_ptr->number = (byte)rand_range(3, 7);
q_ptr->timeout = rand_range(3, 7) * 500;
- object_aware(q_ptr);
- object_known(q_ptr);
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
}
/* Outfit the player with starting items */
@@ -1001,7 +991,7 @@ static void dump_classes(std::vector<u16b> const &classes, int sel, u32b *restri
for (int n = 0; n < n_max; n++)
{
- cptr mod = "";
+ const char *mod = "";
char p2 = ')', p1 = ' ';
/* Analyze */
@@ -1240,7 +1230,7 @@ static int dump_gods(int sel, int *choice, int max)
{
int i, j;
char buf[80];
- cptr str;
+ const char *str;
/* Clean up */
clear_from(12);
@@ -1277,10 +1267,17 @@ static int dump_gods(int sel, int *choice, int max)
{
/* Display the first four lines of the god description */
for (j = 0; j < 4; j++)
- if (strcmp(g_ptr->desc[j], ""))
+ {
+ if (!equals(g_ptr->desc[j], ""))
+ {
print_desc_aux(g_ptr->desc[j], 12 + j, 1);
+ }
+ }
+ }
+ else
+ {
+ print_desc("You can begin as an atheist and still convert to a god later.");
}
- else print_desc("You can begin as an atheist and still convert to a god later.");
c_put_str(TERM_L_BLUE, buf, 20 + (i / 4), 1 + 20 * (i % 4));
}
@@ -1293,11 +1290,9 @@ static int dump_gods(int sel, int *choice, int max)
return (max);
}
+static bool do_quick_start = false;
-/* Ask questions */
-static bool_ do_quick_start = FALSE;
-
-static bool_ player_birth_aux_ask()
+static bool player_birth_aux_ask()
{
auto &class_info = game->edit_data.class_info;
auto const &race_info = game->edit_data.race_info;
@@ -1350,20 +1345,20 @@ static bool_ player_birth_aux_ask()
if (game->previous_char.quick_ok)
{
/* Choose */
- while (1)
+ while (true)
{
put_str("Use same character as last time (y/n)? ", 20, 2);
c = inkey();
if (c == 'Q') quit(NULL);
- else if (c == 'S') return (FALSE);
+ else if (c == 'S') return false;
else if ((c == 'y') || (c == 'Y'))
{
- do_quick_start = TRUE;
+ do_quick_start = true;
break;
}
else
{
- do_quick_start = FALSE;
+ do_quick_start = false;
break;
}
}
@@ -1399,7 +1394,7 @@ static bool_ player_birth_aux_ask()
n = dump_races(sel);
/* Choose */
- while (1)
+ while (true)
{
strnfmt(buf, 200, "Choose a race (%c-%c), * for a random choice, = for options, 8/2/4/6 for movement: ",
I2A(0), I2A(race_info.size() - 1));
@@ -1407,7 +1402,7 @@ static bool_ player_birth_aux_ask()
c = inkey();
if (c == 'Q') quit(NULL);
- if (c == 'S') return (FALSE);
+ if (c == 'S') return false;
if (c == '*')
{
k = rand_int(race_info.size());
@@ -1422,7 +1417,7 @@ static bool_ player_birth_aux_ask()
else if (c == '=')
{
screen_save();
- do_cmd_options_aux(6, "Startup Options", FALSE);
+ do_cmd_options_aux(6, "Startup Options", false);
screen_load();
}
else if (c == '2')
@@ -1528,14 +1523,14 @@ static bool_ player_birth_aux_ask()
n = dump_rmods(sel, racem, max_racem);
/* Choose */
- while (1)
+ while (true)
{
strnfmt(buf, 200, "Choose a race modifier (%c-%c), * for a random choice, = for options: ",
I2A(0), I2A(max_racem - 1));
put_str(buf, 17, 2);
c = inkey();
if (c == 'Q') quit(NULL);
- if (c == 'S') return (FALSE);
+ if (c == 'S') return false;
if (c == '*')
{
// Which choices are legal?
@@ -1565,7 +1560,7 @@ static bool_ player_birth_aux_ask()
else if (c == '=')
{
screen_save();
- do_cmd_options_aux(6, "Startup Options", FALSE);
+ do_cmd_options_aux(6, "Startup Options", false);
screen_load();
}
else if (c == '2')
@@ -1663,13 +1658,13 @@ static bool_ player_birth_aux_ask()
dump_classes(class_types, sel, restrictions);
/* Get a class */
- while (1)
+ while (true)
{
strnfmt(buf, 200, "Choose a class (%c-%c), * for random, = for options, 8/2/4 for up/down/back: ", I2A(0), (n <= 25) ? I2A(n - 1) : I2D(n - 26-1));
put_str(buf, 15, 2);
c = inkey();
if (c == 'Q') quit(NULL);
- if (c == 'S') return (FALSE);
+ if (c == 'S') return false;
if (c == '*')
{
k = randint(n) - 1;
@@ -1684,7 +1679,7 @@ static bool_ player_birth_aux_ask()
else if (c == '=')
{
screen_save();
- do_cmd_options_aux(6, "Startup Options", FALSE);
+ do_cmd_options_aux(6, "Startup Options", false);
screen_load();
}
else if (c == '2')
@@ -1741,13 +1736,13 @@ static bool_ player_birth_aux_ask()
dump_specs(sel);
/* Get a class */
- while (1)
+ while (true)
{
strnfmt(buf, 200, "Choose a class specialisation (%c-%c), * for random, = for options, 8/2/4/6 for up/down/left/right: ", I2A(0), (n <= 25) ? I2A(n - 1) : I2D(n - 26-1));
put_str(buf, 15, 2);
c = inkey();
if (c == 'Q') quit(NULL);
- if (c == 'S') return (FALSE);
+ if (c == 'S') return false;
if (c == '*')
{
k = randint(n) - 1;
@@ -1762,7 +1757,7 @@ static bool_ player_birth_aux_ask()
else if (c == '=')
{
screen_save();
- do_cmd_options_aux(6, "Startup Options", FALSE);
+ do_cmd_options_aux(6, "Startup Options", false);
screen_load();
}
else if (c == '2')
@@ -1850,7 +1845,7 @@ static bool_ player_birth_aux_ask()
n = dump_gods(sel, choice, max);
/* Choose */
- while (1)
+ while (true)
{
strnfmt(buf, 200, "Choose a god (%c-%c), * for a random choice, "
"= for options, 8/2/4/6 for movement: ",
@@ -1861,7 +1856,7 @@ static bool_ player_birth_aux_ask()
if (c == 'Q') quit(NULL);
if (c == 'S')
{
- return (FALSE);
+ return false;
}
if (c == '*')
{
@@ -1881,7 +1876,7 @@ static bool_ player_birth_aux_ask()
else if (c == '=')
{
screen_save();
- do_cmd_options_aux(6, "Startup Options", FALSE);
+ do_cmd_options_aux(6, "Startup Options", false);
screen_load();
}
else if (c == '2')
@@ -1946,13 +1941,13 @@ static bool_ player_birth_aux_ask()
if (get_check("Do you want to modify the options"))
{
screen_save();
- do_cmd_options_aux(6, "Startup Options", FALSE);
+ do_cmd_options_aux(6, "Startup Options", false);
screen_load();
}
}
/* Is the player an "astral" being? */
- p_ptr->astral = (race_flags_p(PR_ASTRAL)) ? TRUE : FALSE;
+ p_ptr->astral = race_flags_p(PR_ASTRAL);
/*
* A note by pelpel. (remove this please)
@@ -2001,13 +1996,13 @@ static bool_ player_birth_aux_ask()
"If you do not want any optional quests, enter 0.");
/* Ask the number of additional quests */
- while (TRUE)
+ while (true)
{
put_str(format("Number of quests? (0-%u) ",
MAX_RANDOM_QUEST - 1), 20, 2);
/* Get a the number of additional quest */
- while (TRUE)
+ while (true)
{
/* Move the cursor */
put_str("", 20, 27);
@@ -2038,7 +2033,7 @@ static bool_ player_birth_aux_ask()
}
/* Set the quest monster hook */
- get_mon_num_hook = monster_quest;
+ get_monster_hook = monster_quest;
/* Prepare allocation table */
get_mon_num_prep();
@@ -2075,7 +2070,7 @@ static bool_ player_birth_aux_ask()
quest_random_init_hook();
/* Ok */
- return (TRUE);
+ return true;
}
@@ -2104,7 +2099,7 @@ static const int birth_stat_costs[(18-10) + 1] =
*
* Taken from V 2.9.0
*/
-static bool_ player_birth_aux_point()
+static bool player_birth_aux_point()
{
int i;
@@ -2139,7 +2134,7 @@ static bool_ player_birth_aux_point()
p_ptr->luck_max = p_ptr->luck_base;
/* Interact */
- while (1)
+ while (true)
{
/* Reset cost */
cost = 0;
@@ -2214,7 +2209,7 @@ static bool_ player_birth_aux_point()
if (ch == 'Q') quit(NULL);
/* Start over */
- if (ch == 'S') return (FALSE);
+ if (ch == 'S') return false;
/* Done */
if (ch == ESCAPE) break;
@@ -2246,19 +2241,17 @@ static bool_ player_birth_aux_point()
/* Done */
- return (TRUE);
+ return true;
}
/*
* Use the autoroller or not to generate a char
*/
-static bool_ player_birth_aux_auto()
+static bool player_birth_aux_auto()
{
int i, j, m, v;
- bool_ flag = FALSE;
-
- bool_ prev = FALSE;
+ bool prev = false;
char c;
@@ -2299,7 +2292,7 @@ static bool_ player_birth_aux_auto()
j = rp_ptr->ps.adj[i] + rmp_ptr->ps.adj[i] + cp_ptr->ps.adj[i];
/* Obtain the "maximal" stat */
- m = adjust_stat(17, j, TRUE);
+ m = adjust_stat(17, j);
/* Save the maximum */
@@ -2321,7 +2314,7 @@ static bool_ player_birth_aux_auto()
for (i = 0; i < 6; i++)
{
/* Get a minimum stat */
- while (TRUE)
+ while (true)
{
char *s;
@@ -2372,7 +2365,7 @@ static bool_ player_birth_aux_auto()
}
/* Roll */
- while (TRUE)
+ while (true)
{
/* Feedback */
if (options->autoroll)
@@ -2417,7 +2410,7 @@ static bool_ player_birth_aux_auto()
/* Auto-roll */
while (options->autoroll)
{
- bool_ accept = TRUE;
+ bool accept = true;
/* Get a new character */
get_stats();
@@ -2440,7 +2433,7 @@ static bool_ player_birth_aux_auto()
/* This stat is not okay */
else
{
- accept = FALSE;
+ accept = false;
}
}
@@ -2448,7 +2441,7 @@ static bool_ player_birth_aux_auto()
if (accept) break;
/* Take note every 25 rolls */
- flag = (!(auto_round % AUTOROLLER_STEP));
+ bool flag = (!(auto_round % AUTOROLLER_STEP));
/* Update display occasionally */
if (flag || (auto_round < last_round + 100))
@@ -2480,7 +2473,7 @@ static bool_ player_birth_aux_auto()
get_money();
/* Input loop */
- while (TRUE)
+ while (true)
{
/* Calculate the bonuses and hitpoints */
p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_BODY);
@@ -2512,7 +2505,7 @@ static bool_ player_birth_aux_auto()
if (c == 'Q') quit(NULL);
/* Start over */
- if (c == 'S') return (FALSE);
+ if (c == 'S') return false;
/* Escape accepts the roll */
if (c == ESCAPE) break;
@@ -2523,7 +2516,7 @@ static bool_ player_birth_aux_auto()
/* Previous character */
if (prev && (c == 'p'))
{
- load_prev_data(TRUE);
+ load_prev_data(true);
continue;
}
@@ -2545,13 +2538,13 @@ static bool_ player_birth_aux_auto()
save_prev_data();
/* Note that a previous roll exists */
- prev = TRUE;
+ prev = true;
}
/* Clear prompt */
clear_from(23);
- return (TRUE);
+ return true;
}
@@ -2562,7 +2555,7 @@ static bool_ player_birth_aux_auto()
* from continuously rolling up characters, which can be VERY
* expensive CPU wise. And it cuts down on player stupidity.
*/
-static bool_ player_birth_aux()
+static bool player_birth_aux()
{
auto const &s_descriptors = game->edit_data.s_descriptors;
auto &s_info = game->s_info;
@@ -2570,7 +2563,10 @@ static bool_ player_birth_aux()
char c;
/* Ask */
- if (!player_birth_aux_ask()) return (FALSE);
+ if (!player_birth_aux_ask())
+ {
+ return false;
+ }
for (std::size_t i = 1; i < s_descriptors.size(); i++)
{
@@ -2606,7 +2602,7 @@ static bool_ player_birth_aux()
if (do_quick_start)
{
- load_prev_data(FALSE);
+ load_prev_data(false);
/* Roll for base hitpoints */
get_extra();
@@ -2628,12 +2624,12 @@ static bool_ player_birth_aux()
/* Point based */
if (options->point_based)
{
- if (!player_birth_aux_point()) return FALSE;
+ if (!player_birth_aux_point()) return false;
}
/* Auto-roll */
else
{
- if (!player_birth_aux_auto()) return FALSE;
+ if (!player_birth_aux_auto()) return false;
}
/*** Finish up ***/
@@ -2649,18 +2645,24 @@ static bool_ player_birth_aux()
c = inkey();
/* Quit */
- if (c == 'Q') quit(NULL);
+ if (c == 'Q')
+ {
+ quit(NULL);
+ }
/* Start over */
- if (c == 'S') return (FALSE);
+ if (c == 'S')
+ {
+ return false;
+ }
}
/* Save this for the next character */
- game->previous_char.quick_ok = TRUE;
+ game->previous_char.quick_ok = true;
save_prev_data();
/* Accept */
- return (TRUE);
+ return true;
}
@@ -2697,7 +2699,7 @@ void player_birth()
std::size_t rtown = TOWN_RANDOM;
/* Create a new character */
- while (1)
+ while (true)
{
/* Wipe the player */
player_wipe();
@@ -2710,7 +2712,7 @@ void player_birth()
p_ptr->skill_points = 0;
p_ptr->skill_last_level = 1;
- recalc_skills(FALSE);
+ recalc_skills(false);
/* grab level 1 abilities */
p_ptr->abilities.clear();
@@ -2720,7 +2722,7 @@ void player_birth()
{
byte i = p_ptr->pgod;
p_ptr->pgod = 0;
- follow_god(i, TRUE);
+ follow_god(i, true);
}
/* Select the default melee type */
@@ -2761,9 +2763,9 @@ void player_birth()
d_ptr->t_idx[num] = rtown;
rtown++;
- while (TRUE)
+ while (true)
{
- bool_ ok = TRUE;
+ bool ok = true;
lev = rand_range(d_ptr->mindepth, d_ptr->maxdepth - 1);
@@ -2772,12 +2774,15 @@ void player_birth()
{
if (d_ptr->t_level[j] == lev)
{
- ok = FALSE;
+ ok = false;
}
}
/* Ok found one */
- if (ok) break;
+ if (ok)
+ {
+ break;
+ }
}
d_ptr->t_level[num] = lev;
@@ -2802,7 +2807,7 @@ void player_birth()
for (std::size_t i = 1; i < max_towns; i++)
{
/* Not destroyed ! yet .. ;) */
- town_info[i].destroyed = FALSE;
+ town_info[i].destroyed = false;
/* Ignore non-existent towns */
if (!(town_info[i].flags & (TOWN_REAL))) continue;
@@ -2826,7 +2831,7 @@ void player_birth()
auto &w = wilderness(x, y);
w.seed = seed_t::system();
w.entrance = 0;
- w.known = FALSE;
+ w.known = false;
}
}
}
@@ -2837,7 +2842,7 @@ void player_birth()
static char savefile_module[46][80];
static char savefile_names[46][30];
static char savefile_desc[46][80];
-static bool_ savefile_alive[46];
+static bool savefile_alive[46];
static int savefile_idx[46];
/*
@@ -2863,10 +2868,6 @@ int load_savefile_names()
if (!fff) return (0);
- /* Save the current 'player_base' */
- player_base_save = game->player_base;
-
-
/*
* Parse, use '@' intead of ':' as a separator because it cannot exists
* in savefiles
@@ -2908,8 +2909,7 @@ int load_savefile_names()
savefile_module[max][4] = '\0';
}
- if (buf[i] == '0') savefile_alive[max] = FALSE;
- else if (buf[i] == '1') savefile_alive[max] = TRUE;
+ savefile_alive[max] = (buf[i] == '1');
i++;
start = i;
@@ -2923,11 +2923,10 @@ int load_savefile_names()
strcpy(savefile_desc[max], buf + i);
/* Build platform-dependent savefile name */
- game->player_base = savefile_names[max];
- process_player_name(TRUE);
+ auto player_base = process_player_name(savefile_names[max]);
/* Try to open the savefile */
- fd = fd_open(savefile, O_RDONLY);
+ fd = fd_open(name_file_save(player_base).c_str(), O_RDONLY);
/* Still existing ? */
if (fd >= 0)
@@ -2939,10 +2938,6 @@ int load_savefile_names()
my_fclose(fff);
- /* Restore the values of 'player_base' and 'savefile' */
- game->player_base = player_base_save;
- process_player_name(TRUE);
-
return (max);
}
@@ -2981,9 +2976,13 @@ void save_savefile_names()
for (i = 0; i < max; i++)
{
- if (!strcmp(savefile_names[i], game->player_base.c_str())) continue;
+ if (equals(savefile_names[i], game->player_base.c_str()))
+ {
+ continue;
+ }
+
fprintf(fff, "%s@%c%s@%s\n", savefile_module[i],
- (savefile_alive[i]) ? '1' : '0', savefile_names[i], savefile_desc[i]);
+ savefile_alive[i] ? '1' : '0', savefile_names[i], savefile_desc[i]);
}
my_fclose(fff);
@@ -3037,9 +3036,9 @@ static void dump_savefiles(int sel, int max)
/* Asks for new game or load game */
-bool_ no_begin_screen = FALSE;
+bool no_begin_screen = false;
-bool_ begin_screen()
+bool begin_screen()
{
int m, k, sel, max;
@@ -3063,7 +3062,7 @@ savefile_try_again:
max = m + 2;
if (max > 2) sel = 2;
- while (TRUE)
+ while (true)
{
/* Clear screen */
Term_clear();
@@ -3114,19 +3113,11 @@ savefile_try_again:
{
if (!get_check(format("Really delete '%s'?", savefile_names[savefile_idx[sel - 2]]))) continue;
- /* Save current 'player_base' */
- std::string player_base_save = game->player_base;
-
/* Build platform-dependent save file name */
- game->player_base = savefile_names[savefile_idx[sel - 2]];
- process_player_name(TRUE);
+ auto player_base = process_player_name(savefile_names[savefile_idx[sel - 2]]);
/* Remove the savefile */
- fd_kill(savefile);
-
- /* Restore 'player_base' and 'savefile' */
- game->player_base = player_base_save;
- process_player_name(TRUE);
+ fd_kill(name_file_save(player_base).c_str());
/* Reload, gods I hate using goto .. */
goto savefile_try_again;
@@ -3144,15 +3135,19 @@ savefile_try_again:
prt("Enter the name of the savefile that will hold this character: ", 23, 0);
/* Ask the user for a string */
- if (!askfor_aux(&game->player_base, 15)) continue;
+ auto tmp = game->player_base;
+ if (!askfor_aux(&tmp, 15))
+ {
+ continue;
+ }
/* Process the player name */
- process_player_name(TRUE);
+ set_player_base(tmp);
// If the savefile already exists, we do *NOT* want to
- // create a new game, so we'll need to return FALSE for
+ // create a new game, so we'll need to return false for
// that.
- if (boost::filesystem::exists(savefile))
+ if (boost::filesystem::exists(name_file_save()))
{
// Show a message so user doesn't get confused.
msg_print(NULL);
@@ -3170,12 +3165,12 @@ savefile_try_again:
prt("", 0, 0);
// Load character
- return FALSE;
+ return false;
}
else
{
// Start new game
- return TRUE;
+ return true;
}
}
if (k == 'b')
@@ -3184,12 +3179,16 @@ savefile_try_again:
prt("Enter the name of a savefile: ", 23, 0);
/* Ask the user for a string */
- if (!askfor_aux(&game->player_base, 15)) continue;
+ auto tmp = game->player_base;
+ if (!askfor_aux(&tmp, 15))
+ {
+ continue;
+ }
/* Process the player name */
- process_player_name(TRUE);
+ set_player_base(tmp);
- return (FALSE);
+ return false;
}
else
{
@@ -3200,15 +3199,13 @@ savefile_try_again:
if ((x < 2) || (x >= max)) continue;
- game->player_base = savefile_names[savefile_idx[x - 2]];
-
/* Process the player name */
- process_player_name(TRUE);
+ set_player_base(savefile_names[savefile_idx[x - 2]]);
- return (FALSE);
+ return false;
}
}
/* Shouldnt happen */
- return (FALSE);
+ return false;
}
diff --git a/src/birth.hpp b/src/birth.hpp
index 82bdfcf6..6dbf1155 100644
--- a/src/birth.hpp
+++ b/src/birth.hpp
@@ -1,11 +1,9 @@
#pragma once
-#include "h-basic.h"
-
-void print_desc_aux(cptr txt, int y, int x);
+void print_desc_aux(const char *txt, int y, int x);
void save_savefile_names();
-bool_ begin_screen();
+bool begin_screen();
void player_birth();
void roll_player_hp();
-extern bool_ no_begin_screen;
+extern bool no_begin_screen;
diff --git a/src/birther.hpp b/src/birther.hpp
index 0c28b513..85773e5e 100644
--- a/src/birther.hpp
+++ b/src/birther.hpp
@@ -1,29 +1,28 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
-#include <string>
-#include <vector>
+#include <array>
/**
* Player information during the birth process.
*/
struct birther
{
- s16b race;
- s16b rmod;
- s16b pclass;
- s16b spec;
+ s16b race = 0;
+ s16b rmod = 0;
+ s16b pclass = 0;
+ s16b spec = 0;
- byte quests;
+ byte quests = 0;
- byte god;
- s32b grace;
+ byte god = 0;
+ s32b grace = 0;
- s32b au;
+ s32b au = 0;
- s16b stat[6];
- s16b luck;
+ std::array<s16b, 6> stat { };
+ s16b luck = 0;
- bool_ quick_ok;
+ bool quick_ok = false;
};
diff --git a/src/bldg.cc b/src/bldg.cc
index 9b3750a6..00105881 100644
--- a/src/bldg.cc
+++ b/src/bldg.cc
@@ -13,6 +13,8 @@
* Heavily modified for ToME by DarkGod
*/
+#include "bldg.hpp"
+
#include "cave_type.hpp"
#include "cmd3.hpp"
#include "files.hpp"
@@ -39,11 +41,12 @@
#include "store_type.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "util.h"
#include "variable.hpp"
#include "xtra1.hpp"
#include "xtra2.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
/* remember building location */
static int building_loc = 0;
@@ -52,7 +55,7 @@ static int building_loc = 0;
/*
* A helper function for is_state
*/
-static bool_ is_state_aux(store_type const *s_ptr, int state)
+static bool is_state_aux(store_type const *s_ptr, int state)
{
auto const &ow_info = game->edit_data.ow_info;
@@ -61,30 +64,30 @@ static bool_ is_state_aux(store_type const *s_ptr, int state)
/* Check race */
if (ow_ptr->races[state][p_ptr->prace / 32] & (1 << p_ptr->prace))
{
- return (TRUE);
+ return true;
}
/* Check class */
if (ow_ptr->classes[state][p_ptr->prace / 32] & (1 << p_ptr->pclass))
{
- return (TRUE);
+ return true;
}
/* All failed */
- return (FALSE);
+ return false;
}
/*
* Test if the state accords with the player
*/
-bool_ is_state(store_type const *s_ptr, int state)
+bool is_state(store_type const *s_ptr, int state)
{
if (state == STORE_NORMAL)
{
- if (is_state_aux(s_ptr, STORE_LIKED)) return (FALSE);
- if (is_state_aux(s_ptr, STORE_HATED)) return (FALSE);
- return (TRUE);
+ if (is_state_aux(s_ptr, STORE_LIKED)) return false;
+ if (is_state_aux(s_ptr, STORE_HATED)) return false;
+ return true;
}
else
@@ -308,7 +311,7 @@ static void display_fruit(int row, int col, int fruit)
/*
* gamble_comm
*/
-static bool_ gamble_comm(int cmd)
+static void gamble_comm(int cmd)
{
int roll1, roll2, roll3, choice, odds, win;
@@ -324,7 +327,7 @@ static bool_ gamble_comm(int cmd)
char out_val[160], tmp_str[80], again;
- cptr p;
+ const char *p;
screen_save();
@@ -358,8 +361,9 @@ static bool_ gamble_comm(int cmd)
{
msg_print("Hey! You don't have the gold - get out of here!");
msg_print(NULL);
+
screen_load();
- return (FALSE);
+ return;
}
else if (wager > maxbet)
{
@@ -373,7 +377,7 @@ static bool_ gamble_comm(int cmd)
wager = 1;
}
msg_print(NULL);
- win = FALSE;
+ win = false;
odds = 0;
oldgold = p_ptr->au;
@@ -391,7 +395,7 @@ static bool_ gamble_comm(int cmd)
{
c_put_str(TERM_GREEN, "In Between", 5, 2);
odds = 3;
- win = FALSE;
+ win = false;
roll1 = randint(10);
roll2 = randint(10);
choice = randint(10);
@@ -402,7 +406,7 @@ static bool_ gamble_comm(int cmd)
prt(tmp_str, 11, 14);
if (((choice > roll1) && (choice < roll2)) ||
((choice < roll1) && (choice > roll2)))
- win = TRUE;
+ win = true;
break;
}
@@ -419,9 +423,9 @@ static bool_ gamble_comm(int cmd)
roll2, roll3);
prt(tmp_str, 7, 5);
if ((roll3 == 7) || (roll3 == 11))
- win = TRUE;
+ win = true;
else if ((roll3 == 2) || (roll3 == 3) || (roll3 == 12))
- win = FALSE;
+ win = false;
else
{
do
@@ -436,11 +440,11 @@ static bool_ gamble_comm(int cmd)
roll1, roll2, roll3);
prt(tmp_str, 8, 5);
if (roll3 == choice)
- win = TRUE;
+ win = true;
else if (roll3 == 7)
- win = FALSE;
+ win = false;
}
- while ((win != TRUE) && (win != FALSE));
+ while ((win != true) && (win != false));
}
break;
@@ -449,7 +453,7 @@ static bool_ gamble_comm(int cmd)
case BACT_DICE_SLOTS: /* The Dice Slots */
{
c_put_str(TERM_GREEN, "Dice Slots", 5, 2);
- win = FALSE;
+ win = false;
roll1 = randint(6);
roll2 = randint(6);
choice = randint(6);
@@ -464,7 +468,7 @@ static bool_ gamble_comm(int cmd)
display_fruit(8, 21, choice - 1);
if ((roll1 == roll2) && (roll2 == choice))
{
- win = TRUE;
+ win = true;
if (roll1 == 1)
odds = 4;
else if (roll1 == 2)
@@ -474,7 +478,7 @@ static bool_ gamble_comm(int cmd)
}
else if ((roll1 == 6) && (roll2 == 6))
{
- win = TRUE;
+ win = true;
odds = choice + 1;
}
@@ -498,16 +502,14 @@ static bool_ gamble_comm(int cmd)
strnfmt(tmp_str, 80, "Current Gold: %9ld", p_ptr->au);
prt(tmp_str, 22, 2);
prt("Again(Y/N)?", 18, 37);
- move_cursor(18, 49);
+ Term_gotoxy(49, 18);
again = inkey();
if (wager > p_ptr->au)
{
msg_print("Hey! You don't have the gold - get out of here!");
msg_print(NULL);
screen_load();
- return (FALSE);
- /* strnfmt(tmp_str, 80, "Current Wager: %9ld",wager);
- prt(tmp_str, 17, 2); */
+ return;
}
}
while ((again == 'y') || (again == 'Y'));
@@ -521,8 +523,6 @@ static bool_ gamble_comm(int cmd)
}
screen_load();
-
- return (TRUE);
}
@@ -535,13 +535,10 @@ static bool_ gamble_comm(int cmd)
* ghost code does become a reality again. Does help to avoid filthy urchins.
* Resting at night is also a quick way to restock stores -KMW-
*/
-static bool_ inn_comm(int cmd)
+static bool inn_comm(int cmd)
{
- bool_ vampire;
-
-
- /* Extract race info */
- vampire = ((race_flags_p(PR_VAMPIRE)) || (p_ptr->mimic_form == resolve_mimic_name("Vampire")));
+ /* Is the player a vampire? */
+ auto const vampire = ((race_flags_p(PR_VAMPIRE)) || (p_ptr->mimic_form == resolve_mimic_name("Vampire")));
switch (cmd)
{
@@ -565,17 +562,15 @@ static bool_ inn_comm(int cmd)
*/
case BACT_REST: /* Rest for the night */
{
- bool_ nighttime;
-
/* Extract the current time */
- nighttime = ((bst(HOUR, turn) < 6) || (bst(HOUR, turn) >= 18));
+ bool const nighttime = ((bst(HOUR, turn) < 6) || (bst(HOUR, turn) >= 18));
/* Normal races rest at night */
if (!vampire && !nighttime)
{
msg_print("The rooms are available only at night.");
msg_print(NULL);
- return (FALSE);
+ return false;
}
/* Vampires rest during daytime */
@@ -583,7 +578,7 @@ static bool_ inn_comm(int cmd)
{
msg_print("The rooms are available only during daylight for your kind.");
msg_print(NULL);
- return (FALSE);
+ return false;
}
/* Must cure HP draining status first */
@@ -592,7 +587,7 @@ static bool_ inn_comm(int cmd)
msg_print("You need a healer, not a room.");
msg_print(NULL);
msg_print("Sorry, but I don't want anyone dying in here.");
- return (FALSE);
+ return false;
}
/* Let the time pass XXX XXX XXX */
@@ -627,7 +622,7 @@ static bool_ inn_comm(int cmd)
else msg_print("You awake refreshed for the new day.");
/* Dungeon stuff */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
p_ptr->oldpx = p_ptr->px;
p_ptr->oldpy = p_ptr->py;
@@ -646,7 +641,7 @@ static bool_ inn_comm(int cmd)
}
}
- return (TRUE);
+ return true;
}
@@ -675,7 +670,7 @@ static void get_questinfo(int questnum)
/*
* Request a quest from the Lord.
*/
-static bool_ castle_quest(int y, int x)
+static bool castle_quest(int y, int x)
{
int plot = 0;
@@ -691,7 +686,7 @@ static bool_ castle_quest(int y, int x)
if ((!plot) || (plots[plot] == QUEST_NULL))
{
put_str("I don't have a quest for you at the moment.", 8, 0);
- return FALSE;
+ return false;
}
q_ptr = &quest[plots[plot]];
@@ -705,7 +700,7 @@ static bool_ castle_quest(int y, int x)
struct hook_quest_finish_in in = { plots[plot] };
process_hooks_new(HOOK_QUEST_FINISH, &in, NULL);
- return (TRUE);
+ return true;
}
/* Quest is still unfinished */
@@ -715,7 +710,7 @@ static bool_ castle_quest(int y, int x)
put_str("Use CTRL-Q to check the status of your quest.", 9, 0);
put_str("Return when you have completed your quest.", 12, 0);
- return (FALSE);
+ return false;
}
/* Failed quest */
else if (q_ptr->status == QUEST_STATUS_FAILED)
@@ -726,7 +721,7 @@ static bool_ castle_quest(int y, int x)
hook_quest_fail_in in = { plots[plot] };
process_hooks_new(HOOK_QUEST_FAIL, &in, NULL);
- return (FALSE);
+ return false;
}
/* No quest yet */
else if (q_ptr->status == QUEST_STATUS_UNTAKEN)
@@ -734,7 +729,7 @@ static bool_ castle_quest(int y, int x)
struct hook_init_quest_in in = { plots[plot] };
if (process_hooks_new(HOOK_INIT_QUEST, &in, NULL))
{
- return (FALSE);
+ return false;
}
q_ptr->status = QUEST_STATUS_TAKEN;
@@ -745,10 +740,10 @@ static bool_ castle_quest(int y, int x)
/* Add the hooks */
quest[plots[plot]].init();
- return (TRUE);
+ return true;
}
- return FALSE;
+ return false;
}
/*
@@ -873,7 +868,7 @@ static void list_weapon(object_type *o_ptr, int row, int col)
char tmp_str[80];
- object_desc(o_name, o_ptr, TRUE, 0);
+ object_desc(o_name, o_ptr, true, 0);
c_put_str(TERM_YELLOW, o_name, row, col);
strnfmt(tmp_str, 80, "To Hit: %d To Damage: %d", o_ptr->to_h, o_ptr->to_d);
put_str(tmp_str, row + 1, col);
@@ -902,7 +897,7 @@ static bool item_tester_hook_melee_weapon(object_type const *o_ptr)
/*
* compare_weapons -KMW-
*/
-static bool_ compare_weapons()
+static bool compare_weapons()
{
int item, i;
@@ -928,7 +923,7 @@ static bool_ compare_weapons()
item_tester_hook_melee_weapon))
{
object_wipe(orig_ptr);
- return (FALSE);
+ return false;
}
/* Get the item (in the pack) */
@@ -944,7 +939,7 @@ static bool_ compare_weapons()
item_tester_hook_melee_weapon))
{
object_wipe(orig_ptr);
- return (FALSE);
+ return false;
}
/* Get the item (in the pack) */
@@ -954,7 +949,7 @@ static bool_ compare_weapons()
i_ptr = &p_ptr->inventory[INVEN_WIELD];
object_copy(i_ptr, o1_ptr);
- calc_bonuses(TRUE);
+ calc_bonuses(true);
list_weapon(o1_ptr, i, 2);
compare_weapon_aux1(o1_ptr, 2, i + 8);
@@ -964,20 +959,20 @@ static bool_ compare_weapons()
object_copy(i_ptr, orig_ptr);
else
object_copy(i_ptr, o2_ptr);
- calc_bonuses(TRUE);
+ calc_bonuses(true);
list_weapon(o2_ptr, i, 40);
compare_weapon_aux1(o2_ptr, 40, i + 8);
i_ptr = &p_ptr->inventory[INVEN_WIELD];
object_copy(i_ptr, orig_ptr);
- calc_bonuses(TRUE);
+ calc_bonuses(true);
object_wipe(orig_ptr);
put_str("(Only highest damage applies per monster. Special damage not cumulative)", 20, 0);
- return (TRUE);
+ return true;
}
@@ -986,7 +981,7 @@ static bool_ compare_weapons()
* sharpen arrows, repair armor, repair weapon
* -KMW-
*/
-static bool_ fix_item(int istart, int iend, int ispecific, bool_ iac)
+static bool fix_item(int istart, int iend, int ispecific, bool iac)
{
int i;
@@ -998,7 +993,7 @@ static bool_ fix_item(int istart, int iend, int ispecific, bool_ iac)
char out_val[80], tmp_str[80];
- bool_ repaired = FALSE;
+ bool repaired = false;
clear_bldg(5, 18);
strnfmt(tmp_str, 80, " Based on your skill, we can improve up to +%d", maxenchant);
@@ -1016,9 +1011,9 @@ static bool_ fix_item(int istart, int iend, int ispecific, bool_ iac)
if (o_ptr->tval)
{
- object_desc(tmp_str, o_ptr, FALSE, 1);
+ object_desc(tmp_str, o_ptr, false, 1);
- if ((o_ptr->name1 && (o_ptr->ident & 0x08)))
+ if (o_ptr->name1 && o_ptr->identified)
strnfmt(out_val, 80, "%-40s: beyond our skills!", tmp_str);
else if (o_ptr->name1)
strnfmt(out_val, 80, "%-40s: in fine condition", tmp_str);
@@ -1032,7 +1027,7 @@ static bool_ fix_item(int istart, int iend, int ispecific, bool_ iac)
{
o_ptr->to_a++;
strnfmt(out_val, 80, "%-40s: polished -> (%d)", tmp_str, o_ptr->to_a);
- repaired = TRUE;
+ repaired = true;
}
else if ((!iac) && ((o_ptr->to_h <= -3) || (o_ptr->to_d <= -3)))
{
@@ -1048,7 +1043,7 @@ static bool_ fix_item(int istart, int iend, int ispecific, bool_ iac)
o_ptr->to_d++;
strnfmt(out_val, 80, "%-40s: sharpened -> (%d,%d)", tmp_str,
o_ptr->to_h, o_ptr->to_d);
- repaired = TRUE;
+ repaired = true;
}
else
strnfmt(out_val, 80, "%-40s: in fine condition", tmp_str);
@@ -1073,33 +1068,22 @@ static bool_ fix_item(int istart, int iend, int ispecific, bool_ iac)
}
clear_bldg(5, 18);
- return (repaired);
+ return repaired;
}
/*
- * Research Item
- */
-static bool_ research_item()
-{
- clear_bldg(5, 18);
- return (identify_fully());
-}
-
-
-
-/*
* Execute a building command
*/
-bool_ bldg_process_command(const store_type *s_ptr, store_action_type const *ba_ptr)
+bool bldg_process_command(const store_type *s_ptr, store_action_type const *ba_ptr)
{
int bact = ba_ptr->action;
int bcost;
- bool_ paid = FALSE;
+ bool paid = false;
- bool_ recreate = FALSE;
+ bool recreate = false;
if (is_state(s_ptr, STORE_LIKED))
@@ -1121,7 +1105,7 @@ bool_ bldg_process_command(const store_type *s_ptr, store_action_type const *ba_
{
msg_print("You have no right to choose that!");
msg_print(NULL);
- return FALSE;
+ return false;
}
/* check gold */
@@ -1129,17 +1113,11 @@ bool_ bldg_process_command(const store_type *s_ptr, store_action_type const *ba_
{
msg_print("You do not have the gold!");
msg_print(NULL);
- return FALSE;
+ return false;
}
switch (bact)
{
- case BACT_RESEARCH_ITEM:
- {
- paid = research_item();
- break;
- }
-
case BACT_TOWN_HISTORY:
{
town_history();
@@ -1154,8 +1132,9 @@ bool_ bldg_process_command(const store_type *s_ptr, store_action_type const *ba_
case BACT_QUEST1:
{
- int y = 1, x = 1;
- bool_ ok = FALSE;
+ int y = 1;
+ int x = 1;
+ bool ok = false;
while ((x < cur_wid - 1) && !ok)
{
@@ -1166,7 +1145,7 @@ bool_ bldg_process_command(const store_type *s_ptr, store_action_type const *ba_
if (bact - BACT_QUEST1 + FEAT_QUEST1 == cave[y][x].feat)
{
/* Stop the loop */
- ok = TRUE;
+ ok = true;
}
y++;
}
@@ -1176,7 +1155,6 @@ bool_ bldg_process_command(const store_type *s_ptr, store_action_type const *ba_
if (ok)
{
recreate = castle_quest(y - 1, x - 1);
- ;
}
else
{
@@ -1216,30 +1194,23 @@ bool_ bldg_process_command(const store_type *s_ptr, store_action_type const *ba_
case BACT_ENCHANT_WEAPON:
{
- paid = fix_item(INVEN_WIELD, INVEN_WIELD, 0, FALSE);
+ paid = fix_item(INVEN_WIELD, INVEN_WIELD, 0, false);
break;
}
case BACT_ENCHANT_ARMOR:
{
- paid = fix_item(INVEN_BODY, INVEN_FEET, 0, TRUE);
+ paid = fix_item(INVEN_BODY, INVEN_FEET, 0, true);
break;
}
/* needs work */
case BACT_RECHARGE:
{
- if (recharge(80)) paid = TRUE;
- break;
- }
-
- /* needs work */
- case BACT_IDENTS:
- {
- identify_pack();
- msg_print("Your possessions have been identified.");
- msg_print(NULL);
- paid = TRUE;
+ if (recharge(80))
+ {
+ paid = true;
+ }
break;
}
@@ -1255,9 +1226,10 @@ bool_ bldg_process_command(const store_type *s_ptr, store_action_type const *ba_
if (p_ptr->black_breath)
{
msg_print("The hold of the Black Breath on you is broken!");
- p_ptr->black_breath = FALSE;
+ p_ptr->black_breath = false;
}
- paid = TRUE;
+
+ paid = true;
break;
}
@@ -1270,31 +1242,32 @@ bool_ bldg_process_command(const store_type *s_ptr, store_action_type const *ba_
set_confused(0);
set_cut(0);
set_stun(0);
- paid = TRUE;
+
+ paid = true;
break;
}
/* needs work */
case BACT_RESTORE:
{
- if (do_res_stat(A_STR, TRUE)) paid = TRUE;
- if (do_res_stat(A_INT, TRUE)) paid = TRUE;
- if (do_res_stat(A_WIS, TRUE)) paid = TRUE;
- if (do_res_stat(A_DEX, TRUE)) paid = TRUE;
- if (do_res_stat(A_CON, TRUE)) paid = TRUE;
- if (do_res_stat(A_CHR, TRUE)) paid = TRUE;
+ if (do_res_stat(A_STR, true)) paid = true;
+ if (do_res_stat(A_INT, true)) paid = true;
+ if (do_res_stat(A_WIS, true)) paid = true;
+ if (do_res_stat(A_DEX, true)) paid = true;
+ if (do_res_stat(A_CON, true)) paid = true;
+ if (do_res_stat(A_CHR, true)) paid = true;
break;
}
case BACT_ENCHANT_ARROWS:
{
- paid = fix_item(0, INVEN_WIELD, TV_ARROW, FALSE);
+ paid = fix_item(0, INVEN_WIELD, TV_ARROW, false);
break;
}
case BACT_ENCHANT_BOW:
{
- paid = fix_item(INVEN_BOW, INVEN_BOW, TV_BOW, FALSE);
+ paid = fix_item(INVEN_BOW, INVEN_BOW, TV_BOW, false);
break;
}
@@ -1302,17 +1275,19 @@ bool_ bldg_process_command(const store_type *s_ptr, store_action_type const *ba_
{
p_ptr->word_recall = 1;
msg_print("The air about you becomes charged...");
- paid = TRUE;
+
+ paid = true;
break;
}
case BACT_TELEPORT_LEVEL:
{
- if (reset_recall(FALSE))
+ if (reset_recall(false))
{
p_ptr->word_recall = 1;
msg_print("The air about you becomes charged...");
- paid = TRUE;
+
+ paid = true;
}
break;
}
@@ -1320,31 +1295,33 @@ bool_ bldg_process_command(const store_type *s_ptr, store_action_type const *ba_
case BACT_MIMIC_NORMAL:
{
set_mimic(0, 0, 0);
- paid = TRUE;
+ paid = true;
break;
}
case BACT_DIVINATION:
{
- int i, count = 0;
- bool_ something = FALSE;
+ bool found = false;
- while (count < 1000)
+ for (int count = 0; count < 1000; count++)
{
- count++;
- i = rand_int(MAX_FATES);
+ int i = rand_int(MAX_FATES);
if (!fates[i].fate) continue;
if (fates[i].know) continue;
msg_print("You know a little more of your fate.");
- fates[i].know = TRUE;
- something = TRUE;
+ fates[i].know = true;
+
+ found = true;
break;
}
- if (!something) msg_print("Well, you have no fate, but I'll keep your money anyway!");
+ if (!found)
+ {
+ msg_print("Well, you have no fate, but I'll keep your money anyway!");
+ }
- paid = TRUE;
+ paid = true;
break;
}
@@ -1418,7 +1395,7 @@ bool_ bldg_process_command(const store_type *s_ptr, store_action_type const *ba_
store_prt_gold();
}
- return (recreate);
+ return recreate;
}
@@ -1442,7 +1419,7 @@ void enter_quest()
p_ptr->inside_quest = cave[p_ptr->py][p_ptr->px].special;
dun_level = 1;
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
p_ptr->oldpx = p_ptr->px;
p_ptr->oldpy = p_ptr->py;
}
diff --git a/src/bldg.hpp b/src/bldg.hpp
index 3b3412fa..095cfda8 100644
--- a/src/bldg.hpp
+++ b/src/bldg.hpp
@@ -1,10 +1,9 @@
#pragma once
-#include "h-basic.h"
#include "store_action_type_fwd.hpp"
#include "store_type_fwd.hpp"
-bool_ bldg_process_command(store_type const *s_ptr, store_action_type const *action);
+bool bldg_process_command(store_type const *s_ptr, store_action_type const *action);
void show_building(store_type const *s_ptr);
-bool_ is_state(store_type const *s_ptr, int state);
+bool is_state(store_type const *s_ptr, int state);
void enter_quest();
diff --git a/src/cave.cc b/src/cave.cc
index cad1506e..e50d7980 100644
--- a/src/cave.cc
+++ b/src/cave.cc
@@ -1,6 +1,7 @@
#include "cave.hpp"
#include "cave_type.hpp"
+#include "config.hpp"
#include "dungeon_flag.hpp"
#include "feature_flag.hpp"
#include "feature_type.hpp"
@@ -21,10 +22,10 @@
#include "store_info_type.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
+#include "z-util.hpp"
#include <cassert>
#include <vector>
@@ -64,10 +65,10 @@ int distance(int y1, int x1, int y2, int x2)
/*
- * Returns TRUE if a grid is considered to be a wall for the purpose
+ * Returns true if a grid is considered to be a wall for the purpose
* of magic mapping / clairvoyance
*/
-static bool_ is_wall(cave_type *c_ptr)
+static bool is_wall(cave_type *c_ptr)
{
auto const &f_info = game->edit_data.f_info;
@@ -77,22 +78,37 @@ static bool_ is_wall(cave_type *c_ptr)
: c_ptr->feat;
/* Paranoia */
- if (feat >= f_info.size()) return FALSE;
+ if (feat >= f_info.size())
+ {
+ return false;
+ }
/* Vanilla floors and doors aren't considered to be walls */
- if (feat < FEAT_SECRET) return FALSE;
+ if (feat < FEAT_SECRET)
+ {
+ return false;
+ }
/* Exception #1: a glass wall is a wall but doesn't prevent LOS */
- if (feat == FEAT_GLASS_WALL) return FALSE;
+ if (feat == FEAT_GLASS_WALL)
+ {
+ return false;
+ }
/* Exception #2: an illusion wall is not a wall but obstructs view */
- if (feat == FEAT_ILLUS_WALL) return TRUE;
+ if (feat == FEAT_ILLUS_WALL)
+ {
+ return true;
+ }
/* Exception #3: a small tree is a floor but obstructs view */
- if (feat == FEAT_SMALL_TREES) return TRUE;
+ if (feat == FEAT_SMALL_TREES)
+ {
+ return true;
+ }
/* Normal cases: use the WALL flag in f_info.txt */
- return (f_info[feat].flags & FF_WALL) ? TRUE : FALSE;
+ return !!(f_info[feat].flags & FF_WALL);
}
@@ -100,10 +116,10 @@ static bool_ is_wall(cave_type *c_ptr)
* A simple, fast, integer-based line-of-sight algorithm. By Joseph Hall,
* 4116 Brewster Drive, Raleigh NC 27606. Email to jnh@ecemwl.ncsu.edu.
*
- * Returns TRUE if a line of sight can be traced from (x1,y1) to (x2,y2).
+ * Returns true if a line of sight can be traced from (x1,y1) to (x2,y2).
*
* The LOS begins at the center of the tile (x1,y1) and ends at the center of
- * the tile (x2,y2). If los() is to return TRUE, all of the tiles this line
+ * the tile (x2,y2). If los() is to return true, all of the tiles this line
* passes through must be floor tiles, except for (x1,y1) and (x2,y2).
*
* We assume that the "mathematical corner" of a non-floor tile does not
@@ -131,7 +147,7 @@ static bool_ is_wall(cave_type *c_ptr)
*
* Use the "update_view()" function to determine player line-of-sight.
*/
-bool_ los(int y1, int x1, int y2, int x2)
+bool los(int y1, int x1, int y2, int x2)
{
/* Delta */
int dx, dy;
@@ -165,11 +181,14 @@ bool_ los(int y1, int x1, int y2, int x2)
/* Handle adjacent (or identical) grids */
- if ((ax < 2) && (ay < 2)) return (TRUE);
+ if ((ax < 2) && (ay < 2))
+ {
+ return true;
+ }
/* Paranoia -- require "safe" origin */
- /* if (!in_bounds(y1, x1)) return (FALSE); */
+ /* if (!in_bounds(y1, x1)) return false; */
/* Directly South/North */
@@ -180,7 +199,10 @@ bool_ los(int y1, int x1, int y2, int x2)
{
for (ty = y1 + 1; ty < y2; ty++)
{
- if (!cave_sight_bold(ty, x1)) return (FALSE);
+ if (!cave_sight_bold(ty, x1))
+ {
+ return false;
+ }
}
}
@@ -189,12 +211,15 @@ bool_ los(int y1, int x1, int y2, int x2)
{
for (ty = y1 - 1; ty > y2; ty--)
{
- if (!cave_sight_bold(ty, x1)) return (FALSE);
+ if (!cave_sight_bold(ty, x1))
+ {
+ return false;
+ }
}
}
/* Assume los */
- return (TRUE);
+ return true;
}
/* Directly East/West */
@@ -205,7 +230,10 @@ bool_ los(int y1, int x1, int y2, int x2)
{
for (tx = x1 + 1; tx < x2; tx++)
{
- if (!cave_sight_bold(y1, tx)) return (FALSE);
+ if (!cave_sight_bold(y1, tx))
+ {
+ return false;
+ }
}
}
@@ -214,12 +242,15 @@ bool_ los(int y1, int x1, int y2, int x2)
{
for (tx = x1 - 1; tx > x2; tx--)
{
- if (!cave_sight_bold(y1, tx)) return (FALSE);
+ if (!cave_sight_bold(y1, tx))
+ {
+ return false;
+ }
}
}
/* Assume los */
- return (TRUE);
+ return true;
}
@@ -228,21 +259,25 @@ bool_ los(int y1, int x1, int y2, int x2)
sy = (dy < 0) ? -1 : 1;
- /* Vertical "knights" */
+ /* Knight's moves */
if (ax == 1)
{
if (ay == 2)
{
- if (cave_sight_bold(y1 + sy, x1)) return (TRUE);
+ if (cave_sight_bold(y1 + sy, x1))
+ {
+ return true;
+ }
}
}
-
- /* Horizontal "knights" */
else if (ay == 1)
{
if (ax == 2)
{
- if (cave_sight_bold(y1, x1 + sx)) return (TRUE);
+ if (cave_sight_bold(y1, x1 + sx))
+ {
+ return true;
+ }
}
}
@@ -278,7 +313,10 @@ bool_ los(int y1, int x1, int y2, int x2)
/* the LOS exactly meets the corner of a tile. */
while (x2 - tx)
{
- if (!cave_sight_bold(ty, tx)) return (FALSE);
+ if (!cave_sight_bold(ty, tx))
+ {
+ return false;
+ }
qy += m;
@@ -289,7 +327,10 @@ bool_ los(int y1, int x1, int y2, int x2)
else if (qy > f2)
{
ty += sy;
- if (!cave_sight_bold(ty, tx)) return (FALSE);
+ if (!cave_sight_bold(ty, tx))
+ {
+ return false;
+ }
qy -= f1;
tx += sx;
}
@@ -325,7 +366,10 @@ bool_ los(int y1, int x1, int y2, int x2)
/* the LOS exactly meets the corner of a tile. */
while (y2 - ty)
{
- if (!cave_sight_bold(ty, tx)) return (FALSE);
+ if (!cave_sight_bold(ty, tx))
+ {
+ return false;
+ }
qx += m;
@@ -336,7 +380,10 @@ bool_ los(int y1, int x1, int y2, int x2)
else if (qx > f2)
{
tx += sx;
- if (!cave_sight_bold(ty, tx)) return (FALSE);
+ if (!cave_sight_bold(ty, tx))
+ {
+ return false;
+ }
qx -= f1;
ty += sy;
}
@@ -350,7 +397,7 @@ bool_ los(int y1, int x1, int y2, int x2)
}
/* Assume los */
- return (TRUE);
+ return true;
}
@@ -358,7 +405,7 @@ bool_ los(int y1, int x1, int y2, int x2)
/*
* Returns true if the player's grid is dark
*/
-bool_ no_lite()
+bool no_lite()
{
return (!player_can_see_bold(p_ptr->py, p_ptr->px));
}
@@ -370,12 +417,15 @@ bool_ no_lite()
*
* Used by destruction spells, and for placing stairs, etc.
*/
-bool_ cave_valid_bold(int y, int x)
+bool cave_valid_bold(int y, int x)
{
cave_type const *c_ptr = &cave[y][x];
/* Forbid perma-grids */
- if (cave_perma_grid(c_ptr)) return (FALSE);
+ if (cave_perma_grid(c_ptr))
+ {
+ return false;
+ }
/* Check objects */
for (auto const o_idx: c_ptr->o_idxs)
@@ -386,12 +436,12 @@ bool_ cave_valid_bold(int y, int x)
/* Forbid artifact grids */
if (artifact_p(o_ptr))
{
- return (FALSE);
+ return false;
}
}
/* Accept */
- return (TRUE);
+ return true;
}
@@ -438,31 +488,10 @@ static void image_object(byte *ap, char *cp)
{
auto const &k_info = game->edit_data.k_info;
- // Cached state which keeps a list of the "live" object_kind entries.
- static std::vector<size_t> *instance = nullptr;
-
- // First-time initialization
- if (!instance)
- {
- // Create the list of "live" indexes
- instance = new std::vector<size_t>();
- // Filter all the "live" entries
- for (size_t i = 0; i < k_info.size(); i++)
- {
- if (k_info[i].name)
- {
- instance->push_back(i);
- }
- }
- }
-
- // Sanity check
- assert(instance != nullptr);
-
// Select an object kind at random
- int n = rand_int(instance->size());
- *cp = k_info[(*instance)[n]].x_char;
- *ap = k_info[(*instance)[n]].x_attr;
+ auto const &k_ptr = uniform_element(k_info)->second;
+ *cp = k_ptr->x_char;
+ *ap = k_ptr->x_attr;
}
@@ -592,7 +621,7 @@ static byte multi_hued_attr(std::shared_ptr<monster_race> r_ptr)
/* Check breaths */
for (std::size_t i = 0; i < monster_spell_flag_set::nbits; i++)
{
- bool_ stored = FALSE;
+ bool stored = false;
/* Don't have that breath */
if (!(r_ptr->spells.bit(i))) continue;
@@ -622,7 +651,7 @@ static byte multi_hued_attr(std::shared_ptr<monster_race> r_ptr)
for (std::size_t j = 0; j < stored_colors; j++)
{
/* Already stored */
- if (allowed_attrs[j] == first_color) stored = TRUE;
+ if (allowed_attrs[j] == first_color) stored = true;
}
if (!stored)
{
@@ -847,25 +876,21 @@ static byte darker_attrs[16] =
};
-static void map_info(int y, int x, byte *ap, char *cp)
+static void map_info_layer1(
+ cave_type const *c_ptr,
+ bool apply_effects,
+ std::tuple<char, byte> feature_fn(feature_type const *),
+ std::tuple<char, byte> store_fn(store_info_type const *),
+ char *cp,
+ byte *ap)
{
auto const &st_info = game->edit_data.st_info;
- auto const &r_info = game->edit_data.r_info;
auto const &f_info = game->edit_data.f_info;
- auto const &k_info = game->edit_data.k_info;
+ auto const &lasting_effects = game->lasting_effects;
+ char c;
byte a;
- byte c;
-
- /**** Preparation ****/
-
- /* Access the grid */
- cave_type *c_ptr = &cave[y][x];
-
-
- /* Cache some frequently used values */
-
/* Grid info */
auto info = c_ptr->info;
@@ -878,9 +903,6 @@ static void map_info(int y, int x, byte *ap, char *cp)
/* Access floor */
auto f_ptr = &f_info[feat];
-
- /**** Layer 1 -- Terrain feature ****/
-
/* Only memorised or visible grids are displayed */
if (info & (CAVE_MARK | CAVE_SEEN))
{
@@ -889,18 +911,14 @@ static void map_info(int y, int x, byte *ap, char *cp)
/* 'Sane' terrain features */
if (feat != FEAT_SHOP)
{
- /* Normal char */
- c = f_ptr->x_char;
-
- /* Normal attr */
- a = f_ptr->x_attr;
+ std::tie(c, a) = feature_fn(f_ptr);
}
/* Mega-Hack 1 -- Building don't conform to f_info */
else
{
- c = st_info[c_ptr->special].x_char;
- a = st_info[c_ptr->special].x_attr;
+ std::tie(c, a) =
+ store_fn(&st_info[c_ptr->special]);
}
/* Mega-Hack 2 -- stair to dungeon branch are purple */
@@ -910,12 +928,12 @@ static void map_info(int y, int x, byte *ap, char *cp)
}
/**** Step 2 -- Apply special random effects ****/
- if (!options->avoid_other && !options->avoid_shimmer)
+ if (apply_effects)
{
/* Special terrain effect */
- if (c_ptr->effect)
+ if (auto effect_idx = c_ptr->maybe_effect)
{
- a = spell_color(effects[c_ptr->effect].type);
+ a = spell_color(lasting_effects[*effect_idx].type);
}
/* Multi-hued attr */
@@ -941,7 +959,7 @@ static void map_info(int y, int x, byte *ap, char *cp)
/* view_special_lite: lighting effects for boring features */
if (options->view_special_lite &&
- ((f_ptr->flags & (FF_FLOOR | FF_REMEMBER)) == FF_FLOOR))
+ ((f_ptr->flags & (FF_FLOOR | FF_REMEMBER)) == FF_FLOOR))
{
if (!p_ptr->wild_mode)
{
@@ -981,7 +999,7 @@ static void map_info(int y, int x, byte *ap, char *cp)
/* view_granite_lite: lighting effects for walls and doors */
else if (options->view_granite_lite &&
- (f_ptr->flags & (FF_NO_VISION | FF_DOOR)))
+ (f_ptr->flags & (FF_NO_VISION | FF_DOOR)))
{
if (!p_ptr->wild_mode)
{
@@ -1017,13 +1035,8 @@ static void map_info(int y, int x, byte *ap, char *cp)
else
{
/* Access darkness */
- f_ptr = &f_info[FEAT_NONE];
-
- /* Normal attr */
- a = f_ptr->x_attr;
-
- /* Normal char */
- c = f_ptr->x_char;
+ std::tie(c, a) =
+ feature_fn(&f_info[FEAT_NONE]);
}
/*
@@ -1040,10 +1053,15 @@ static void map_info(int y, int x, byte *ap, char *cp)
/* Save the info */
*ap = a;
*cp = c;
+}
- /**** Layer 2 -- Objects ****/
-
+static void map_info_layer2(
+ cave_type const *c_ptr,
+ std::tuple<char, byte> object_fn(object_type const *),
+ char *cp,
+ byte *ap)
+{
for (auto const o_idx: c_ptr->o_idxs)
{
/* Acquire object */
@@ -1052,33 +1070,42 @@ static void map_info(int y, int x, byte *ap, char *cp)
/* Memorized objects */
if (o_ptr->marked)
{
- /* Normal char */
- *cp = object_char(o_ptr);
-
- /* Normal attr */
- *ap = object_attr(o_ptr);
+ /* Normal char + attr */
+ std::tie(*cp, *ap) = object_fn(o_ptr);
/* Multi-hued attr */
- if (!options->avoid_other && (k_info[o_ptr->k_idx].flags & TR_ATTR_MULTI))
+ if (!options->avoid_other && (o_ptr->k_ptr->flags & TR_ATTR_MULTI))
{
*ap = get_shimmer_color();
}
/* Hack -- hallucination */
- if (p_ptr->image) image_object(ap, cp);
+ if (p_ptr->image)
+ {
+ image_object(ap, cp);
+ }
/* Done */
break;
}
}
+}
- /**** Layer 3 -- Handle monsters ****/
+static void map_info_layer3(
+ cave_type const *c_ptr,
+ std::tuple<char, byte> object_fn(object_type const *),
+ std::tuple<char, byte> race_fn(std::shared_ptr<monster_race const>),
+ char *cp,
+ byte *ap)
+{
+ char c;
+ byte a;
if (c_ptr->m_idx)
{
monster_type *m_ptr = &m_list[c_ptr->m_idx];
- auto const r_ptr = m_ptr->race();
+ auto r_ptr = m_ptr->race();
if (r_ptr->flags & RF_MIMIC)
{
@@ -1089,13 +1116,11 @@ static void map_info(int y, int x, byte *ap, char *cp)
if (o_ptr->marked)
{
/* Normal char */
- *cp = object_char(o_ptr);
-
- /* Normal attr */
- *ap = object_attr(o_ptr);
+ std::tie(*cp, *ap) =
+ object_fn(o_ptr);
/* Multi-hued attr */
- if (!options->avoid_other && (k_info[o_ptr->k_idx].flags & TR_ATTR_MULTI))
+ if (!options->avoid_other && o_ptr->k_ptr && (o_ptr->k_ptr->flags & TR_ATTR_MULTI))
{
*ap = get_shimmer_color();
}
@@ -1110,8 +1135,8 @@ static void map_info(int y, int x, byte *ap, char *cp)
if (m_ptr->ml)
{
/* Desired attr/char */
- c = r_ptr->x_char;
- a = r_ptr->x_attr;
+ std::tie(c, a) =
+ race_fn(r_ptr);
/* Ignore weird codes */
if (options->avoid_other)
@@ -1195,28 +1220,38 @@ static void map_info(int y, int x, byte *ap, char *cp)
}
}
}
+}
+
+
+static void map_info_layer4(
+ int y,
+ int x,
+ std::tuple<char, byte> race_fn(monster_race const *),
+ bool player_char_health,
+ char *cp,
+ byte *ap)
+{
+ auto const &r_info = game->edit_data.r_info;
+
+ char c;
+ byte a;
- /* Handle "player" */
if ((y == p_ptr->py) && (x == p_ptr->px) &&
- (!p_ptr->invis || p_ptr->see_inv))
+ (!p_ptr->invis || p_ptr->see_inv))
{
auto r_ptr = &r_info[p_ptr->body_monster];
- /* Get the "player" attr */
+ /* Get the "player" char + attr */
+ std::tie(c, a) =
+ race_fn(r_ptr);
+
if (!options->avoid_other && (r_ptr->flags & RF_ATTR_MULTI))
{
a = get_shimmer_color();
}
- else
- {
- a = r_ptr->x_attr;
- }
-
- /* Get the "player" char */
- c = r_ptr->x_char;
/* Show player health char instead? */
- if (options->player_char_health)
+ if (player_char_health)
{
int percent = p_ptr->chp * 10 / p_ptr->mhp;
@@ -1230,385 +1265,112 @@ static void map_info(int y, int x, byte *ap, char *cp)
/* Save the info */
*ap = a;
*cp = c;
-
}
}
-/*
- * Special version of map_info, for use by HTML converter
- * to obtain pure-ASCII image of dungeon map
- */
-void map_info_default(int y, int x, byte *ap, char *cp)
+static void map_info(int y, int x, byte *ap, char *cp)
{
- auto const &st_info = game->edit_data.st_info;
- auto const &r_info = game->edit_data.r_info;
- auto const &f_info = game->edit_data.f_info;
- auto const &k_info = game->edit_data.k_info;
-
- byte a;
-
- byte c;
-
- /* Shorthand */
- auto const avoid_other = options->avoid_other;
+ auto c_ptr = &cave[y][x];
- /**** Preparation ****/
-
- /* Access the grid */
- auto const c_ptr = &cave[y][x];
-
-
- /* Cache some frequently used values */
-
- /* Grid info */
- auto info = c_ptr->info;
-
- /* Feature code */
- auto const feat = c_ptr->mimic
- ? c_ptr->mimic
- : f_info[c_ptr->feat].mimic;
-
- /* Access floor */
- feature_type const *f_ptr = &f_info[feat];
-
-
- /**** Layer 1 -- Terrain feature ****/
-
- /* Only memorised or visible grids are displayed */
- if (info & (CAVE_MARK | CAVE_SEEN))
+ auto feature_fn = [](auto f_ptr)
{
- /**** Step 1 -- Retrieve base attr/char ****/
-
- /* 'Sane' terrain features */
- if (feat != FEAT_SHOP)
- {
- /* Default char */
- c = f_ptr->d_char;
-
- /* Default attr */
- a = f_ptr->d_attr;
- }
-
- /* Mega-Hack 1 -- Building don't conform to f_info */
- else
- {
- c = st_info[c_ptr->special].d_char;
- a = st_info[c_ptr->special].d_attr;
- }
-
- /* Mega-Hack 2 -- stair to dungeon branch are purple */
- if (c_ptr->special &&
- ((feat == FEAT_MORE) || (feat == FEAT_LESS)))
- {
- a = TERM_VIOLET;
- }
-
- /**** Step 2 -- Apply special random effects ****/
- if (!avoid_other)
- {
- /* Special terrain effect */
- if (c_ptr->effect)
- {
- a = spell_color(effects[c_ptr->effect].type);
- }
-
- /* Multi-hued attr */
- else if (f_ptr->flags & FF_ATTR_MULTI)
- {
- a = f_ptr->shimmer[rand_int(7)];
- }
- }
-
-
- /*
- * Step 3
- *
- * Special lighting effects, if specified and applicable
- * This will never happen for
- * - any grids in the overhead map
- * - (graphics modes) terrain features without corresponding
- * "darker" tiles.
- *
- * All the if's here are flag checks, so changed order shouldn't
- * affect performance a lot, I hope...
- */
-
- /* view_special_lite: lighting effects for boring features */
- if (options->view_special_lite &&
- ((f_ptr->flags & (FF_FLOOR | FF_REMEMBER)) == FF_FLOOR))
- {
- if (!p_ptr->wild_mode)
- {
- /* Handle "seen" grids */
- if (info & (CAVE_SEEN))
- {
- /* Only lit by "torch" light */
- if (options->view_yellow_lite && !(info & (CAVE_GLOW)))
- {
- /* Use "yellow" */
- a = TERM_YELLOW;
- }
- }
-
- /* Handle "blind" */
- else if (p_ptr->blind)
- {
- /* Use darker colour */
- a = darker_attrs[a & 0xF];
- }
-
- /* Handle "dark" grids */
- else if (!(info & (CAVE_GLOW)))
- {
- /* Use darkest colour */
- a = TERM_L_DARK;
- }
-
- /* "Out-of-sight" glowing grids -- handle "view_bright_lite" */
- else if (options->view_bright_lite)
- {
- /* Use darker colour */
- a = dark_attrs[a & 0xF];
- }
- }
- }
-
- /* view_granite_lite: lighting effects for walls and doors */
- else if (options->view_granite_lite &&
- (f_ptr->flags & (FF_NO_VISION | FF_DOOR)))
- {
- if (!p_ptr->wild_mode)
- {
- /* Handle "seen" grids */
- if (info & (CAVE_SEEN))
- {
- /* Do nothing */
- }
-
- /* Handle "blind" */
- else if (p_ptr->blind)
- {
- /* Use darker colour */
- a = darker_attrs[a & 0xF];
- }
-
- /* Handle "view_bright_lite" */
- else if (options->view_bright_lite)
- {
- /* Use darker colour */
- a = dark_attrs[a & 0xF];
- }
- }
- }
- }
+ return std::make_tuple(
+ f_ptr->x_char,
+ f_ptr->x_attr);
+ };
- /* Unknown grids */
- else
+ auto store_fn = [](auto st_ptr)
{
- /* Access darkness */
- f_ptr = &f_info[FEAT_NONE];
-
- /* Default attr */
- a = f_ptr->d_attr;
-
- /* Default char */
- c = f_ptr->d_char;
- }
+ return std::make_tuple(
+ st_ptr->x_char,
+ st_ptr->x_attr);
+ };
- /*
- * Hack -- rare random hallucination
- * Because we cannot be sure which is outer dungeon walls,
- * the check for 'feat' has been removed
- */
- if (p_ptr->image && (rand_int(256) == 0))
+ auto object_fn = [](auto o_ptr)
{
- /* Hallucinate */
- image_random(ap, cp);
- }
-
- /* Save the info */
- *ap = a;
- *cp = c;
-
-
- /**** Layer 2 -- Objects ****/
+ return std::make_tuple(
+ object_char(o_ptr),
+ object_attr(o_ptr));
+ };
- for (auto const this_o_idx: c_ptr->o_idxs)
+ auto race_fn = [](auto r_ptr)
{
- /* Acquire object */
- object_type *o_ptr = &o_list[this_o_idx];
-
- /* Memorized objects */
- if (o_ptr->marked)
- {
- /* Normal char */
- *cp = object_char_default(o_ptr);
+ return std::make_tuple(
+ r_ptr->x_char,
+ r_ptr->x_attr);
+ };
- /* Normal attr */
- *ap = object_attr_default(o_ptr);
+ // Layer 1: Terrain
+ map_info_layer1(
+ c_ptr, !options->avoid_other && !options->avoid_shimmer,
+ feature_fn, store_fn, cp, ap);
- /* Multi-hued attr */
- if (!avoid_other && (k_info[o_ptr->k_idx].flags & TR_ATTR_MULTI))
- {
- *ap = get_shimmer_color();
- }
+ // Layer 2: Objects
+ map_info_layer2(c_ptr, object_fn, cp, ap);
- /* Hack -- hallucination */
- if (p_ptr->image) image_object(ap, cp);
+ // Layer 3: Monsters
+ map_info_layer3(
+ c_ptr, object_fn, race_fn, cp, ap);
- /* Done */
- break;
- }
- }
+ // Layer 4: Player
+ map_info_layer4(
+ y, x, race_fn, options->player_char_health, cp, ap);
+}
- /**** Layer 3 -- Handle monsters ****/
+/*
+ * Special version of map_info, for use by HTML converter
+ * to obtain pure-ASCII image of dungeon map
+ */
+void map_info_default(int y, int x, byte *ap, char *cp)
+{
+ auto c_ptr = &cave[y][x];
- if (c_ptr->m_idx)
+ auto feature_fn = [](auto f_ptr)
{
- monster_type *m_ptr = &m_list[c_ptr->m_idx];
- auto const r_ptr = m_ptr->race();
-
- if (r_ptr->flags & RF_MIMIC)
- {
- /* Acquire object being mimicked */
- object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()];
-
- /* Memorized objects */
- if (o_ptr->marked)
- {
- /* Normal char */
- *cp = object_char_default(o_ptr);
-
- /* Normal attr */
- *ap = object_attr_default(o_ptr);
-
- /* Multi-hued attr */
- if (!avoid_other && (k_info[o_ptr->k_idx].flags & TR_ATTR_MULTI))
- {
- *ap = get_shimmer_color();
- }
-
- /* Hack -- hallucination */
- if (p_ptr->image) image_object(ap, cp);
- }
- }
- else
- {
- /* Visible monster */
- if (m_ptr->ml)
- {
- /* Default attr/char */
- c = r_ptr->d_char;
- a = r_ptr->d_attr;
-
- /* Ignore weird codes */
- if (avoid_other)
- {
- /* Use char */
- *cp = c;
-
- /* Use attr */
- *ap = a;
- }
-
- /* Multi-hued monster */
- else if (r_ptr->flags & RF_ATTR_MULTI)
- {
- /* Is it a shapechanger? */
- if (r_ptr->flags & RF_SHAPECHANGER)
- {
- image_random(ap, cp);
- }
- else
- *cp = c;
-
- /* Multi-hued attr */
- if (r_ptr->flags & RF_ATTR_ANY)
- {
- *ap = randint(15);
- }
- else
- {
- *ap = multi_hued_attr(r_ptr);
- }
- }
-
- /* Normal monster (not "clear" in any way) */
- else if (!(r_ptr->flags & (RF_ATTR_CLEAR | RF_CHAR_CLEAR)))
- {
- /* Use char */
- *cp = c;
-
- /* Use attr */
- *ap = a;
- }
-
- /* Hack -- Bizarre grid under monster */
- else if ((*ap & 0x80) || (*cp & 0x80))
- {
- /* Use char */
- *cp = c;
-
- /* Use attr */
- *ap = a;
- }
-
- /* Normal */
- else
- {
- /* Normal (non-clear char) monster */
- if (!(r_ptr->flags & RF_CHAR_CLEAR))
- {
- /* Normal char */
- *cp = c;
- }
-
- /* Normal (non-clear attr) monster */
- else if (!(r_ptr->flags & RF_ATTR_CLEAR))
- {
- /* Normal attr */
- *ap = a;
- }
- }
+ return std::make_tuple(
+ f_ptr->d_char,
+ f_ptr->d_attr);
+ };
- /* Hack -- hallucination */
- if (p_ptr->image)
- {
- /* Hallucinatory monster */
- image_monster(ap, cp);
- }
- }
- }
- }
+ auto store_fn = [](auto st_ptr)
+ {
+ return std::make_tuple(
+ st_ptr->d_char,
+ st_ptr->d_attr);
+ };
+ auto object_fn = [](auto o_ptr)
+ {
+ return std::make_tuple(
+ object_char_default(o_ptr),
+ object_attr_default(o_ptr));
+ };
- /* Handle "player" */
- if ((y == p_ptr->py) && (x == p_ptr->px) &&
- (!p_ptr->invis ||
- (p_ptr->invis && p_ptr->see_inv)))
+ auto race_fn = [](auto r_ptr)
{
- auto r_ptr = &r_info[p_ptr->body_monster];
+ return std::make_tuple(
+ r_ptr->d_char,
+ r_ptr->d_attr);
+ };
- /* Get the "player" attr */
- if (!avoid_other && (r_ptr->flags & RF_ATTR_MULTI))
- {
- a = get_shimmer_color();
- }
- else
- {
- a = r_ptr->d_attr;
- }
+ // Layer 1: Terrain
+ map_info_layer1(
+ c_ptr, !options->avoid_other,
+ feature_fn, store_fn, cp, ap);
- /* Get the "player" char */
- c = r_ptr->d_char;
+ // Layer 2: Objects
+ map_info_layer2(
+ c_ptr, object_fn, cp, ap);
- /* Save the info */
- *ap = a;
- *cp = c;
+ // Layer 3: Monsters
+ map_info_layer3(
+ c_ptr, object_fn, race_fn, cp, ap);
- }
+ // Layer 4: Player */
+ map_info_layer4(
+ y, x, race_fn, false, cp, ap);
}
@@ -1709,7 +1471,7 @@ void note_spot(int y, int x)
object_type *o_ptr = &o_list[this_o_idx];
/* Memorize objects */
- o_ptr->marked = TRUE;
+ o_ptr->marked = true;
}
if (c_ptr->m_idx)
@@ -1720,7 +1482,7 @@ void note_spot(int y, int x)
if (r_ptr->flags & RF_MIMIC)
{
object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()];
- o_ptr->marked = TRUE;
+ o_ptr->marked = true;
}
}
@@ -1783,38 +1545,30 @@ void lite_spot(int y, int x)
*/
void prt_map()
{
- int x, y;
-
- int v;
-
/* Access the cursor state */
- Term_get_cursor(&v);
-
- /* Hide the cursor */
- Term_set_cursor(0);
+ Term_with_saved_cursor_visbility([] {
+ /* Hide the cursor */
+ Term_hide_cursor();
- /* Dump the map */
- for (y = panel_row_min; y <= panel_row_max; y++)
- {
- /* Scan the columns of row "y" */
- for (x = panel_col_min; x <= panel_col_max; x++)
+ /* Dump the map */
+ for (int y = panel_row_min; y <= panel_row_max; y++)
{
- byte a;
- char c;
+ for (int x = panel_col_min; x <= panel_col_max; x++)
+ {
+ byte a;
+ char c;
- /* Determine what is there */
- map_info(y, x, &a, &c);
+ /* Determine what is there */
+ map_info(y, x, &a, &c);
- /* Efficiency -- Redraw that grid of the map */
- Term_queue_char(panel_col_of(x), y - panel_row_prt, a, c);
+ /* Efficiency -- Redraw that grid of the map */
+ Term_queue_char(panel_col_of(x), y - panel_row_prt, a, c);
+ }
}
- }
-
- /* Display player */
- lite_spot(p_ptr->py, p_ptr->px);
- /* Restore the cursor */
- Term_set_cursor(v);
+ /* Display player */
+ lite_spot(p_ptr->py, p_ptr->px);
+ });
}
@@ -1917,7 +1671,7 @@ static byte priority(byte a, char c)
int i, p0, p1;
/* Scan the table */
- for (i = 0; TRUE; i++)
+ for (i = 0; true; i++)
{
/* Priority level */
p1 = priority_table[i][1];
@@ -1990,8 +1744,8 @@ void display_map(int *cy, int *cx)
auto const old_view_granite_lite = options->view_granite_lite;
/* Disable lighting effects */
- options->view_special_lite = FALSE;
- options->view_granite_lite = FALSE;
+ options->view_special_lite = false;
+ options->view_granite_lite = false;
/* Set up initial maps */
@@ -2106,11 +1860,8 @@ void do_cmd_view_map()
/* Retrive current screen size */
Term_get_size(&wid, &hgt);
- /* Enter "icky" mode */
- character_icky = TRUE;
-
/* Save the screen */
- Term_save();
+ screen_save_no_flush();
/* Note */
prt("Please wait...", 0, 0);
@@ -2128,16 +1879,13 @@ void do_cmd_view_map()
put_str("Hit any key to continue", hgt - 1, (wid - COL_MAP) / 2);
/* Hilite the player */
- move_cursor(cy, cx);
+ Term_gotoxy(cx, cy);
/* Get any key */
inkey();
/* Restore the screen */
- Term_load();
-
- /* Leave "icky" mode */
- character_icky = FALSE;
+ screen_load_no_flush();
}
@@ -3485,7 +3233,7 @@ void update_mon_lite()
cave_type *c_ptr;
u16b info;
- bool_ invis;
+ bool invis;
s16b fast_lite_n = lite_n;
s16b fast_temp_n;
@@ -3649,7 +3397,7 @@ void update_mon_lite()
if (player_has_los_bold(y, x) && c_ptr->m_idx)
{
/* Hide the monster */
- update_mon(c_ptr->m_idx, FALSE);
+ update_mon(c_ptr->m_idx, false);
}
else
{
@@ -3687,7 +3435,7 @@ void update_mon_lite()
if (c_ptr->m_idx)
{
/* Show it */
- update_mon(c_ptr->m_idx, FALSE);
+ update_mon(c_ptr->m_idx, false);
}
else
{
@@ -3930,13 +3678,13 @@ void wiz_lite()
object_type *o_ptr = &o_list[i];
/* Skip dead objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr) continue;
/* Skip held objects */
if (o_ptr->held_m_idx) continue;
/* Memorize */
- o_ptr->marked = TRUE;
+ o_ptr->marked = true;
}
/* Scan all normal grids */
@@ -3955,7 +3703,7 @@ void wiz_lite()
if (r_ptr->flags & RF_MIMIC)
{
object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()];
- o_ptr->marked = TRUE;
+ o_ptr->marked = true;
}
}
@@ -4041,13 +3789,13 @@ void wiz_dark()
object_type *o_ptr = &o_list[i];
/* Skip dead objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr) continue;
/* Skip held objects */
if (o_ptr->held_m_idx) continue;
/* Forget the object */
- o_ptr->marked = FALSE;
+ o_ptr->marked = false;
}
/* Fully update the visuals */
@@ -4202,15 +3950,14 @@ void mmove2(int *y, int *x, int y1, int x1, int y2, int x2)
*
* This is slightly (but significantly) different from "los(y1,x1,y2,x2)".
*/
-bool_ projectable(int y1, int x1, int y2, int x2)
+bool projectable(int y1, int x1, int y2, int x2)
{
- int dist, y, x;
-
/* Start at the initial location */
- y = y1, x = x1;
+ int y = y1;
+ int x = x1;
/* See "project()" */
- for (dist = 0; dist <= MAX_RANGE; dist++)
+ for (int dist = 0; dist <= MAX_RANGE; dist++)
{
/* Check for arrival at "final target" */
/*
@@ -4219,18 +3966,23 @@ bool_ projectable(int y1, int x1, int y2, int x2)
* lets monsters shoot a the player if s/he is
* visible but in a wall
*/
- if ((x == x2) && (y == y2)) return (TRUE);
+ if ((x == x2) && (y == y2))
+ {
+ return true;
+ }
/* Never pass through walls */
- if (dist && (!cave_sight_bold(y, x) || !cave_floor_bold(y, x))) break;
+ if (dist && (!cave_sight_bold(y, x) || !cave_floor_bold(y, x)))
+ {
+ break;
+ }
/* Calculate the new location */
mmove2(&y, &x, y1, x1, y2, x2);
}
-
/* Assume obstruction */
- return (FALSE);
+ return false;
}
@@ -4406,6 +4158,8 @@ void disturb_on_other()
*/
static int random_quest_number()
{
+ auto const &dungeon_flags = game->dungeon_flags;
+
if ((dun_level >= 1) && (dun_level < MAX_RANDOM_QUEST) &&
(dungeon_flags & DF_PRINCIPAL) &&
(random_quests[dun_level].type) &&
@@ -4439,33 +4193,30 @@ int is_quest(int level)
}
-/*
- * handle spell effects
+/**
+ * Create a new lasting effect.
*/
-int effect_pop()
+boost::optional<s16b> new_effect(int type, int dam, int time, int cy, int cx, int rad, s32b flags)
{
- int i;
+ auto &lasting_effects = game->lasting_effects;
- for (i = 1; i < MAX_EFFECTS; i++)
- if (!effects[i].time)
- return i;
- return -1;
-}
-
-int new_effect(int type, int dam, int time, int cy, int cx, int rad, s32b flags)
-{
- int i;
-
- if ((i = effect_pop()) == -1) return -1;
+ // Limit to 128 effects at most.
+ if (lasting_effects.size() >= 128)
+ {
+ return boost::none;
+ }
- effects[i].type = type;
- effects[i].dam = dam;
- effects[i].time = time;
- effects[i].flags = flags;
- effects[i].cx = cx;
- effects[i].cy = cy;
- effects[i].rad = rad;
- return i;
+ effect_type effect;
+ effect.type = type;
+ effect.dam = dam;
+ effect.time = time;
+ effect.flags = flags;
+ effect.cx = cx;
+ effect.cy = cy;
+ effect.rad = rad;
+
+ lasting_effects.push_back(effect);
+ return lasting_effects.size() - 1;
}
/**
diff --git a/src/cave.hpp b/src/cave.hpp
index ce1631a1..48ec829a 100644
--- a/src/cave.hpp
+++ b/src/cave.hpp
@@ -1,13 +1,15 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "cave_type_fwd.hpp"
#include "object_type_fwd.hpp"
+#include <boost/optional.hpp>
+
int distance(int y1, int x1, int y2, int x2);
-bool_ los(int y1, int x1, int y2, int x2);
-bool_ cave_valid_bold(int y, int x);
-bool_ no_lite();
+bool los(int y1, int x1, int y2, int x2);
+bool cave_valid_bold(int y, int x);
+bool no_lite();
void map_info_default(int y, int x, byte *ap, char *cp);
void move_cursor_relative(int row, int col);
void print_rel(char c, byte a, int y, int x);
@@ -31,7 +33,7 @@ void place_floor(int y, int x);
void place_floor_convert_glass(int y, int x);
void place_filler(int y, int x);
void mmove2(int *y, int *x, int y1, int x1, int y2, int x2);
-bool_ projectable(int y1, int x1, int y2, int x2);
+bool projectable(int y1, int x1, int y2, int x2);
void scatter(int *yp, int *xp, int y, int x, int d);
void health_track(int m_idx);
void monster_race_track(int r_idx, int ego);
@@ -40,7 +42,7 @@ void disturb();
void disturb_on_state();
void disturb_on_other();
int is_quest(int level);
-int new_effect(int type, int dam, int time, int cy, int cx, int rad, s32b flags);
+boost::optional<s16b> new_effect(int type, int dam, int time, int cy, int cx, int rad, s32b flags);
bool cave_floor_bold(int y, int x);
bool cave_floor_grid(cave_type const *c);
bool cave_plain_floor_bold(int y, int x);
diff --git a/src/cave_type.hpp b/src/cave_type.hpp
index 08e6002f..3f630ee1 100644
--- a/src/cave_type.hpp
+++ b/src/cave_type.hpp
@@ -1,7 +1,8 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
+#include <boost/optional.hpp>
#include <cassert>
#include <vector>
@@ -50,7 +51,7 @@ struct cave_type
byte cost = 0; /* Hack -- cost of flowing */
byte when = 0; /* Hack -- when cost was computed */
- s16b effect = 0; /* The lasting effects */
+ boost::optional<s16b> maybe_effect { }; /* The lasting effects */
/**
* @brief wipe the object's state
diff --git a/src/cli_comm.hpp b/src/cli_comm.hpp
index 6ae53edc..c83c5a95 100644
--- a/src/cli_comm.hpp
+++ b/src/cli_comm.hpp
@@ -1,13 +1,13 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* A structure for CLI commands.
*/
struct cli_comm
{
- cptr comm; /* Extended name of the command. */
- cptr descrip; /* Description of the command. */
+ const char *comm; /* Extended name of the command. */
+ const char *descrip; /* Description of the command. */
s16b key; /* Key to convert command to. */
};
diff --git a/src/cmd1.cc b/src/cmd1.cc
index 13edf0ff..8256f8fd 100644
--- a/src/cmd1.cc
+++ b/src/cmd1.cc
@@ -16,6 +16,7 @@
#include "feature_flag.hpp"
#include "feature_type.hpp"
#include "files.hpp"
+#include "format_ext.hpp"
#include "game.hpp"
#include "gods.hpp"
#include "hooks.hpp"
@@ -42,14 +43,17 @@
#include "spells3.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "wild.hpp"
#include "xtra1.hpp"
#include "xtra2.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
+#include <boost/algorithm/string/predicate.hpp>
+
+using boost::algorithm::equals;
+
#define MAX_VAMPIRIC_DRAIN 100
@@ -57,28 +61,31 @@
* Determine if the player "hits" a monster (normal combat).
* Note -- Always miss 5%, always hit 5%, otherwise random.
*/
-bool_ test_hit_fire(int chance, int ac, int vis)
+bool test_hit_fire(int chance, int ac, int vis)
{
- int k;
-
-
/* Percentile dice */
- k = rand_int(100);
+ int const k = rand_int(100);
/* Hack -- Instant miss or hit */
if (k < 10) return (k < 5);
/* Never hit */
- if (chance <= 0) return (FALSE);
+ if (chance <= 0)
+ {
+ return false;
+ }
/* Invisible monsters are harder to hit */
if (!vis) chance = (chance + 1) / 2;
/* Power competes against armor */
- if (rand_int(chance + luck( -10, 10)) < (ac * 3 / 4)) return (FALSE);
+ if (rand_int(chance + luck( -10, 10)) < (ac * 3 / 4))
+ {
+ return false;
+ }
/* Assume hit */
- return (TRUE);
+ return true;
}
@@ -88,28 +95,31 @@ bool_ test_hit_fire(int chance, int ac, int vis)
*
* Note -- Always miss 5%, always hit 5%, otherwise random.
*/
-bool_ test_hit_norm(int chance, int ac, int vis)
+bool test_hit_norm(int chance, int ac, int vis)
{
- int k;
-
-
/* Percentile dice */
- k = rand_int(100);
+ int const k = rand_int(100);
/* Hack -- Instant miss or hit */
if (k < 10) return (k < 5);
/* Wimpy attack never hits */
- if (chance <= 0) return (FALSE);
+ if (chance <= 0)
+ {
+ return false;
+ }
/* Penalize invisible targets */
if (!vis) chance = (chance + 1) / 2;
/* Power must defeat armor */
- if (rand_int(chance + luck( -10, 10)) < (ac * 3 / 4)) return (FALSE);
+ if (rand_int(chance + luck( -10, 10)) < (ac * 3 / 4))
+ {
+ return false;
+ }
/* Assume hit */
- return (TRUE);
+ return true;
}
@@ -159,11 +169,11 @@ s16b critical_shot(int weight, int plus, int dam, int skill)
*
* Factor in weapon weight, total plusses, player level.
*/
-s16b critical_norm(int weight, int plus, int dam, int weapon_tval, bool_ *done_crit)
+s16b critical_norm(int weight, int plus, int dam, int weapon_tval, bool *done_crit)
{
int i, k, num = randint(5000);
- *done_crit = FALSE;
+ *done_crit = false;
/* Extract "blow" power */
i = (weight + ((p_ptr->to_h + plus) * 5) +
@@ -181,7 +191,7 @@ s16b critical_norm(int weight, int plus, int dam, int weapon_tval, bool_ *done_c
set_tim_deadly(p_ptr->tim_deadly - 1);
msg_print("It was a *GREAT* hit!");
dam = 3 * dam + 20;
- *done_crit = TRUE;
+ *done_crit = true;
}
/* Chance */
@@ -218,7 +228,7 @@ s16b critical_norm(int weight, int plus, int dam, int weapon_tval, bool_ *done_c
msg_print("It was a *SUPERB* hit!");
dam = ((7 * dam) / 2) + 25;
}
- *done_crit = TRUE;
+ *done_crit = true;
}
return (dam);
@@ -504,8 +514,7 @@ static void touch_zap_player(monster_type *m_ptr)
* Carried monster can attack too.
* Based on monst_attack_monst.
*/
-static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
- int x, int y)
+static void carried_monster_attack(s16b m_idx, int x, int y)
{
auto const &r_info = game->edit_data.r_info;
@@ -519,7 +528,7 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
char temp[80];
- bool_ blinked = FALSE, touched = FALSE;
+ bool blinked = false, touched = false;
byte y_saver = t_ptr->fy;
@@ -527,7 +536,10 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
/* Get the carried monster */
auto o_ptr = &p_ptr->inventory[INVEN_CARRY];
- if (!o_ptr->k_idx) return;
+ if (!o_ptr->k_ptr)
+ {
+ return;
+ }
/* Get monster race of the symbiote */
auto r_ptr = &r_info[o_ptr->pval];
@@ -545,7 +557,7 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
monster_desc(t_name, t_ptr, 0);
/* Assume no blink */
- blinked = FALSE;
+ blinked = false;
if (!t_ptr->ml)
{
@@ -558,7 +570,7 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
int power = 0;
int damage = 0;
- cptr act = NULL;
+ const char *act = NULL;
/* Extract the attack infomation */
int effect = r_ptr->blow[ap_cnt].effect;
@@ -593,49 +605,49 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
case RBM_HIT:
{
act = "hits %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_TOUCH:
{
act = "touches %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_PUNCH:
{
act = "punches %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_KICK:
{
act = "kicks %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_CLAW:
{
act = "claws %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_BITE:
{
act = "bites %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_STING:
{
act = "stings %s.";
- touched = TRUE;
+ touched = true;
break;
}
@@ -648,84 +660,84 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
case RBM_BUTT:
{
act = "butts %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_CRUSH:
{
act = "crushes %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_ENGULF:
{
act = "engulfs %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_CHARGE:
{
act = "charges %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_CRAWL:
{
act = "crawls on %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_DROOL:
{
act = "drools on %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_SPIT:
{
act = "spits on %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_GAZE:
{
act = "gazes at %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_WAIL:
{
act = "wails at %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_SPORE:
{
act = "releases spores at %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_XXX4:
{
act = "projects XXX4's at %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_BEG:
{
act = "begs %s for money.";
- touched = FALSE;
+ touched = false;
t_ptr->csleep = 0;
break;
}
@@ -733,7 +745,7 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
case RBM_INSULT:
{
act = "insults %s.";
- touched = FALSE;
+ touched = false;
t_ptr->csleep = 0;
break;
}
@@ -741,7 +753,7 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
case RBM_MOAN:
{
act = "moans at %s.";
- touched = FALSE;
+ touched = false;
t_ptr->csleep = 0;
break;
}
@@ -749,7 +761,7 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
case RBM_SHOW:
{
act = "sings to %s.";
- touched = FALSE;
+ touched = false;
t_ptr->csleep = 0;
break;
}
@@ -814,7 +826,7 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
case RBE_EAT_GOLD:
{
pt = damage = 0;
- if (randint(2) == 1) blinked = TRUE;
+ if (randint(2) == 1) blinked = true;
break;
}
@@ -927,7 +939,7 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
{
if (t_ptr->ml)
{
- blinked = FALSE;
+ blinked = false;
msg_format("You are suddenly very hot!");
}
project(m_idx, 0, p_ptr->py, p_ptr->px,
@@ -942,7 +954,7 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
{
if (t_ptr->ml)
{
- blinked = FALSE;
+ blinked = false;
msg_format("You get zapped!");
}
project(m_idx, 0, p_ptr->py, p_ptr->px,
@@ -997,8 +1009,7 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
* Carried monster can attack too.
* Based on monst_attack_monst.
*/
-static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
- int x, int y)
+static void incarnate_monster_attack(s16b m_idx, int x, int y)
{
auto const &r_info = game->edit_data.r_info;
@@ -1014,7 +1025,7 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
char temp[80];
- bool_ blinked = FALSE, touched = FALSE;
+ bool blinked = false, touched = false;
byte y_saver = t_ptr->fy;
@@ -1038,7 +1049,7 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
monster_desc(t_name, t_ptr, 0);
/* Assume no blink */
- blinked = FALSE;
+ blinked = false;
if (!t_ptr->ml)
{
@@ -1046,13 +1057,12 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
}
/* Scan through all four blows */
- for (ap_cnt = 0; ap_cnt < (p_ptr->num_blow > 4) ? 4 : p_ptr->num_blow;
- ap_cnt++)
+ for (ap_cnt = 0; ap_cnt < std::min<int>(p_ptr->num_blow, 4); ap_cnt++)
{
int power = 0;
int damage = 0;
- cptr act = NULL;
+ const char *act = NULL;
/* Extract the attack infomation */
int effect = r_ptr->blow[ap_cnt].effect;
@@ -1087,49 +1097,49 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
case RBM_HIT:
{
act = "hit %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_TOUCH:
{
act = "touch %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_PUNCH:
{
act = "punch %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_KICK:
{
act = "kick %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_CLAW:
{
act = "claw %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_BITE:
{
act = "bite %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_STING:
{
act = "sting %s.";
- touched = TRUE;
+ touched = true;
break;
}
@@ -1142,84 +1152,84 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
case RBM_BUTT:
{
act = "butt %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_CRUSH:
{
act = "crush %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_ENGULF:
{
act = "engulf %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_CHARGE:
{
act = "charge %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_CRAWL:
{
act = "crawl on %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_DROOL:
{
act = "drool on %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_SPIT:
{
act = "spit on %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_GAZE:
{
act = "gaze at %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_WAIL:
{
act = "wail at %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_SPORE:
{
act = "release spores at %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_XXX4:
{
act = "project XXX4's at %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_BEG:
{
act = "beg %s for money.";
- touched = FALSE;
+ touched = false;
t_ptr->csleep = 0;
break;
}
@@ -1227,7 +1237,7 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
case RBM_INSULT:
{
act = "insult %s.";
- touched = FALSE;
+ touched = false;
t_ptr->csleep = 0;
break;
}
@@ -1235,7 +1245,7 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
case RBM_MOAN:
{
act = "moan at %s.";
- touched = FALSE;
+ touched = false;
t_ptr->csleep = 0;
break;
}
@@ -1243,7 +1253,7 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
case RBM_SHOW:
{
act = "sing to %s.";
- touched = FALSE;
+ touched = false;
t_ptr->csleep = 0;
break;
}
@@ -1305,7 +1315,7 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
case RBE_EAT_GOLD:
{
pt = damage = 0;
- if (randint(2) == 1) blinked = TRUE;
+ if (randint(2) == 1) blinked = true;
break;
}
@@ -1417,7 +1427,7 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
{
if (t_ptr->ml)
{
- blinked = FALSE;
+ blinked = false;
msg_format("You are suddenly very hot!");
}
project(m_idx, 0, p_ptr->py, p_ptr->px,
@@ -1432,7 +1442,7 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
{
if (t_ptr->ml)
{
- blinked = FALSE;
+ blinked = false;
msg_format("You get zapped!");
}
project(m_idx, 0, p_ptr->py, p_ptr->px,
@@ -1493,7 +1503,7 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
static void flavored_attack(int percent, char *output)
{
int insanity = (p_ptr->msane - p_ptr->csane) * 100 / p_ptr->msane;
- bool_ insane = (rand_int(100) < insanity);
+ bool insane = (rand_int(100) < insanity);
if (percent < 5)
{
@@ -1614,7 +1624,7 @@ static void py_attack_hand(int *k, monster_type *m_ptr, s32b *special)
martial_arts *blow_table = ma_blows;
int resist_stun = 0;
int max = MAX_MA;
- bool_ desc = FALSE;
+ bool desc = false;
int plev = p_ptr->lev;
if ((!p_ptr->body_monster) && (p_ptr->mimic_form == resolve_mimic_name("Bear")) &&
@@ -1686,14 +1696,14 @@ static void py_attack_hand(int *k, monster_type *m_ptr, s32b *special)
}
else if (!desc) msg_format(ma_ptr->desc, m_name);
- desc = TRUE;
+ desc = true;
}
if (ma_ptr->effect & MA_FULL_SLOW)
{
special_effect = MA_SLOW;
if (!desc) msg_format(ma_ptr->desc, m_name);
- desc = TRUE;
+ desc = true;
}
if (ma_ptr->effect & MA_SLOW)
{
@@ -1706,7 +1716,7 @@ static void py_attack_hand(int *k, monster_type *m_ptr, s32b *special)
}
else if (!desc) msg_format(ma_ptr->desc, m_name);
- desc = TRUE;
+ desc = true;
}
if (ma_ptr->effect & MA_STUN)
{
@@ -1716,7 +1726,7 @@ static void py_attack_hand(int *k, monster_type *m_ptr, s32b *special)
}
if (!desc) msg_format(ma_ptr->desc, m_name);
- desc = TRUE;
+ desc = true;
}
if (ma_ptr->effect & MA_WOUND)
{
@@ -1725,10 +1735,10 @@ static void py_attack_hand(int *k, monster_type *m_ptr, s32b *special)
*special |= SPEC_CUT;
}
if (!desc) msg_format(ma_ptr->desc, m_name);
- desc = TRUE;
+ desc = true;
}
- bool_ done_crit;
+ bool done_crit;
*k = critical_norm(plev * (randint(10)), ma_ptr->min_level, *k, -1, &done_crit);
if ((special_effect & MA_KNEE) && ((*k + p_ptr->to_d) < m_ptr->hp))
@@ -1769,13 +1779,13 @@ static void py_attack_hand(int *k, monster_type *m_ptr, s32b *special)
static void do_nazgul(int *k, int *num, int num_blow, int weap, std::shared_ptr<monster_race> r_ptr,
object_type *o_ptr)
{
- bool_ allow_shatter = TRUE;
+ bool allow_shatter = true;
/* Extract mundane-ness of the current weapon */
auto const f = object_flags(o_ptr);
/* It should be Slay Evil, Slay Undead, or *Slay Undead* */
- bool_ const mundane =
+ bool const mundane =
!(f & TR_SLAY_EVIL) &&
!(f & TR_SLAY_UNDEAD) &&
!(f & TR_KILL_UNDEAD);
@@ -1783,7 +1793,7 @@ static void do_nazgul(int *k, int *num, int num_blow, int weap, std::shared_ptr<
/* Some blades can resist shattering */
if (f & TR_RES_MORGUL)
{
- allow_shatter = FALSE;
+ allow_shatter = false;
}
/* Mega Hack -- Hitting Nazgul is REALY dangerous (ideas from Akhronath) */
@@ -1850,7 +1860,7 @@ static void do_nazgul(int *k, int *num, int num_blow, int weap, std::shared_ptr<
msg_print("Your foe calls upon your soul!");
msg_print
("You feel the Black Breath slowly draining you of life...");
- p_ptr->black_breath = TRUE;
+ p_ptr->black_breath = true;
}
}
}
@@ -1874,23 +1884,23 @@ void py_attack(int y, int x, int max_blow)
monster_type *m_ptr = &m_list[c_ptr->m_idx];
- bool_ fear = FALSE;
+ bool fear = false;
- bool_ mdeath = FALSE;
+ bool mdeath = false;
- bool_ backstab = FALSE;
+ bool backstab = false;
- bool_ vorpal_cut = FALSE;
+ bool vorpal_cut = false;
int chaos_effect = 0;
- bool_ stab_fleeing = FALSE;
+ bool stab_fleeing = false;
- bool_ do_quake = FALSE;
+ bool do_quake = false;
- bool_ done_crit = FALSE;
+ bool done_crit = false;
- bool_ drain_msg = TRUE;
+ bool drain_msg = true;
int drain_result = 0, drain_heal = 0;
@@ -1912,11 +1922,11 @@ void py_attack(int y, int x, int max_blow)
if ((m_ptr->csleep) && (m_ptr->ml))
{
/* Can't backstab creatures that we can't see, right? */
- backstab = TRUE;
+ backstab = true;
}
else if ((m_ptr->monfear) && (m_ptr->ml))
{
- stab_fleeing = TRUE;
+ stab_fleeing = true;
}
}
@@ -1979,7 +1989,7 @@ void py_attack(int y, int x, int max_blow)
(!r_info[p_ptr->body_monster].body_parts[BODY_WEAPON]) &&
!(p_ptr->melee_style == SKILL_HAND))
{
- incarnate_monster_attack(c_ptr->m_idx, &fear, &mdeath, y, x);
+ incarnate_monster_attack(c_ptr->m_idx, y, x);
}
/* Otherwise use your weapon(s) */
else
@@ -2070,9 +2080,9 @@ void py_attack(int y, int x, int max_blow)
}
if ((flags & TR_VORPAL) && (randint(6) == 1))
- vorpal_cut = TRUE;
+ vorpal_cut = true;
else
- vorpal_cut = FALSE;
+ vorpal_cut = false;
/* Should we attack with hands or not ? */
if (p_ptr->melee_style != SKILL_MASTERY)
@@ -2080,7 +2090,7 @@ void py_attack(int y, int x, int max_blow)
py_attack_hand(&k, m_ptr, &special);
}
/* Handle normal weapon */
- else if (o_ptr->k_idx)
+ else if (o_ptr->k_ptr)
{
k = damroll(o_ptr->dd, o_ptr->ds);
k = tot_dam_aux(o_ptr, k, m_ptr, &special);
@@ -2100,7 +2110,7 @@ void py_attack(int y, int x, int max_blow)
if ((p_ptr->impact && ((k > 50) || randint(7) == 1))
|| (chaos_effect == 2))
{
- do_quake = TRUE;
+ do_quake = true;
}
k = critical_norm(o_ptr->weight, o_ptr->to_h, k, o_ptr->tval, &done_crit);
@@ -2159,7 +2169,7 @@ void py_attack(int y, int x, int max_blow)
project(0, p_ptr->tim_project_rad, y, x, p_ptr->tim_project_dam, p_ptr->tim_project_gf, p_ptr->tim_project_flag | PROJECT_JUMP);
if (!c_ptr->m_idx)
{
- mdeath = TRUE;
+ mdeath = true;
break;
}
}
@@ -2190,7 +2200,7 @@ void py_attack(int y, int x, int max_blow)
{
msg_format("Oh no! Your weapon clones %^s!",
m_name);
- multiply_monster(c_ptr->m_idx, FALSE, TRUE);
+ multiply_monster(c_ptr->m_idx, false, true);
}
/* Apply the player damage bonuses */
@@ -2223,7 +2233,7 @@ void py_attack(int y, int x, int max_blow)
monster_race_desc(buf, m_ptr->r_idx, m_ptr->ego);
- backstab = FALSE;
+ backstab = false;
msg_format
("You cruelly stab the helpless, sleeping %s!",
@@ -2258,7 +2268,7 @@ void py_attack(int y, int x, int max_blow)
{
energy_use = energy_use * num / num_blow;
}
- mdeath = TRUE;
+ mdeath = true;
break;
}
@@ -2309,7 +2319,7 @@ void py_attack(int y, int x, int max_blow)
msg_format
("Your weapon drains life from %s!",
m_name);
- drain_msg = FALSE;
+ drain_msg = false;
}
hp_player(drain_heal);
@@ -2324,7 +2334,7 @@ void py_attack(int y, int x, int max_blow)
/* Cancel glowing hands */
if (p_ptr->confusing)
{
- p_ptr->confusing = FALSE;
+ p_ptr->confusing = false;
msg_print("Your hands stop glowing.");
}
@@ -2374,7 +2384,7 @@ void py_attack(int y, int x, int max_blow)
/* Hack -- Get new race */
r_ptr = m_ptr->race();
- fear = FALSE;
+ fear = false;
}
else
{
@@ -2391,7 +2401,7 @@ void py_attack(int y, int x, int max_blow)
/* Player misses */
else
{
- backstab = FALSE; /* Clumsy! */
+ backstab = false; /* Clumsy! */
/* Message */
msg_format("You miss %s.", m_name);
@@ -2407,7 +2417,9 @@ void py_attack(int y, int x, int max_blow)
/* Carried monster can attack too */
if ((!mdeath) && m_list[c_ptr->m_idx].hp)
- carried_monster_attack(c_ptr->m_idx, &fear, &mdeath, y, x);
+ {
+ carried_monster_attack(c_ptr->m_idx, y, x);
+ }
/* Hack -- delay fear messages */
if (fear && m_ptr->ml)
@@ -2427,27 +2439,16 @@ void py_attack(int y, int x, int max_blow)
-bool_ player_can_enter(byte feature)
+bool player_can_enter(byte feature)
{
auto const &r_info = game->edit_data.r_info;
auto const &f_info = game->edit_data.f_info;
- bool_ pass_wall;
-
- bool_ only_wall = FALSE;
-
-
/* Player can not walk through "walls" unless in Shadow Form */
- if (p_ptr->wraith_form || (race_flags_p(PR_SEMI_WRAITH)))
- pass_wall = TRUE;
- else
- pass_wall = FALSE;
+ auto const pass_wall = (p_ptr->wraith_form || (race_flags_p(PR_SEMI_WRAITH)));
/* Wall mimicry force the player to stay in walls */
- if (p_ptr->mimic_extra & CLASS_WALL)
- {
- only_wall = TRUE;
- }
+ auto const only_wall = (p_ptr->mimic_extra & CLASS_WALL);
/* Don't let the player kill himself with one keystroke */
if (p_ptr->wild_mode)
@@ -2457,7 +2458,9 @@ bool_ player_can_enter(byte feature)
int wt = weight_limit() / 2;
if ((calc_total_weight() >= wt) && !(p_ptr->ffall))
- return (FALSE);
+ {
+ return false;
+ }
}
else if (feature == FEAT_SHAL_LAVA ||
feature == FEAT_DEEP_LAVA)
@@ -2466,7 +2469,9 @@ bool_ player_can_enter(byte feature)
p_ptr->immune_fire ||
p_ptr->oppose_fire ||
p_ptr->ffall))
- return (FALSE);
+ {
+ return false;
+ }
}
}
@@ -2477,44 +2482,60 @@ bool_ player_can_enter(byte feature)
p_ptr->has_ability(AB_TREE_WALK) ||
(p_ptr->mimic_form == resolve_mimic_name("Ent")) ||
((p_ptr->grace >= 9000) && praying_to(GOD_YAVANNA)))
- return (TRUE);
+ {
+ return true;
+ }
}
if ((p_ptr->climb) && (f_info[feature].flags & FF_CAN_CLIMB))
- return (TRUE);
+ {
+ return true;
+ }
if ((p_ptr->fly) &&
((f_info[feature].flags & FF_CAN_FLY) ||
(f_info[feature].flags & FF_CAN_LEVITATE)))
- return (TRUE);
+ {
+ return true;
+ }
else if (only_wall && (f_info[feature].flags & FF_FLOOR))
- return (FALSE);
+ {
+ return false;
+ }
else if ((p_ptr->ffall) &&
(f_info[feature].flags & FF_CAN_LEVITATE))
- return (TRUE);
+ {
+ return true;
+ }
else if ((pass_wall || only_wall) &&
(f_info[feature].flags & FF_CAN_PASS))
- return (TRUE);
+ {
+ return true;
+ }
else if (f_info[feature].flags & FF_NO_WALK)
- return (FALSE);
+ {
+ return false;
+ }
else if ((f_info[feature].flags & FF_WEB) &&
((!(r_info[p_ptr->body_monster].flags & RF_SPIDER)) && (p_ptr->mimic_form != resolve_mimic_name("Spider"))))
- return (FALSE);
+ {
+ return false;
+ }
- return (TRUE);
+ return true;
}
/*
* easy_open_door --
*
* If there is a jammed/closed/locked door at the given location,
- * then attempt to unlock/open it. Return TRUE if an attempt was
- * made (successful or not), otherwise return FALSE.
+ * then attempt to unlock/open it. Return true if an attempt was
+ * made (successful or not), otherwise return false.
*
* The code here should be nearly identical to that in
* do_cmd_open_test() and do_cmd_open_aux().
*/
-static bool_ easy_open_door(int y, int x)
+static bool easy_open_door(int y, int x)
{
auto const &r_info = game->edit_data.r_info;
@@ -2529,14 +2550,14 @@ static bool_ easy_open_door(int y, int x)
{
msg_print("You cannot open doors.");
- return (FALSE);
+ return false;
}
/* Must be a closed door */
if (!((c_ptr->feat >= FEAT_DOOR_HEAD) && (c_ptr->feat <= FEAT_DOOR_TAIL)))
{
/* Nope */
- return (FALSE);
+ return false;
}
/* Jammed door */
@@ -2603,7 +2624,7 @@ static bool_ easy_open_door(int y, int x)
}
/* Result */
- return (TRUE);
+ return true;
}
/*
@@ -2631,7 +2652,7 @@ void move_player_aux(int dir, int do_pickup, int run)
char m_name[80];
- bool_ oktomove = TRUE;
+ bool oktomove = true;
/* Hack - random movement */
@@ -2706,7 +2727,7 @@ void move_player_aux(int dir, int do_pickup, int run)
p_ptr->wilderness_x--;
p_ptr->oldpy = cur_hgt - 2;
p_ptr->oldpx = cur_wid - 2;
- ambush_flag = FALSE;
+ ambush_flag = false;
}
else if ((y == 0) && (x == MAX_WID - 1))
@@ -2715,7 +2736,7 @@ void move_player_aux(int dir, int do_pickup, int run)
p_ptr->wilderness_x++;
p_ptr->oldpy = cur_hgt - 2;
p_ptr->oldpx = 1;
- ambush_flag = FALSE;
+ ambush_flag = false;
}
else if ((y == MAX_HGT - 1) && (x == 0))
@@ -2724,7 +2745,7 @@ void move_player_aux(int dir, int do_pickup, int run)
p_ptr->wilderness_x--;
p_ptr->oldpy = 1;
p_ptr->oldpx = cur_wid - 2;
- ambush_flag = FALSE;
+ ambush_flag = false;
}
else if ((y == MAX_HGT - 1) && (x == MAX_WID - 1))
@@ -2733,7 +2754,7 @@ void move_player_aux(int dir, int do_pickup, int run)
p_ptr->wilderness_x++;
p_ptr->oldpy = 1;
p_ptr->oldpx = 1;
- ambush_flag = FALSE;
+ ambush_flag = false;
}
else if (y == 0)
@@ -2741,7 +2762,7 @@ void move_player_aux(int dir, int do_pickup, int run)
p_ptr->wilderness_y--;
p_ptr->oldpy = cur_hgt - 2;
p_ptr->oldpx = x;
- ambush_flag = FALSE;
+ ambush_flag = false;
}
else if (y == cur_hgt - 1)
@@ -2749,7 +2770,7 @@ void move_player_aux(int dir, int do_pickup, int run)
p_ptr->wilderness_y++;
p_ptr->oldpy = 1;
p_ptr->oldpx = x;
- ambush_flag = FALSE;
+ ambush_flag = false;
}
else if (x == 0)
@@ -2757,7 +2778,7 @@ void move_player_aux(int dir, int do_pickup, int run)
p_ptr->wilderness_x--;
p_ptr->oldpx = cur_wid - 2;
p_ptr->oldpy = y;
- ambush_flag = FALSE;
+ ambush_flag = false;
}
else if (x == cur_wid - 1)
@@ -2765,10 +2786,10 @@ void move_player_aux(int dir, int do_pickup, int run)
p_ptr->wilderness_x++;
p_ptr->oldpx = 1;
p_ptr->oldpy = y;
- ambush_flag = FALSE;
+ ambush_flag = false;
}
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
return;
}
@@ -2784,7 +2805,7 @@ void move_player_aux(int dir, int do_pickup, int run)
if (p_ptr->dripping_tread > 0)
{
- geomancy_random_floor(y, x, FALSE);
+ geomancy_random_floor(y, x, false);
p_ptr->dripping_tread -= 1;
if (p_ptr->dripping_tread == 0)
{
@@ -2833,13 +2854,13 @@ void move_player_aux(int dir, int do_pickup, int run)
m_ptr->fx = p_ptr->px;
cave[p_ptr->py][p_ptr->px].m_idx = c_ptr->m_idx;
c_ptr->m_idx = 0;
- update_mon(cave[p_ptr->py][p_ptr->px].m_idx, TRUE);
+ update_mon(cave[p_ptr->py][p_ptr->px].m_idx, true);
}
else
{
msg_format("%^s is in your way!", m_name);
energy_use = 0;
- oktomove = FALSE;
+ oktomove = false;
}
/* now continue on to 'movement' */
@@ -2847,7 +2868,7 @@ void move_player_aux(int dir, int do_pickup, int run)
else
{
py_attack(y, x, -1);
- oktomove = FALSE;
+ oktomove = false;
}
}
@@ -2855,20 +2876,20 @@ void move_player_aux(int dir, int do_pickup, int run)
{
msg_print("You can't cross the chasm.");
running = 0;
- oktomove = FALSE;
+ oktomove = false;
}
/* Player can't enter ? soo bad for him/her ... */
else if (!player_can_enter(c_ptr->feat))
{
- oktomove = FALSE;
+ oktomove = false;
/* Disturb the player */
disturb();
if (p_ptr->prob_travel)
{
- if (passwall(tmp, TRUE)) return;
+ if (passwall(tmp, true)) return;
}
/* Notice things in the dark */
@@ -3018,13 +3039,17 @@ void move_player_aux(int dir, int do_pickup, int run)
else if (cave[y][x].feat >= FEAT_ALTAR_HEAD &&
cave[y][x].feat <= FEAT_ALTAR_TAIL)
{
- cptr name = f_info[cave[y][x].feat].name;
- cptr pref = (is_a_vowel(name[0])) ? "an" : "a";
+ auto msg = fmt::format(
+ "You see {}.",
+ singular_prefix(f_info[cave[y][x].feat].name));
- msg_format("You see %s %s.", pref, name);
+ msg_print(msg);
/* Flush message while running */
- if (running) msg_print(NULL);
+ if (running)
+ {
+ msg_print(nullptr);
+ }
}
/* Execute the inscription */
@@ -3051,7 +3076,7 @@ void move_player_aux(int dir, int do_pickup, int run)
reveal_wilderness_around_player(p_ptr->py, p_ptr->px, 0, WILDERNESS_SEE_RADIUS);
/* Walking the wild isnt meaningfull */
- p_ptr->did_nothing = TRUE;
+ p_ptr->did_nothing = true;
}
}
@@ -3076,26 +3101,26 @@ static int see_obstacle_grid(cave_type *c_ptr)
case FEAT_DEEP_WATER:
case FEAT_ICE:
{
- if (p_ptr->ffall || p_ptr->fly) return (FALSE);
+ if (p_ptr->ffall || p_ptr->fly) return false;
}
/* Require immunity */
case FEAT_DEEP_LAVA:
case FEAT_SHAL_LAVA:
{
- if (p_ptr->invuln || p_ptr->immune_fire) return (FALSE);
+ if (p_ptr->invuln || p_ptr->immune_fire) return false;
}
}
/* "Safe" floor grids aren't obstacles */
- if (f_info[c_ptr->feat].flags & FF_CAN_RUN) return (FALSE);
+ if (f_info[c_ptr->feat].flags & FF_CAN_RUN) return false;
/* Must be known to the player */
- if (!(c_ptr->info & (CAVE_MARK))) return (FALSE);
+ if (!(c_ptr->info & (CAVE_MARK))) return false;
/* Default */
- return (TRUE);
+ return true;
}
@@ -3109,7 +3134,7 @@ static int see_obstacle(int dir, int y, int x)
x += ddx[dir];
/* Illegal grids are not known walls */
- if (!in_bounds2(y, x)) return (FALSE);
+ if (!in_bounds2(y, x)) return false;
/* Analyse the grid */
return (see_obstacle_grid(&cave[y][x]));
@@ -3126,19 +3151,19 @@ static int see_nothing(int dir, int y, int x)
x += ddx[dir];
/* Illegal grids are unknown */
- if (!in_bounds2(y, x)) return (TRUE);
+ if (!in_bounds2(y, x)) return true;
/* Memorized grids are always known */
- if (cave[y][x].info & (CAVE_MARK)) return (FALSE);
+ if (cave[y][x].info & (CAVE_MARK)) return false;
/* Non-floor grids are unknown */
- if (!cave_floor_bold(y, x)) return (TRUE);
+ if (!cave_floor_bold(y, x)) return true;
/* Viewable door/wall grids are known */
- if (player_can_see_bold(y, x)) return (FALSE);
+ if (player_can_see_bold(y, x)) return false;
/* Default */
- return (TRUE);
+ return true;
}
@@ -3299,13 +3324,13 @@ static byte find_prevdir;
/*
* We are looking for open area
*/
-static bool_ find_openarea;
+static bool find_openarea;
/*
* We are looking for a break
*/
-static bool_ find_breakright;
-static bool_ find_breakleft;
+static bool find_breakright;
+static bool find_breakleft;
@@ -3337,14 +3362,14 @@ static void run_init(int dir)
find_prevdir = dir;
/* Assume looking for open area */
- find_openarea = TRUE;
+ find_openarea = true;
/* Assume not looking for breaks */
- find_breakright = find_breakleft = FALSE;
+ find_breakright = find_breakleft = false;
/* Assume no nearby walls */
- deepleft = deepright = FALSE;
- shortright = shortleft = FALSE;
+ deepleft = deepright = false;
+ shortright = shortleft = false;
/* Find the destination grid */
row = p_ptr->py + ddy[dir];
@@ -3356,32 +3381,32 @@ static void run_init(int dir)
/* Check for walls */
if (see_obstacle(cycle[i + 1], p_ptr->py, p_ptr->px))
{
- find_breakleft = TRUE;
- shortleft = TRUE;
+ find_breakleft = true;
+ shortleft = true;
}
else if (see_obstacle(cycle[i + 1], row, col))
{
- find_breakleft = TRUE;
- deepleft = TRUE;
+ find_breakleft = true;
+ deepleft = true;
}
/* Check for walls */
if (see_obstacle(cycle[i - 1], p_ptr->py, p_ptr->px))
{
- find_breakright = TRUE;
- shortright = TRUE;
+ find_breakright = true;
+ shortright = true;
}
else if (see_obstacle(cycle[i - 1], row, col))
{
- find_breakright = TRUE;
- deepright = TRUE;
+ find_breakright = true;
+ deepright = true;
}
/* Looking for a break */
if (find_breakleft && find_breakright)
{
/* Not looking for open area */
- find_openarea = FALSE;
+ find_openarea = false;
/* Hack -- allow angled corridor entry */
if (dir & 0x01)
@@ -3415,9 +3440,9 @@ static void run_init(int dir)
/*
* Update the current "run" path
*
- * Return TRUE if the running should be stopped
+ * Return true if the running should be stopped
*/
-static bool_ run_test()
+static bool run_test()
{
auto const &f_info = game->edit_data.f_info;
@@ -3457,7 +3482,7 @@ static bool_ run_test()
monster_type *m_ptr = &m_list[c_ptr->m_idx];
/* Visible monster */
- if (m_ptr->ml) return (TRUE);
+ if (m_ptr->ml) return true;
}
/* Visible objects abort running */
@@ -3467,17 +3492,17 @@ static bool_ run_test()
object_type * o_ptr = &o_list[o_idx];
/* Visible object */
- if (o_ptr->marked) return (TRUE);
+ if (o_ptr->marked) return true;
}
/* Assume unknown */
- inv = TRUE;
+ inv = true;
/* Check memorized grids */
if (c_ptr->info & (CAVE_MARK))
{
- bool_ notice = TRUE;
+ bool notice = true;
/*
* Examine the terrain -- conditional disturbance
@@ -3489,7 +3514,7 @@ static bool_ run_test()
case FEAT_SHAL_LAVA:
{
/* Ignore */
- if (p_ptr->invuln || p_ptr->immune_fire) notice = FALSE;
+ if (p_ptr->invuln || p_ptr->immune_fire) notice = false;
/* Done */
break;
@@ -3499,7 +3524,7 @@ static bool_ run_test()
case FEAT_ICE:
{
/* Ignore */
- if (p_ptr->ffall || p_ptr->fly) notice = FALSE;
+ if (p_ptr->ffall || p_ptr->fly) notice = false;
/* Done */
break;
@@ -3510,7 +3535,7 @@ static bool_ run_test()
case FEAT_BROKEN:
{
/* Option -- ignore */
- if (options->find_ignore_doors) notice = FALSE;
+ if (options->find_ignore_doors) notice = false;
/* Done */
break;
@@ -3536,7 +3561,7 @@ static bool_ run_test()
case FEAT_BETWEEN2:
{
/* Option -- ignore */
- if (options->find_ignore_stairs) notice = FALSE;
+ if (options->find_ignore_stairs) notice = false;
/* Done */
break;
@@ -3546,14 +3571,14 @@ static bool_ run_test()
/* Check the "don't notice running" flag */
if (f_info[c_ptr->feat].flags & FF_DONT_NOTICE_RUNNING)
{
- notice = FALSE;
+ notice = false;
}
/* Interesting feature */
- if (notice) return (TRUE);
+ if (notice) return true;
/* The grid is "visible" */
- inv = FALSE;
+ inv = false;
}
/* Analyze unknown grids and floors */
@@ -3574,13 +3599,13 @@ static bool_ run_test()
/* Three new directions. Stop running. */
else if (option2)
{
- return (TRUE);
+ return true;
}
/* Two non-adjacent new directions. Stop running. */
else if (option != cycle[chome[prev_dir] + i - 1])
{
- return (TRUE);
+ return true;
}
/* Two new (adjacent) directions (case 1) */
@@ -3607,13 +3632,13 @@ static bool_ run_test()
if (i < 0)
{
/* Break to the right */
- find_breakright = TRUE;
+ find_breakright = true;
}
else if (i > 0)
{
/* Break to the left */
- find_breakleft = TRUE;
+ find_breakleft = true;
}
}
}
@@ -3640,7 +3665,7 @@ static bool_ run_test()
/* Looking to break right */
if (find_breakright)
{
- return (TRUE);
+ return true;
}
}
@@ -3650,7 +3675,7 @@ static bool_ run_test()
/* Looking to break left */
if (find_breakleft)
{
- return (TRUE);
+ return true;
}
}
}
@@ -3672,7 +3697,7 @@ static bool_ run_test()
/* Looking to break left */
if (find_breakleft)
{
- return (TRUE);
+ return true;
}
}
@@ -3682,7 +3707,7 @@ static bool_ run_test()
/* Looking to break right */
if (find_breakright)
{
- return (TRUE);
+ return true;
}
}
}
@@ -3695,7 +3720,7 @@ static bool_ run_test()
/* No options */
if (!option)
{
- return (TRUE);
+ return true;
}
/* One option */
@@ -3742,7 +3767,7 @@ static bool_ run_test()
/* STOP: we are next to an intersection or a room */
else
{
- return (TRUE);
+ return true;
}
}
@@ -3767,12 +3792,12 @@ static bool_ run_test()
/* About to hit a known wall, stop */
if (see_obstacle(find_current, p_ptr->py, p_ptr->px))
{
- return (TRUE);
+ return true;
}
/* Failure */
- return (FALSE);
+ return false;
}
@@ -3847,7 +3872,7 @@ void do_cmd_pet()
char power_desc[36][80];
- bool_ flag;
+ bool flag;
int ask;
@@ -3857,7 +3882,7 @@ void do_cmd_pet()
int pets = 0, pet_ctr = 0;
- bool_ all_pets = FALSE;
+ bool all_pets = false;
monster_type *m_ptr;
@@ -3924,7 +3949,7 @@ void do_cmd_pet()
}
/* Nothing chosen yet */
- flag = FALSE;
+ flag = false;
/* Build a prompt (accept all spells) */
if (num <= 26)
@@ -3942,7 +3967,7 @@ void do_cmd_pet()
}
/* Save the screen */
- character_icky = TRUE;
+ character_icky = true;
Term_save();
/* Show the list */
@@ -3993,7 +4018,7 @@ void do_cmd_pet()
}
else
{
- ask = FALSE; /* Can't uppercase digits */
+ ask = false; /* Can't uppercase digits */
i = choice - '0' + 26;
}
@@ -4018,12 +4043,12 @@ void do_cmd_pet()
}
/* Stop the loop */
- flag = TRUE;
+ flag = true;
}
/* Restore the screen */
Term_load();
- character_icky = FALSE;
+ character_icky = false;
/* Abort if needed */
if (!flag)
@@ -4094,7 +4119,7 @@ void do_cmd_pet()
{
int Dismissed = 0;
- if (get_check("Dismiss all pets? ")) all_pets = TRUE;
+ if (get_check("Dismiss all pets? ")) all_pets = true;
/* Process the monsters (backwards) */
for (pet_ctr = m_max - 1; pet_ctr >= 1; pet_ctr--)
@@ -4105,13 +4130,13 @@ void do_cmd_pet()
if ((!(r_ptr->flags & RF_NO_DEATH)) && ((m_ptr->status == MSTATUS_PET) || (m_ptr->status == MSTATUS_FRIEND))) /* Get rid of it! */
{
- bool_ checked = FALSE;
+ bool checked = false;
char command;
- bool_ delete_this = FALSE;
+ bool delete_this = false;
if (all_pets)
{
- delete_this = TRUE;
+ delete_this = true;
}
else
{
@@ -4124,19 +4149,19 @@ void do_cmd_pet()
if (!get_com(check_friend, &command))
{
/* get out of loop */
- checked = TRUE;
+ checked = true;
pet_ctr = 0;
}
else switch (command)
{
case 'Y':
case 'y':
- delete_this = TRUE;
- checked = TRUE;
+ delete_this = true;
+ checked = true;
break;
case 'n':
case 'N':
- checked = TRUE;
+ checked = true;
break;
default:
bell();
@@ -4161,7 +4186,7 @@ void do_cmd_pet()
{
int Dismissed = 0;
- if (get_check("Dismiss all companions? ")) all_pets = TRUE;
+ if (get_check("Dismiss all companions? ")) all_pets = true;
/* Process the monsters (backwards) */
for (pet_ctr = m_max - 1; pet_ctr >= 1; pet_ctr--)
@@ -4172,10 +4197,10 @@ void do_cmd_pet()
if ((!(r_ptr->flags & RF_NO_DEATH)) && ((m_ptr->status == MSTATUS_COMPANION))) /* Get rid of it! */
{
- bool_ delete_this = FALSE;
+ bool delete_this = false;
if (all_pets)
- delete_this = TRUE;
+ delete_this = true;
else
{
char friend_name[80], check_friend[80];
@@ -4183,7 +4208,7 @@ void do_cmd_pet()
strnfmt(check_friend, 80, "Dismiss %s? ", friend_name);
if (get_check(check_friend))
- delete_this = TRUE;
+ delete_this = true;
}
if (delete_this)
@@ -4285,38 +4310,32 @@ void do_cmd_integrate_body()
floor_item_optimize(0 - item);
msg_print("Your spirit is incarnated in your new body.");
- p_ptr->wraith_form = FALSE;
- p_ptr->disembodied = FALSE;
+ p_ptr->wraith_form = false;
+ p_ptr->disembodied = false;
do_cmd_redraw();
}
/*
* Leave a body
*/
-bool_ do_cmd_leave_body(bool_ drop_body)
+void do_cmd_leave_body(bool drop_body)
{
auto const &r_info = game->edit_data.r_info;
- object_type *o_ptr, forge;
-
- auto r_ptr = &r_info[p_ptr->body_monster];
-
- int i;
-
-
if (p_ptr->disembodied)
{
msg_print("You are already disembodied.");
- return FALSE;
+ return;
}
- for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
+ for (int i = INVEN_WIELD; i < INVEN_TOTAL; i++)
{
- if (p_ptr->body_parts[i - INVEN_WIELD] && p_ptr->inventory[i].k_idx &&
- cursed_p(&p_ptr->inventory[i]))
+ if (p_ptr->body_parts[i - INVEN_WIELD] &&
+ p_ptr->inventory[i].k_ptr &&
+ cursed_p(&p_ptr->inventory[i]))
{
msg_print("A cursed object is preventing you from leaving your body.");
- return FALSE;
+ return;
}
}
@@ -4324,7 +4343,10 @@ bool_ do_cmd_leave_body(bool_ drop_body)
{
if (magik(25 + get_skill_scale(SKILL_POSSESSION, 25) + get_skill(SKILL_PRESERVATION)))
{
- o_ptr = &forge;
+ auto r_ptr = &r_info[p_ptr->body_monster];
+
+ object_type forge;
+ auto o_ptr = &forge;
object_prep(o_ptr, lookup_kind(TV_CORPSE, SV_CORPSE_CORPSE));
o_ptr->number = 1;
o_ptr->pval = 0;
@@ -4333,7 +4355,6 @@ bool_ do_cmd_leave_body(bool_ drop_body)
o_ptr->weight = (r_ptr->weight + rand_int(r_ptr->weight) / 10) + 1;
object_aware(o_ptr);
object_known(o_ptr);
- o_ptr->ident |= IDENT_STOREB;
/* Unique corpses are unique */
if (r_ptr->flags & RF_UNIQUE)
@@ -4349,24 +4370,24 @@ bool_ do_cmd_leave_body(bool_ drop_body)
}
msg_print("Your spirit leaves your body.");
- p_ptr->disembodied = TRUE;
+ p_ptr->disembodied = true;
/* Turn into a lost soul(just for the picture) */
p_ptr->body_monster = test_monster_name("Lost soul");
do_cmd_redraw();
-
- return (TRUE);
}
-bool_ execute_inscription(byte i, byte y, byte x)
+bool execute_inscription(byte i, byte y, byte x)
{
cave_type *c_ptr = &cave[y][x];
/* Not enough mana in the current grid */
- if (c_ptr->mana < inscription_info[i].mana) return (TRUE);
-
+ if (c_ptr->mana < inscription_info[i].mana)
+ {
+ return true;
+ }
/* Reduce the grid mana -- note: it can't be restored */
c_ptr->mana -= inscription_info[i].mana;
@@ -4402,9 +4423,7 @@ bool_ execute_inscription(byte i, byte y, byte x)
case INSCRIP_PROTECTION:
{
- return (FALSE);
-
- break;
+ return false;
}
case INSCRIP_DWARF_SUMMON:
@@ -4413,7 +4432,7 @@ bool_ execute_inscription(byte i, byte y, byte x)
scatter(&yy, &xx, y, x, 3);
place_monster_one(yy, xx, test_monster_name("Dwarven Warrior"),
- 0, FALSE, MSTATUS_FRIEND);
+ 0, false, MSTATUS_FRIEND);
break;
}
@@ -4454,19 +4473,19 @@ bool_ execute_inscription(byte i, byte y, byte x)
/* Scan all objects in the grid */
for (auto const this_o_idx: object_idxs)
{
- bool_ plural = FALSE;
+ bool plural = false;
char o_name[80];
/* Acquire object */
object_type * o_ptr = &o_list[this_o_idx];
- if (o_ptr->number > 1) plural = TRUE;
+ if (o_ptr->number > 1) plural = true;
/* Effect "observed" */
if (o_ptr->marked)
{
- object_desc(o_name, o_ptr, FALSE, 0);
+ object_desc(o_name, o_ptr, false, 0);
}
/* Artifacts get to resist */
@@ -4506,7 +4525,7 @@ bool_ execute_inscription(byte i, byte y, byte x)
}
}
- return (TRUE);
+ return true;
}
@@ -4528,7 +4547,7 @@ void do_cmd_engrave()
for (i = 0; i < MAX_INSCRIPTIONS; i++)
{
- if (!strcmp(inscription_info[i].text, buf))
+ if (equals(inscription_info[i].text, buf))
{
if (p_ptr->inscriptions[i])
{
diff --git a/src/cmd1.hpp b/src/cmd1.hpp
index 19b40ebf..263cad38 100644
--- a/src/cmd1.hpp
+++ b/src/cmd1.hpp
@@ -1,25 +1,25 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "monster_type_fwd.hpp"
#include "object_type_fwd.hpp"
void attack_special(monster_type *m_ptr, s32b special, int dam);
-bool_ test_hit_fire(int chance, int ac, int vis);
-bool_ test_hit_norm(int chance, int ac, int vis);
+bool test_hit_fire(int chance, int ac, int vis);
+bool test_hit_norm(int chance, int ac, int vis);
s16b critical_shot(int weight, int plus, int dam, int skill);
-s16b critical_norm(int weight, int plus, int dam, int weapon_tval, bool_ *done_crit);
+s16b critical_norm(int weight, int plus, int dam, int weapon_tval, bool *done_crit);
s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr, s32b *special);
void search();
void carry(int pickup);
void py_attack(int y, int x, int max_blow);
-bool_ player_can_enter(byte feature);
+bool player_can_enter(byte feature);
void move_player(int dir, int do_pickup);
void move_player_aux(int dir, int do_pickup, int run);
void run_step(int dir);
void do_cmd_pet();
void do_cmd_integrate_body();
-bool_ do_cmd_leave_body(bool_ drop_body);
-bool_ execute_inscription(byte i, byte y, byte x);
+void do_cmd_leave_body(bool drop_body);
+bool execute_inscription(byte i, byte y, byte x);
void do_cmd_engrave();
void do_spin();
diff --git a/src/cmd2.cc b/src/cmd2.cc
index a348c221..c57fcb2e 100644
--- a/src/cmd2.cc
+++ b/src/cmd2.cc
@@ -12,6 +12,7 @@
#include "cave.hpp"
#include "cave_type.hpp"
#include "cmd1.hpp"
+#include "cmd5.hpp"
#include "dungeon_info_type.hpp"
#include "dungeon_flag.hpp"
#include "feature_flag.hpp"
@@ -45,16 +46,17 @@
#include "stats.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "wilderness_map.hpp"
#include "wilderness_type_info.hpp"
#include "xtra1.hpp"
#include "xtra2.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#include <chrono>
+#include <fmt/format.h>
#include <thread>
using std::this_thread::sleep_for;
@@ -65,23 +67,23 @@ void do_cmd_immovable_special();
/*
* Try to bash an altar
*/
-static bool_ do_cmd_bash_altar(int y, int x)
+static bool do_cmd_bash_altar(int y, int x)
{
msg_print("Are you mad? You want to anger the gods?");
- return (FALSE);
+ return false;
}
/*
* Try to bash a fountain
*/
-static bool_ do_cmd_bash_fountain(int y, int x)
+static bool do_cmd_bash_fountain(int y, int x)
{
auto const &r_info = game->edit_data.r_info;
int bash, temp;
- bool_ more = TRUE;
+ bool more = true;
auto r_ptr = &r_info[p_ptr->body_monster];
@@ -90,7 +92,7 @@ static bool_ do_cmd_bash_fountain(int y, int x)
{
msg_print("You cannot do that.");
- return (FALSE);
+ return false;
}
/* Take a turn */
@@ -118,7 +120,7 @@ static bool_ do_cmd_bash_fountain(int y, int x)
fire_ball(GF_WATER, 5, damroll(6, 8), 2);
cave_set_feat(y, x, FEAT_DEEP_WATER);
- more = FALSE;
+ more = false;
}
return (more);
@@ -127,10 +129,10 @@ static bool_ do_cmd_bash_fountain(int y, int x)
/*
* Stair hooks
*/
-static bool_ stair_hooks(stairs_direction direction)
+static bool stair_hooks(stairs_direction direction)
{
hook_stair_in in = { direction };
- hook_stair_out out = { TRUE }; /* Allow by default */
+ hook_stair_out out = { true }; /* Allow by default */
process_hooks_new(HOOK_STAIR, &in, &out);
return (!out.allow);
}
@@ -165,8 +167,9 @@ static bool ask_leave()
void do_cmd_go_up()
{
auto const &d_info = game->edit_data.d_info;
+ auto const &dungeon_flags = game->dungeon_flags;
- bool_ go_up = FALSE, go_up_many = FALSE, prob_traveling = FALSE;
+ bool go_up = false, go_up_many = false, prob_traveling = false;
cave_type *c_ptr;
@@ -189,7 +192,7 @@ void do_cmd_go_up()
{
if (!dun_level)
{
- go_up = TRUE;
+ go_up = true;
}
else if (dungeon_flags & DF_ASK_LEAVE)
{
@@ -197,7 +200,7 @@ void do_cmd_go_up()
}
else if (ask_leave())
{
- go_up = TRUE;
+ go_up = true;
}
}
@@ -206,7 +209,7 @@ void do_cmd_go_up()
{
if (dun_level == 1)
{
- go_up = TRUE;
+ go_up = true;
}
else if (dungeon_flags & DF_ASK_LEAVE)
{
@@ -214,7 +217,7 @@ void do_cmd_go_up()
}
else if (ask_leave())
{
- go_up_many = TRUE;
+ go_up_many = true;
}
}
@@ -231,7 +234,7 @@ void do_cmd_go_up()
dun_level = 0;
p_ptr->oldpx = 0;
p_ptr->oldpy = 0;
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
return;
}
@@ -248,11 +251,11 @@ void do_cmd_go_up()
return;
}
- prob_traveling = TRUE;
+ prob_traveling = true;
if (ask_leave())
{
- go_up = TRUE;
+ go_up = true;
}
}
else
@@ -284,9 +287,9 @@ void do_cmd_go_up()
/* Create a way back */
if (go_up_many)
- create_down_shaft = TRUE;
+ create_down_shaft = true;
else
- create_down_stair = TRUE;
+ create_down_stair = true;
/* New depth */
if (go_up)
@@ -306,15 +309,15 @@ void do_cmd_go_up()
}
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
}
}
/*
- * Returns TRUE if we are in the Between...
+ * Returns true if we are in the Between...
*/
-static bool_ between_effect()
+static bool between_effect()
{
byte bx, by;
@@ -333,26 +336,26 @@ static bool_ between_effect()
/* To avoid being teleported back */
energy_use = 100;
- return (TRUE);
+ return true;
}
else if (cave[p_ptr->py][p_ptr->px].feat == FEAT_BETWEEN2)
{
between_exit *be_ptr = &between_exits[cave[p_ptr->py][p_ptr->px].special];
- p_ptr->wild_mode = FALSE;
+ p_ptr->wild_mode = false;
p_ptr->wilderness_x = be_ptr->wild_x;
p_ptr->wilderness_y = be_ptr->wild_y;
p_ptr->oldpx = p_ptr->px = be_ptr->px;
p_ptr->oldpy = p_ptr->py = be_ptr->py;
dungeon_type = be_ptr->d_idx;
dun_level = be_ptr->level;
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
- return (TRUE);
+ return true;
}
else
- return (FALSE);
+ return false;
}
/*
@@ -361,10 +364,11 @@ static bool_ between_effect()
void do_cmd_go_down()
{
auto const &d_info = game->edit_data.d_info;
+ auto const &dungeon_flags = game->dungeon_flags;
cave_type *c_ptr;
- bool_ go_down = FALSE, go_down_many = FALSE, prob_traveling = FALSE;
+ bool go_down = false, go_down_many = false, prob_traveling = false;
char i;
@@ -402,7 +406,7 @@ void do_cmd_go_down()
{
if (!dun_level)
{
- go_down = TRUE;
+ go_down = true;
/* Save old player position */
p_ptr->oldpx = p_ptr->px;
@@ -412,7 +416,7 @@ void do_cmd_go_down()
{
if (ask_leave())
{
- go_down_many = TRUE;
+ go_down_many = true;
}
}
}
@@ -426,7 +430,7 @@ void do_cmd_go_down()
}
if (!dun_level)
{
- go_down = TRUE;
+ go_down = true;
/* Save old player position */
p_ptr->oldpx = p_ptr->px;
@@ -436,7 +440,7 @@ void do_cmd_go_down()
{
if (ask_leave())
{
- go_down = TRUE;
+ go_down = true;
}
}
}
@@ -461,11 +465,11 @@ void do_cmd_go_down()
return;
}
- prob_traveling = TRUE;
+ prob_traveling = true;
if (ask_leave())
{
- go_down = TRUE;
+ go_down = true;
}
}
@@ -551,221 +555,23 @@ void do_cmd_go_down()
}
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
}
}
/*
- * Determine if a grid contains a chest
+ * Return true if the given grid is an open door
*/
-static s16b chest_check(int y, int x)
-{
- cave_type *c_ptr = &cave[y][x];
-
- /* Scan all objects in the grid */
- for (auto const this_o_idx: c_ptr->o_idxs)
- {
- object_type * o_ptr;
-
- /* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Skip unknown chests XXX XXX */
- /* if (!o_ptr->marked) continue; */
-
- /* Check for chest */
- if (o_ptr->tval == TV_CHEST) return (this_o_idx);
- }
-
- /* No chest */
- return (0);
-}
-
-
-/*
- * Allocates objects upon opening a chest -BEN-
- *
- * Disperse treasures from the given chest, centered at (x,y).
- *
- * Small chests often contain "gold", while Large chests always contain
- * items. Wooden chests contain 2 items, Iron chests contain 4 items,
- * and Steel chests contain 6 items. The "value" of the items in a
- * chest is based on the "power" of the chest, which is in turn based
- * on the level on which the chest is generated.
- */
-static void chest_death(int y, int x, s16b o_idx)
-{
- auto const &d_info = game->edit_data.d_info;
-
- int number;
-
- bool_ small;
-
- object_type forge;
- object_type *q_ptr;
-
- object_type *o_ptr = &o_list[o_idx];
-
-
- /* Small chests often hold "gold" */
- small = (o_ptr->sval < SV_CHEST_MIN_LARGE);
-
- /* Determine how much to drop (see above) */
- number = (o_ptr->sval % SV_CHEST_MIN_LARGE) * 2;
-
- /* Zero pval means empty chest */
- if (!o_ptr->pval) number = 0;
-
- /* Opening a chest */
- opening_chest = TRUE;
-
- /* Determine the "value" of the items */
- object_level = ABS(o_ptr->pval) + 10;
-
- /* Drop some objects (non-chests) */
- for (; number > 0; --number)
- {
- /* Get local object */
- q_ptr = &forge;
-
- /* Wipe the object */
- object_wipe(q_ptr);
-
- /* Small chests often drop gold */
- if (small && (rand_int(100) < 75))
- {
- /* Make some gold */
- if (!make_gold(q_ptr)) continue;
- }
-
- /* Otherwise drop an item */
- else
- {
- /* Make an object */
- if (!make_object(q_ptr, FALSE, FALSE, d_info[dungeon_type].objs))
- continue;
- }
-
- /* Drop it in the dungeon */
- drop_near(q_ptr, -1, y, x);
- }
-
- /* Reset the object level */
- object_level = dun_level;
-
- /* No longer opening a chest */
- opening_chest = FALSE;
-
- /* Empty */
- o_ptr->pval = 0;
- o_ptr->pval2 = 0;
-
- /* Known */
- object_known(o_ptr);
-}
-
-
-/*
- * Attempt to open the given chest at the given location
- *
- * Assume there is no monster blocking the destination
- *
- * Returns TRUE if repeated commands may continue
- */
-static bool_ do_cmd_open_chest(int y, int x, s16b o_idx)
-{
- auto const &r_info = game->edit_data.r_info;
-
- int i, j;
-
- bool_ flag = TRUE;
-
- bool_ more = FALSE;
-
- object_type *o_ptr = &o_list[o_idx];
-
- auto r_ptr = &r_info[p_ptr->body_monster];
-
-
- if ((p_ptr->body_monster != 0) && !(r_ptr->flags & RF_OPEN_DOOR))
- {
- msg_print("You cannot open chests.");
-
- return (FALSE);
- }
-
- /* Take a turn */
- energy_use = 100;
-
- /* Attempt to unlock it */
- if (o_ptr->pval > 0)
- {
- /* Assume locked, and thus not open */
- flag = FALSE;
-
- /* Get the "disarm" factor */
- i = 100;
-
- /* Penalize some conditions */
- if (p_ptr->blind || no_lite()) i = i / 10;
- if (p_ptr->confused || p_ptr->image) i = i / 10;
-
- /* Extract the difficulty */
- j = i - o_ptr->pval;
-
- /* Always have a small chance of success */
- if (j < 2) j = 2;
-
- /* Success -- May still have traps */
- if (rand_int(100) < j)
- {
- msg_print("You have picked the lock.");
- gain_exp(1);
- flag = TRUE;
- }
-
- /* Failure -- Keep trying */
- else
- {
- /* We may continue repeating */
- more = TRUE;
-
- flush_on_failure();
-
- msg_print("You failed to pick the lock.");
- }
- }
-
- /* Allowed to open */
- if (flag)
- {
- /* Let the Chest drop items */
- chest_death(y, x, o_idx);
- }
-
- /* Result */
- return (more);
-}
-
-
-/*
- * Original code by TNB, improvement for Angband 2.9.3 by rr9
- * Slightly modified for ToME because of its trap implementation
- */
-
-/*
- * Return TRUE if the given grid is an open door
- */
-static bool_ is_open(cave_type *c_ptr)
+static bool is_open(cave_type *c_ptr)
{
return (c_ptr->feat == FEAT_OPEN);
}
/*
- * Return TRUE if the given grid is a closed door
+ * Return true if the given grid is a closed door
*/
-static bool_ is_closed(cave_type *c_ptr)
+static bool is_closed(cave_type *c_ptr)
{
byte feat;
@@ -779,8 +585,8 @@ static bool_ is_closed(cave_type *c_ptr)
* Return the number of doors/traps around (or under)
* the character using the filter function 'test'
*/
-static int count_feats(int *y, int *x, bool_ (*test) (cave_type *c_ptr),
- bool_ under)
+static int count_feats(int *y, int *x, bool (*test) (cave_type *c_ptr),
+ bool under)
{
int d;
@@ -826,50 +632,6 @@ static int count_feats(int *y, int *x, bool_ (*test) (cave_type *c_ptr),
/*
- * Return the number of chests around (or under) the character.
- * If requested, count only trapped chests.
- */
-static int count_chests(int *y, int *x, bool_ trapped)
-{
- int d, count, o_idx;
-
- object_type *o_ptr;
-
-
- /* Count how many matches */
- count = 0;
-
- /* Check around (and under) the character */
- for (d = 0; d < 9; d++)
- {
-
- /* Extract adjacent (legal) location */
- int yy = p_ptr->py + ddy_ddd[d];
- int xx = p_ptr->px + ddx_ddd[d];
-
- /* No (visible) chest is there */
- if ((o_idx = chest_check(yy, xx)) == 0) continue;
-
- /* Grab the object */
- o_ptr = &o_list[o_idx];
-
- /* Already open */
- if (o_ptr->pval == 0) continue;
-
- /* OK */
- ++count;
-
- /* Remember the location. Only useful if only one match */
- *y = yy;
- *x = xx;
- }
-
- /* All done */
- return (count);
-}
-
-
-/*
* Convert an adjacent location to a direction.
*/
static int coords_to_dir(int y, int x)
@@ -900,9 +662,9 @@ static int coords_to_dir(int y, int x)
*
* Assume there is no monster blocking the destination
*
- * Returns TRUE if repeated commands may continue
+ * Returns true if repeated commands may continue
*/
-static bool_ do_cmd_open_aux(int y, int x, int dir)
+static bool do_cmd_open_aux(int y, int x)
{
auto const &r_info = game->edit_data.r_info;
@@ -910,7 +672,7 @@ static bool_ do_cmd_open_aux(int y, int x, int dir)
cave_type *c_ptr;
- bool_ more = FALSE;
+ bool more = false;
auto r_ptr = &r_info[p_ptr->body_monster];
@@ -919,7 +681,7 @@ static bool_ do_cmd_open_aux(int y, int x, int dir)
{
msg_print("You cannot open doors.");
- return (FALSE);
+ return false;
}
/* Take a turn */
@@ -980,7 +742,7 @@ static bool_ do_cmd_open_aux(int y, int x, int dir)
msg_print("You failed to pick the lock.");
/* We may keep trying */
- more = TRUE;
+ more = true;
}
}
@@ -999,6 +761,26 @@ static bool_ do_cmd_open_aux(int y, int x, int dir)
}
+/*
+ * Change a command "argument" to a number of repitions
+ */
+static void allow_repeat_command()
+{
+ // If there's a command argument, we set the number
+ // of repetitions instead.
+ if (command_arg)
+ {
+ /* Set repeat count */
+ command_rep = command_arg - 1;
+
+ /* Redraw the state */
+ p_ptr->redraw |= (PR_FRAME);
+
+ /* Cancel the arg */
+ command_arg = 0;
+ }
+}
+
/*
* Open a closed/locked/jammed door or a closed/locked chest.
@@ -1011,11 +793,9 @@ void do_cmd_open()
int y, x, dir;
- s16b o_idx;
-
cave_type *c_ptr;
- bool_ more = FALSE;
+ bool more = false;
auto r_ptr = &r_info[p_ptr->body_monster];
@@ -1029,16 +809,11 @@ void do_cmd_open()
/* Pick a direction if there's an obvious target */
{
- int num_doors, num_chests;
-
/* Count closed doors (locked or jammed) */
- num_doors = count_feats(&y, &x, is_closed, FALSE);
-
- /* Count chests (locked) */
- num_chests = count_chests(&y, &x, FALSE);
+ const int num_doors = count_feats(&y, &x, is_closed, false);
/* There is nothing the player can open */
- if ((num_doors + num_chests) == 0)
+ if (num_doors == 0)
{
/* Message */
msg_print("You see nothing there to open.");
@@ -1048,24 +823,14 @@ void do_cmd_open()
}
/* Set direction if there is only one target */
- else if ((num_doors + num_chests) == 1)
+ else if (num_doors == 1)
{
command_dir = coords_to_dir(y, x);
}
}
/* Allow repeated command */
- if (command_arg)
- {
- /* Set repeat count */
- command_rep = command_arg - 1;
-
- /* Redraw the state */
- p_ptr->redraw |= (PR_FRAME);
-
- /* Cancel the arg */
- command_arg = 0;
- }
+ allow_repeat_command();
/* Get a "repeated" direction */
if (get_rep_dir(&dir))
@@ -1077,12 +842,9 @@ void do_cmd_open()
/* Get requested grid */
c_ptr = &cave[y][x];
- /* Check for chest */
- o_idx = chest_check(y, x);
-
/* Nothing useful */
if (!((c_ptr->feat >= FEAT_DOOR_HEAD) &&
- (c_ptr->feat <= FEAT_DOOR_TAIL)) && !o_idx)
+ (c_ptr->feat <= FEAT_DOOR_TAIL)))
{
/* Message */
msg_print("You see nothing there to open.");
@@ -1101,18 +863,11 @@ void do_cmd_open()
py_attack(y, x, -1);
}
- /* Handle chests */
- else if (o_idx)
- {
- /* Open the chest */
- more = do_cmd_open_chest(y, x, o_idx);
- }
-
/* Handle doors */
else
{
/* Open the door */
- more = do_cmd_open_aux(y, x, dir);
+ more = do_cmd_open_aux(y, x);
}
}
@@ -1129,15 +884,15 @@ void do_cmd_open()
*
* Assume there is no monster blocking the destination
*
- * Returns TRUE if repeated commands may continue
+ * Returns true if repeated commands may continue
*/
-static bool_ do_cmd_close_aux(int y, int x, int dir)
+static bool do_cmd_close_aux(int y, int x)
{
auto const &r_info = game->edit_data.r_info;
cave_type *c_ptr;
- bool_ more = FALSE;
+ bool more = false;
auto r_ptr = &r_info[p_ptr->body_monster];
@@ -1146,7 +901,7 @@ static bool_ do_cmd_close_aux(int y, int x, int dir)
{
msg_print("You cannot close doors.");
- return (FALSE);
+ return false;
}
/* Take a turn */
@@ -1186,7 +941,7 @@ void do_cmd_close()
cave_type *c_ptr;
- bool_ more = FALSE;
+ bool more = false;
/* Pick a direction if there's an obvious choice */
@@ -1194,7 +949,7 @@ void do_cmd_close()
int num_doors;
/* Count open doors */
- num_doors = count_feats(&y, &x, is_open, FALSE);
+ num_doors = count_feats(&y, &x, is_open, false);
/* There are no doors the player can close */
if (num_doors == 0)
@@ -1214,17 +969,7 @@ void do_cmd_close()
}
/* Allow repeated command */
- if (command_arg)
- {
- /* Set repeat count */
- command_rep = command_arg - 1;
-
- /* Redraw the state */
- p_ptr->redraw |= (PR_FRAME);
-
- /* Cancel the arg */
- command_arg = 0;
- }
+ allow_repeat_command();
/* Get a "repeated" direction */
if (get_rep_dir(&dir))
@@ -1260,7 +1005,7 @@ void do_cmd_close()
else
{
/* Close the door */
- more = do_cmd_close_aux(y, x, dir);
+ more = do_cmd_close_aux(y, x);
}
}
@@ -1272,7 +1017,7 @@ void do_cmd_close()
/*
* Determine if a given grid may be "tunneled"
*/
-static bool_ do_cmd_tunnel_test(int y, int x)
+static bool do_cmd_tunnel_test(int y, int x)
{
auto const &f_info = game->edit_data.f_info;
@@ -1283,7 +1028,7 @@ static bool_ do_cmd_tunnel_test(int y, int x)
msg_print("You see nothing there.");
/* Nope */
- return (FALSE);
+ return false;
}
/* Must be a wall/door/etc */
@@ -1293,7 +1038,7 @@ static bool_ do_cmd_tunnel_test(int y, int x)
msg_print("You see nothing there to tunnel.");
/* Nope */
- return (FALSE);
+ return false;
}
/* Must be tunnelable */
@@ -1303,11 +1048,11 @@ static bool_ do_cmd_tunnel_test(int y, int x)
msg_print(f_info[cave[y][x].feat].tunnel);
/* Nope */
- return (FALSE);
+ return false;
}
/* Okay */
- return (TRUE);
+ return true;
}
@@ -1321,13 +1066,13 @@ static bool_ do_cmd_tunnel_test(int y, int x)
* This will, however, produce grids which are NOT illuminated
* (or darkened) along with the rest of the room.
*/
-static bool_ twall(int y, int x, byte feat)
+static bool twall(int y, int x, byte feat)
{
cave_type *c_ptr = &cave[y][x];
/* Paranoia -- Require a wall or door or some such */
- if (cave_floor_bold(y, x)) return (FALSE);
+ if (cave_floor_bold(y, x)) return false;
/* Forget the wall */
c_ptr->info &= ~(CAVE_MARK);
@@ -1339,7 +1084,7 @@ static bool_ twall(int y, int x, byte feat)
p_ptr->update |= (PU_VIEW | PU_FLOW | PU_MONSTERS | PU_MON_LITE);
/* Result */
- return (TRUE);
+ return true;
}
@@ -1352,9 +1097,9 @@ static bool_ twall(int y, int x, byte feat)
*
* Assumes that no monster is blocking the destination
*
- * Returns TRUE if repeated commands may continue
+ * Returns true if repeated commands may continue
*/
-static bool_ do_cmd_tunnel_aux(int y, int x, int dir)
+static bool do_cmd_tunnel_aux(int y, int x)
{
auto const &d_info = game->edit_data.d_info;
auto const &f_info = game->edit_data.f_info;
@@ -1364,23 +1109,23 @@ static bool_ do_cmd_tunnel_aux(int y, int x, int dir)
auto f_ptr = &f_info[c_ptr->feat];
- bool_ more = FALSE;
+ bool more = false;
/* Must be have something to dig with (except for sandwalls) */
if ((c_ptr->feat < FEAT_SANDWALL) || (c_ptr->feat > FEAT_SANDWALL_K))
{
- if (!p_ptr->inventory[INVEN_TOOL].k_idx ||
- (p_ptr->inventory[INVEN_TOOL].tval != TV_DIGGING))
+ auto o_ptr = &p_ptr->inventory[INVEN_TOOL];
+ if (!o_ptr->k_ptr || (o_ptr->tval != TV_DIGGING))
{
msg_print("You need to have a shovel or pick in your tool slot.");
- return (FALSE);
+ return false;
}
}
/* Verify legality */
- if (!do_cmd_tunnel_test(y, x)) return (FALSE);
+ if (!do_cmd_tunnel_test(y, x)) return false;
/* Take a turn */
energy_use = 100;
@@ -1409,7 +1154,7 @@ static bool_ do_cmd_tunnel_aux(int y, int x, int dir)
{
/* We may continue chopping */
msg_print(f_ptr->tunnel);
- more = TRUE;
+ more = true;
}
}
@@ -1431,7 +1176,7 @@ static bool_ do_cmd_tunnel_aux(int y, int x, int dir)
{
/* We may continue tunelling */
msg_print(f_ptr->tunnel);
- more = TRUE;
+ more = true;
}
}
@@ -1442,24 +1187,24 @@ static bool_ do_cmd_tunnel_aux(int y, int x, int dir)
((c_ptr->feat >= FEAT_SANDWALL) &&
(c_ptr->feat <= FEAT_SANDWALL_K)))
{
- bool_ okay = FALSE;
- bool_ gold = FALSE;
- bool_ hard = FALSE;
- bool_ soft = FALSE;
+ bool okay = false;
+ bool gold = false;
+ bool hard = false;
+ bool soft = false;
/* Found gold */
if ((c_ptr->feat >= FEAT_MAGMA_H) &&
- (c_ptr->feat <= FEAT_QUARTZ_K)) gold = TRUE;
+ (c_ptr->feat <= FEAT_QUARTZ_K)) gold = true;
if ((c_ptr->feat == FEAT_SANDWALL_H) ||
(c_ptr->feat == FEAT_SANDWALL_K))
{
- gold = TRUE;
- soft = TRUE;
+ gold = true;
+ soft = true;
}
else
/* Extract "quartz" flag XXX XXX XXX */
- if ((c_ptr->feat - FEAT_MAGMA) & 0x01) hard = TRUE;
+ if ((c_ptr->feat - FEAT_MAGMA) & 0x01) hard = true;
/* Quartz */
if (hard)
@@ -1511,7 +1256,7 @@ static bool_ do_cmd_tunnel_aux(int y, int x, int dir)
{
/* Message, continue digging */
msg_print(f_ptr->tunnel);
- more = TRUE;
+ more = true;
}
}
@@ -1531,7 +1276,7 @@ static bool_ do_cmd_tunnel_aux(int y, int x, int dir)
if (rand_int(100) < 10)
{
/* Create a simple object */
- place_object(y, x, FALSE, FALSE, OBJ_FOUND_RUBBLE);
+ place_object(y, x, false, false, OBJ_FOUND_RUBBLE);
/* Observe new object */
if (player_can_see_bold(y, x))
@@ -1545,7 +1290,7 @@ static bool_ do_cmd_tunnel_aux(int y, int x, int dir)
{
/* Message, keep digging */
msg_print(f_ptr->tunnel);
- more = TRUE;
+ more = true;
}
}
@@ -1573,7 +1318,7 @@ static bool_ do_cmd_tunnel_aux(int y, int x, int dir)
/* We may continue tunelling */
msg_print(f_info[feat].tunnel);
- more = TRUE;
+ more = true;
}
}
@@ -1593,7 +1338,7 @@ static bool_ do_cmd_tunnel_aux(int y, int x, int dir)
{
/* We may continue tunelling */
msg_print(f_ptr->tunnel);
- more = TRUE;
+ more = true;
}
}
@@ -1602,7 +1347,7 @@ static bool_ do_cmd_tunnel_aux(int y, int x, int dir)
if (p_ptr->skill_dig < skill_req)
{
msg_print("You fail to make even the slightest of progress.");
- more = FALSE;
+ more = false;
}
else if (p_ptr->skill_dig < skill_req_1pct)
{
@@ -1637,23 +1382,13 @@ void do_cmd_tunnel()
cave_type *c_ptr;
- bool_ more = FALSE;
+ bool more = false;
if (p_ptr->wild_mode) return;
/* Allow repeated command */
- if (command_arg)
- {
- /* Set repeat count */
- command_rep = command_arg - 1;
-
- /* Redraw the state */
- p_ptr->redraw |= (PR_FRAME);
-
- /* Cancel the arg */
- command_arg = 0;
- }
+ allow_repeat_command();
/* Get a direction to tunnel, or Abort */
if (get_rep_dir(&dir))
@@ -1689,7 +1424,7 @@ void do_cmd_tunnel()
else
{
/* Tunnel through walls */
- more = do_cmd_tunnel_aux(y, x, dir);
+ more = do_cmd_tunnel_aux(y, x);
}
}
@@ -1704,9 +1439,9 @@ void do_cmd_tunnel()
*
* Assume there is no monster blocking the destination
*
- * Returns TRUE if repeated commands may continue
+ * Returns true if repeated commands may continue
*/
-static bool_ do_cmd_bash_aux(int y, int x, int dir)
+static bool do_cmd_bash_aux(int y, int x, int dir)
{
auto const &r_info = game->edit_data.r_info;
@@ -1714,7 +1449,7 @@ static bool_ do_cmd_bash_aux(int y, int x, int dir)
cave_type *c_ptr;
- bool_ more = FALSE;
+ bool more = false;
auto r_ptr = &r_info[p_ptr->body_monster];
@@ -1723,7 +1458,7 @@ static bool_ do_cmd_bash_aux(int y, int x, int dir)
{
msg_print("You cannot do that.");
- return (FALSE);
+ return false;
}
/* Take a turn */
@@ -1781,7 +1516,7 @@ static bool_ do_cmd_bash_aux(int y, int x, int dir)
msg_print("The door holds firm.");
/* Allow repeated bashing */
- more = TRUE;
+ more = true;
}
/* High dexterity yields coolness */
@@ -1821,7 +1556,7 @@ void do_cmd_bash()
cave_type *c_ptr;
- bool_ more = FALSE;
+ bool more = false;
auto r_ptr = &r_info[p_ptr->body_monster];
@@ -1834,17 +1569,7 @@ void do_cmd_bash()
}
/* Allow repeated command */
- if (command_arg)
- {
- /* Set repeat count */
- command_rep = command_arg - 1;
-
- /* Redraw the state */
- p_ptr->redraw |= (PR_FRAME);
-
- /* Cancel the arg */
- command_arg = 0;
- }
+ allow_repeat_command();
/* Get a "repeated" direction */
if (get_rep_dir(&dir))
@@ -1920,21 +1645,11 @@ void do_cmd_alter()
cave_type *c_ptr;
- bool_ more = FALSE;
+ bool more = false;
/* Allow repeated command */
- if (command_arg)
- {
- /* Set repeat count */
- command_rep = command_arg - 1;
-
- /* Redraw the state */
- p_ptr->redraw |= (PR_FRAME);
-
- /* Cancel the arg */
- command_arg = 0;
- }
+ allow_repeat_command();
/* Get a direction */
if (get_rep_dir(&dir))
@@ -1961,14 +1676,14 @@ void do_cmd_alter()
(c_ptr->feat <= FEAT_DOOR_TAIL))
{
/* Tunnel */
- more = do_cmd_open_aux(y, x, dir);
+ more = do_cmd_open_aux(y, x);
}
/* Tunnel through walls */
else if (f_info[c_ptr->feat].flags & FF_TUNNELABLE)
{
/* Tunnel */
- more = do_cmd_tunnel_aux(y, x, dir);
+ more = do_cmd_tunnel_aux(y, x);
}
/* Oops */
@@ -1989,7 +1704,7 @@ void do_cmd_alter()
*
* XXX XXX XXX Let user choose a pile of spikes, perhaps?
*/
-static bool_ get_spike(int *ip)
+static bool get_spike(int *ip)
{
int i;
@@ -1999,8 +1714,10 @@ static bool_ get_spike(int *ip)
{
object_type *o_ptr = &p_ptr->inventory[i];
- /* Skip non-objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Check the "tval" code */
if (o_ptr->tval == TV_SPIKE)
@@ -2009,12 +1726,12 @@ static bool_ get_spike(int *ip)
(*ip) = i;
/* Success */
- return (TRUE);
+ return true;
}
}
/* Oops */
- return (FALSE);
+ return false;
}
@@ -2097,21 +1814,11 @@ static void do_cmd_walk_jump(int pickup)
int dir;
- bool_ more = FALSE;
+ bool more = false;
/* Allow repeated command */
- if (command_arg)
- {
- /* Set repeat count */
- command_rep = command_arg - 1;
-
- /* Redraw the state */
- p_ptr->redraw |= (PR_FRAME);
-
- /* Cancel the arg */
- command_arg = 0;
- }
+ allow_repeat_command();
/* Get a "repeated" direction */
if (get_rep_dir(&dir))
@@ -2123,7 +1830,7 @@ static void do_cmd_walk_jump(int pickup)
move_player(dir, pickup);
/* Allow more walking */
- more = TRUE;
+ more = true;
}
/* Hack -- In small scale wilderness it takes MUCH more time to move */
@@ -2141,7 +1848,7 @@ static void do_cmd_walk_jump(int pickup)
change_wild_mode();
/* HACk -- set the encouter flag for the wilderness generation */
- generate_encounter = TRUE;
+ generate_encounter = true;
p_ptr->oldpx = MAX_WID / 2;
p_ptr->oldpy = MAX_HGT / 2;
@@ -2163,7 +1870,7 @@ static void do_cmd_unwalk()
cave_type *c_ptr;
- bool_ more = FALSE;
+ bool more = false;
if (!get_rep_dir(&dir)) return;
@@ -2183,18 +1890,7 @@ static void do_cmd_unwalk()
/* Allow repeated command */
- if (command_arg)
- {
- /* Set repeat count */
- command_rep = command_arg - 1;
-
- /* Redraw the state */
- p_ptr->redraw |= (PR_FRAME);
-
- /* Cancel the arg */
- command_arg = 0;
- }
-
+ allow_repeat_command();
/* Attack monsters */
if (c_ptr->m_idx > 0)
@@ -2217,7 +1913,7 @@ static void do_cmd_unwalk()
p_ptr->wilderness_x--;
p_ptr->oldpy = cur_hgt - 2;
p_ptr->oldpx = cur_wid - 2;
- ambush_flag = FALSE;
+ ambush_flag = false;
}
else if ((y == 0) && (x == MAX_WID - 1))
@@ -2226,7 +1922,7 @@ static void do_cmd_unwalk()
p_ptr->wilderness_x++;
p_ptr->oldpy = cur_hgt - 2;
p_ptr->oldpx = 1;
- ambush_flag = FALSE;
+ ambush_flag = false;
}
else if ((y == MAX_HGT - 1) && (x == 0))
@@ -2235,7 +1931,7 @@ static void do_cmd_unwalk()
p_ptr->wilderness_x--;
p_ptr->oldpy = 1;
p_ptr->oldpx = cur_wid - 2;
- ambush_flag = FALSE;
+ ambush_flag = false;
}
else if ((y == MAX_HGT - 1) && (x == MAX_WID - 1))
@@ -2244,7 +1940,7 @@ static void do_cmd_unwalk()
p_ptr->wilderness_x++;
p_ptr->oldpy = 1;
p_ptr->oldpx = 1;
- ambush_flag = FALSE;
+ ambush_flag = false;
}
else if (y == 0)
@@ -2252,7 +1948,7 @@ static void do_cmd_unwalk()
p_ptr->wilderness_y--;
p_ptr->oldpy = cur_hgt - 2;
p_ptr->oldpx = x;
- ambush_flag = FALSE;
+ ambush_flag = false;
}
else if (y == cur_hgt - 1)
@@ -2260,7 +1956,7 @@ static void do_cmd_unwalk()
p_ptr->wilderness_y++;
p_ptr->oldpy = 1;
p_ptr->oldpx = x;
- ambush_flag = FALSE;
+ ambush_flag = false;
}
else if (x == 0)
@@ -2268,7 +1964,7 @@ static void do_cmd_unwalk()
p_ptr->wilderness_x--;
p_ptr->oldpx = cur_wid - 2;
p_ptr->oldpy = y;
- ambush_flag = FALSE;
+ ambush_flag = false;
}
else if (x == cur_wid - 1)
@@ -2276,10 +1972,10 @@ static void do_cmd_unwalk()
p_ptr->wilderness_x++;
p_ptr->oldpx = 1;
p_ptr->oldpy = y;
- ambush_flag = FALSE;
+ ambush_flag = false;
}
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
return;
}
@@ -2296,7 +1992,7 @@ static void do_cmd_unwalk()
((feat >= FEAT_LESS) && (feat <= FEAT_MORE)))
{
move_player(dir, options->always_pickup);
- more = FALSE;
+ more = false;
}
/* Hack -- Ignore wilderness mofe. */
@@ -2396,18 +2092,7 @@ void do_cmd_stay(int pickup)
/* Allow repeated command */
- if (command_arg)
- {
- /* Set repeat count */
- command_rep = command_arg - 1;
-
- /* Redraw the state */
- p_ptr->redraw |= (PR_FRAME);
-
- /* Cancel the arg */
- command_arg = 0;
- }
-
+ allow_repeat_command();
/* Take a turn */
energy_use = 100;
@@ -2441,8 +2126,9 @@ void do_cmd_rest()
flush_on_failure();
/* Tell the player why */
- msg_print(format("Resting on a %s is too dangerous!",
- f_info[cave[p_ptr->py][p_ptr->px].feat].name));
+ msg_print(fmt::format(
+ "Resting on a {} is too dangerous!",
+ f_info[cave[p_ptr->py][p_ptr->px].feat].name));
/* Done */
return;
@@ -2464,7 +2150,7 @@ void do_cmd_rest()
/* Prompt for time if needed */
if (command_arg <= 0)
{
- cptr p = "Rest (0-9999, '*' for HP/SP, '&' as needed): ";
+ const char *p = "Rest (0-9999, '*' for HP/SP, '&' as needed): ";
char out_val[80];
@@ -2683,7 +2369,7 @@ void do_cmd_fire()
object_type *j_ptr;
- bool_ hit_body = FALSE;
+ bool hit_body = false;
byte missile_attr;
@@ -2717,7 +2403,7 @@ void do_cmd_fire()
item = INVEN_AMMO;
/* If nothing correct try to choose from the backpack */
- if ((p_ptr->tval_ammo != o_ptr->tval) || (!o_ptr->k_idx))
+ if ((p_ptr->tval_ammo != o_ptr->tval) || (!o_ptr->k_ptr))
{
/* Get an item */
if (!get_item(&item,
@@ -2762,7 +2448,7 @@ void do_cmd_fire()
/* Describe the object */
- object_desc(o_name, q_ptr, FALSE, 3);
+ object_desc(o_name, q_ptr, false, 3);
/* Find the color and symbol for the object for throwing */
missile_attr = object_attr(q_ptr);
@@ -2831,7 +2517,7 @@ void do_cmd_fire()
handle_stuff();
oldtdam = tdam;
- while (TRUE)
+ while (true)
{
/* Reset after a piercing shot */
tdam = oldtdam;
@@ -2890,15 +2576,15 @@ void do_cmd_fire()
visible = m_ptr->ml;
/* Note the collision */
- hit_body = TRUE;
+ hit_body = true;
/* Did we hit it (penalize range) */
if (test_hit_fire(chance - cur_dis, m_ptr->ac, m_ptr->ml))
{
- bool_ fear = FALSE;
+ bool fear = false;
/* Assume a default death */
- cptr note_dies = " dies.";
+ const char *note_dies = " dies.";
/* Some monsters get "destroyed" */
if ((r_ptr->flags & RF_DEMON) ||
@@ -3046,7 +2732,7 @@ void do_cmd_fire()
(magik(45 + get_skill(SKILL_ARCHERY))))
{
num_pierce--;
- hit_body = FALSE;
+ hit_body = false;
/* If target isn't reached, continue moving to target */
if ( !((tx < x && x < bx) || (bx < x && x < tx)) &&
@@ -3092,8 +2778,6 @@ void do_cmd_fire()
*/
void do_cmd_throw()
{
- auto const &k_info = game->edit_data.k_info;
-
int dir;
s32b special = 0;
@@ -3113,9 +2797,9 @@ void do_cmd_throw()
object_type *q_ptr;
- bool_ hit_body = FALSE;
+ bool hit_body = false;
- bool_ hit_wall = FALSE;
+ bool hit_wall = false;
byte missile_attr;
@@ -3194,7 +2878,7 @@ void do_cmd_throw()
inc_stack_size(item, -1);
/* Description */
- object_desc(o_name, q_ptr, FALSE, 3);
+ object_desc(o_name, q_ptr, false, 3);
/* Find the color and symbol for the object for throwing */
missile_attr = object_attr(q_ptr);
@@ -3258,7 +2942,7 @@ void do_cmd_throw()
/* Stopped by walls/doors */
if (!cave_floor_bold(ny, nx))
{
- hit_wall = TRUE;
+ hit_wall = true;
break;
}
@@ -3302,15 +2986,15 @@ void do_cmd_throw()
visible = m_ptr->ml;
/* Note the collision */
- hit_body = TRUE;
+ hit_body = true;
/* Did we hit it (penalize range) */
if (test_hit_fire(chance - cur_dis, m_ptr->ac, m_ptr->ml))
{
- bool_ fear = FALSE;
+ bool fear = false;
/* Assume a default death */
- cptr note_dies = " dies.";
+ const char *note_dies = " dies.";
/* Some monsters get "destroyed" */
if ((r_ptr->flags & RF_DEMON) ||
@@ -3377,7 +3061,7 @@ void do_cmd_throw()
if (special) attack_special(m_ptr, special, tdam);
/* Anger friends */
- if (!(k_info[q_ptr->k_idx].tval == TV_POTION))
+ if (!(q_ptr->k_ptr->tval == TV_POTION))
{
char m_name[80];
monster_desc(m_name, m_ptr, 0);
@@ -3417,7 +3101,7 @@ void do_cmd_throw()
j = (hit_body ? breakage_chance(q_ptr) : 0);
/* Potions smash open */
- if (k_info[q_ptr->k_idx].tval == TV_POTION)
+ if (q_ptr->k_ptr->tval == TV_POTION)
{
if ((hit_body) || (hit_wall) || (randint(100) < j))
{
@@ -3468,8 +3152,6 @@ void do_cmd_throw()
*/
void do_cmd_boomerang()
{
- auto const &k_info = game->edit_data.k_info;
-
int dir;
int j, y, x, ny, nx, ty, tx;
@@ -3486,7 +3168,7 @@ void do_cmd_boomerang()
object_type *o_ptr;
- bool_ hit_body = FALSE;
+ bool hit_body = false;
byte missile_attr;
@@ -3517,7 +3199,7 @@ void do_cmd_boomerang()
q_ptr->number = 1;
/* Description */
- object_desc(o_name, q_ptr, FALSE, 3);
+ object_desc(o_name, q_ptr, false, 3);
/* Find the color and symbol for the object for throwing */
missile_attr = object_attr(q_ptr);
@@ -3628,15 +3310,15 @@ void do_cmd_boomerang()
visible = m_ptr->ml;
/* Note the collision */
- hit_body = TRUE;
+ hit_body = true;
/* Did we hit it (penalize range) */
if (test_hit_fire(chance - cur_dis, m_ptr->ac, m_ptr->ml))
{
- bool_ fear = FALSE;
+ bool fear = false;
/* Assume a default death */
- cptr note_dies = " dies.";
+ const char *note_dies = " dies.";
/* Some monsters get "destroyed" */
if ((r_ptr->flags & RF_DEMON) ||
@@ -3703,7 +3385,7 @@ void do_cmd_boomerang()
if (special) attack_special(m_ptr, special, tdam);
/* Anger friends */
- if (!(k_info[q_ptr->k_idx].tval == TV_POTION))
+ if (!(q_ptr->k_ptr->tval == TV_POTION))
{
char m_name[80];
monster_desc(m_name, m_ptr, 0);
@@ -3739,7 +3421,7 @@ void do_cmd_boomerang()
/* Break the boomerang */
if ((!artifact_p(o_ptr)) && (rand_int(100) < j))
{
- msg_print(format("Your %s is destroyed.", o_name));
+ msg_print(fmt::format("Your {} is destroyed.", o_name));
inc_stack_size_ex(INVEN_BOW, -1, OPTIMIZE, NO_DESCRIBE);
}
}
@@ -3790,21 +3472,22 @@ void do_cmd_boomerang()
}
-static bool_ tport_vertically(bool_ how)
+static bool tport_vertically(bool how)
{
auto const &d_info = game->edit_data.d_info;
+ auto const &dungeon_flags = game->dungeon_flags;
/* quest? */
if (p_ptr->inside_quest)
{
msg_print("There is no effect.");
- return (FALSE);
+ return false;
}
if (dungeon_flags & DF_NO_EASY_MOVE)
{
msg_print("Some powerful force prevents you from teleporting.");
- return FALSE;
+ return false;
}
/* Go down */
@@ -3813,27 +3496,27 @@ static bool_ tport_vertically(bool_ how)
if (dun_level >= d_info[dungeon_type].maxdepth)
{
msg_print("The floor is impermeable.");
- return (FALSE);
+ return false;
}
msg_print("You sink through the floor.");
dun_level++;
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
}
else
{
if (dun_level < d_info[dungeon_type].mindepth)
{
msg_print("There is nothing above you but air.");
- return (FALSE);
+ return false;
}
msg_print("You rise through the ceiling.");
dun_level--;
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
}
- return (TRUE);
+ return true;
}
@@ -3851,9 +3534,9 @@ void do_cmd_immovable_special()
int lose_hp = 0;
- bool_ did_act = FALSE;
+ bool did_act = false;
- bool_ did_load = FALSE;
+ bool did_load = false;
if (foo > 1)
@@ -3884,14 +3567,14 @@ void do_cmd_immovable_special()
}
/* Enter "icky" mode */
- character_icky = TRUE;
+ character_icky = true;
/* Save the screen */
Term_save();
/* Interact until done */
- while (1)
+ while (true)
{
/* Clear screen */
Term_clear();
@@ -3918,15 +3601,15 @@ void do_cmd_immovable_special()
if (i == 'a')
{
Term_load();
- character_icky = FALSE;
- did_load = TRUE;
+ character_icky = false;
+ did_load = true;
if (!tgt_pt(&ii, &ij)) break;
/* Teleport to the target */
teleport_player_to(ij, ii);
- did_act = TRUE;
+ did_act = true;
break;
}
@@ -3934,14 +3617,14 @@ void do_cmd_immovable_special()
else if (i == 'b')
{
Term_load();
- character_icky = FALSE;
- did_load = TRUE;
+ character_icky = false;
+ did_load = true;
if (!get_aim_dir(&dir)) return;
- fetch(dir, p_ptr->lev * 15, FALSE);
+ fetch(dir, p_ptr->lev * 15, false);
py_pickup_floor(options->always_pickup);
- did_act = TRUE;
+ did_act = true;
break;
}
@@ -3949,12 +3632,12 @@ void do_cmd_immovable_special()
else if (i == 'c')
{
Term_load();
- character_icky = FALSE;
- did_load = TRUE;
+ character_icky = false;
+ did_load = true;
- if (!tport_vertically(FALSE)) return;
+ if (!tport_vertically(false)) return;
- did_act = TRUE;
+ did_act = true;
break;
}
@@ -3962,12 +3645,12 @@ void do_cmd_immovable_special()
else if (i == 'd')
{
Term_load();
- character_icky = FALSE;
- did_load = TRUE;
+ character_icky = false;
+ did_load = true;
- if (!tport_vertically(TRUE)) return;
+ if (!tport_vertically(true)) return;
- did_act = TRUE;
+ did_act = true;
break;
}
@@ -3986,7 +3669,7 @@ void do_cmd_immovable_special()
Term_load();
/* Leave "icky" mode */
- character_icky = FALSE;
+ character_icky = false;
}
/* Apply stat losses if something was done */
@@ -4017,17 +3700,17 @@ static bool item_tester_hook_sacrificable(object_type const *o_ptr)
{
/* Corpses are */
if (o_ptr->tval == TV_CORPSE && o_ptr->sval == SV_CORPSE_CORPSE)
- return (TRUE);
+ return true;
/* Books without any udun spells */
if ((o_ptr->tval == TV_BOOK) && udun_in_book(o_ptr->sval, o_ptr->pval) <= 0)
{
- return TRUE;
+ return true;
}
}
/* Assume not */
- return (FALSE);
+ return false;
}
/*
@@ -4097,9 +3780,9 @@ void do_cmd_sacrifice()
if (deity_info[agod].desc[i] != NULL)
msg_print(deity_info[agod].desc[i]);
}
- if (get_check(format("Do you want to worship %s? ", deity_info[agod].name)))
+ if (get_check(fmt::format("Do you want to worship {}? ", deity_info[agod].name)))
{
- follow_god(agod, FALSE);
+ follow_god(agod, false);
p_ptr->grace = -200;
inc_piety(p_ptr->pgod, 0);
}
@@ -4230,7 +3913,7 @@ std::vector<s16b> show_monster_inven(int m_idx)
/* Describe the object */
char o_name[80];
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Hack -- enforce max length */
o_name[lim] = '\0';
@@ -4264,18 +3947,15 @@ std::vector<s16b> show_monster_inven(int m_idx)
/* Clear the line */
prt("", i + 1, col ? col - 2 : col);
- /* Prepare an index --(-- */
- char tmp_val[80];
- strnfmt(tmp_val, 80, "%c)", index_to_label(i));
-
- /* Clear the line with the (possibly indented) index */
- put_str(tmp_val, i + 1, col);
+ /* Display index */
+ put_str(fmt::format("{})", index_to_label(i)), i + 1, col);
/* Display the entry itself */
c_put_str(out_color[i], out_desc[i], i + 1, col + 3);
/* Display the weight if needed */
{
+ char tmp_val[80];
int wgt = o_ptr->weight * o_ptr->number;
strnfmt(tmp_val, 80, "%3d.%1d lb", wgt / 10, wgt % 10);
put_str(tmp_val, i + 1, 71);
@@ -4301,7 +3981,7 @@ void do_cmd_steal()
int dir = 0, item = -1, k = -1;
- bool_ done = FALSE;
+ bool done = false;
/* Only works on adjacent monsters */
if (!get_rep_dir(&dir)) return;
@@ -4357,7 +4037,7 @@ void do_cmd_steal()
{
case ESCAPE:
{
- done = TRUE;
+ done = true;
break;
}
@@ -4381,14 +4061,14 @@ void do_cmd_steal()
/* Verify the item */
if (ver && !verify("Try", -objects[k]))
{
- done = TRUE;
+ done = true;
break;
}
/* Accept that choice */
item = objects[k];
- done = TRUE;
+ done = true;
break;
}
@@ -4463,11 +4143,11 @@ void do_cmd_steal()
{
object_copy(o_ptr, &o_list[item]);
- inven_carry(o_ptr, FALSE);
+ inven_carry(o_ptr, false);
}
/* Delete source item */
- o_list[item].k_idx = 0;
+ o_list[item].k_ptr.reset();
}
screen_load();
diff --git a/src/cmd2.hpp b/src/cmd2.hpp
index 9641dc72..35aed893 100644
--- a/src/cmd2.hpp
+++ b/src/cmd2.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_type_fwd.hpp"
#include <vector>
@@ -27,6 +27,5 @@ void do_cmd_fire();
void do_cmd_throw();
void do_cmd_boomerang();
void do_cmd_immovable_special();
-void fetch(int dir, int wgt, bool_ require_los);
void do_cmd_sacrifice();
void do_cmd_steal();
diff --git a/src/cmd3.cc b/src/cmd3.cc
index cbf58820..6498d48b 100644
--- a/src/cmd3.cc
+++ b/src/cmd3.cc
@@ -33,19 +33,21 @@
#include "tables.hpp"
#include "town_type.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "xtra1.hpp"
#include "xtra2.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
-#include <cassert>
#include <algorithm>
+#include <boost/algorithm/string/predicate.hpp>
+#include <cassert>
#include <fmt/format.h>
#include <memory>
#include <utility>
+using boost::algorithm::equals;
+
/*
* Display p_ptr->inventory
*/
@@ -55,11 +57,10 @@ void do_cmd_inven()
/* Note that we are in "p_ptr->inventory" mode */
- command_wrk = FALSE;
+ command_wrk = false;
/* Save the screen */
- character_icky = TRUE;
- Term_save();
+ screen_save_no_flush();
/* Show the inventory */
show_inven_full();
@@ -81,9 +82,7 @@ void do_cmd_inven()
command_new = inkey();
/* Restore the screen */
- Term_load();
- character_icky = FALSE;
-
+ screen_load_no_flush();
/* Process "Escape" */
if (command_new == ESCAPE)
@@ -96,7 +95,7 @@ void do_cmd_inven()
else
{
/* Mega-Hack -- Don't disable keymaps for this key */
- request_command_inven_mode = TRUE;
+ request_command_inven_mode = true;
}
}
@@ -110,11 +109,10 @@ void do_cmd_equip()
/* Note that we are in "equipment" mode */
- command_wrk = TRUE;
+ command_wrk = true;
/* Save the screen */
- character_icky = TRUE;
- Term_save();
+ screen_save_no_flush();
/* Display the equipment */
show_equip_full();
@@ -137,9 +135,7 @@ void do_cmd_equip()
command_new = inkey();
/* Restore the screen */
- Term_load();
- character_icky = FALSE;
-
+ screen_load_no_flush();
/* Process "Escape" */
if (command_new == ESCAPE)
@@ -152,7 +148,7 @@ void do_cmd_equip()
else
{
/* Mega-Hack -- Don't disable keymaps for this key */
- request_command_inven_mode = TRUE;
+ request_command_inven_mode = true;
}
}
@@ -171,33 +167,32 @@ static bool item_tester_hook_wear(object_type const *o_ptr)
{
object_type *q_ptr = &p_ptr->inventory[i];
- if (!q_ptr->k_idx) continue;
+ if (!q_ptr->k_ptr)
+ {
+ continue;
+ }
- if (object_flags(q_ptr) & TR_ULTIMATE) return (FALSE);
+ if (object_flags(q_ptr) & TR_ULTIMATE)
+ {
+ return false;
+ }
}
}
if ((slot < INVEN_WIELD) || ((p_ptr->body_parts[slot - INVEN_WIELD] == INVEN_WIELD) && (p_ptr->melee_style != SKILL_MASTERY)))
- return (FALSE);
+ return false;
/* Check for a usable slot */
- if (slot >= INVEN_WIELD) return (TRUE);
+ if (slot >= INVEN_WIELD) return true;
/* Assume not wearable */
- return (FALSE);
+ return false;
}
-bool_ is_slot_ok(int slot)
+static bool is_slot_ok(int slot)
{
- if ((slot >= INVEN_WIELD) && (slot < INVEN_TOTAL))
- {
- return (TRUE);
- }
- else
- {
- return (FALSE);
- }
+ return (slot >= INVEN_WIELD) && (slot < INVEN_TOTAL);
}
@@ -216,7 +211,7 @@ void do_cmd_wield()
object_type *i_ptr;
- cptr act;
+ const char *act;
char o_name[80];
@@ -240,7 +235,7 @@ void do_cmd_wield()
if (cursed_p(&p_ptr->inventory[slot]))
{
/* Describe it */
- object_desc(o_name, &p_ptr->inventory[slot], FALSE, 0);
+ object_desc(o_name, &p_ptr->inventory[slot], false, 0);
/* Message */
msg_format("The %s you are %s appears to be cursed.",
@@ -251,12 +246,12 @@ void do_cmd_wield()
}
if ((cursed_p(o_ptr)) && (options->wear_confirm)
- && (object_known_p(o_ptr) || (o_ptr->ident & (IDENT_SENSE))))
+ && (object_known_p(o_ptr)))
{
char dummy[512];
/* Describe it */
- object_desc(o_name, o_ptr, FALSE, 0);
+ object_desc(o_name, o_ptr, false, 0);
strnfmt(dummy, 512, "Really use the %s {cursed}? ", o_name);
if (!(get_check(dummy)))
@@ -277,10 +272,10 @@ void do_cmd_wield()
/* Two handed weapons can't be wielded with a shield */
if ((is_slot_ok(slot - INVEN_WIELD + INVEN_ARM)) &&
- (flags & TR_MUST2H) &&
- (p_ptr->inventory[slot - INVEN_WIELD + INVEN_ARM].k_idx != 0))
+ (flags & TR_MUST2H) &&
+ (p_ptr->inventory[slot - INVEN_WIELD + INVEN_ARM].k_ptr))
{
- object_desc(o_name, o_ptr, FALSE, 0);
+ object_desc(o_name, o_ptr, false, 0);
msg_format("You cannot wield your %s with a shield.", o_name);
return;
}
@@ -293,16 +288,17 @@ void do_cmd_wield()
auto const i_flags = object_flags(i_ptr);
/* Prevent shield from being put on if wielding 2H */
- if ((i_flags & TR_MUST2H) && (i_ptr->k_idx) &&
- (p_ptr->body_parts[slot - INVEN_WIELD] == INVEN_ARM))
+ if ((i_flags & TR_MUST2H) &&
+ i_ptr->k_ptr &&
+ (p_ptr->body_parts[slot - INVEN_WIELD] == INVEN_ARM))
{
- object_desc(o_name, o_ptr, FALSE, 0);
+ object_desc(o_name, o_ptr, false, 0);
msg_format("You cannot wield your %s with a two-handed weapon.", o_name);
return;
}
if ((p_ptr->body_parts[slot - INVEN_WIELD] == INVEN_ARM) &&
- (i_flags & TR_COULD2H))
+ (i_flags & TR_COULD2H))
{
if (!get_check("Are you sure you want to restrict your fighting? "))
{
@@ -312,8 +308,8 @@ void do_cmd_wield()
}
if ((is_slot_ok(slot - INVEN_WIELD + INVEN_ARM)) &&
- (p_ptr->inventory[slot - INVEN_WIELD + INVEN_ARM].k_idx != 0) &&
- (flags & TR_COULD2H))
+ p_ptr->inventory[slot - INVEN_WIELD + INVEN_ARM].k_ptr &&
+ (flags & TR_COULD2H))
{
if (!get_check("Are you sure you want to use this weapon with a shield?"))
{
@@ -344,20 +340,20 @@ void do_cmd_wield()
/* Take off existing item */
if (slot != INVEN_AMMO)
{
- if (o_ptr->k_idx)
+ if (o_ptr->k_ptr)
{
/* Take off existing item */
- inven_takeoff(slot, 255, FALSE);
+ inven_takeoff(slot, 255, false);
}
}
else
{
- if (o_ptr->k_idx)
+ if (o_ptr->k_ptr)
{
if (!object_similar(o_ptr, q_ptr))
{
/* Take off existing item */
- inven_takeoff(slot, 255, FALSE);
+ inven_takeoff(slot, 255, false);
}
else
{
@@ -404,7 +400,7 @@ void do_cmd_wield()
}
/* Describe the result */
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Message */
msg_format("%s %s (%c).", act, o_name, index_to_label(slot));
@@ -414,16 +410,12 @@ void do_cmd_wield()
{
/* Warn the player */
msg_print("Oops! It feels deathly cold!");
-
- /* Note the curse */
- o_ptr->ident |= (IDENT_SENSE);
- o_ptr->sense = SENSE_CURSED;
}
/* Take care of item sets */
if (o_ptr->name1)
{
- wield_set(o_ptr->name1, a_info[o_ptr->name1].set, FALSE);
+ wield_set(o_ptr->name1, a_info[o_ptr->name1].set, false);
}
/* Recalculate bonuses */
@@ -479,7 +471,7 @@ void do_cmd_takeoff()
energy_use = 50;
/* Take off the item */
- inven_takeoff(item, 255, FALSE);
+ inven_takeoff(item, 255, false);
/* Recalculate hitpoint */
p_ptr->update |= (PU_HP);
@@ -550,7 +542,7 @@ void do_cmd_drop()
energy_use = 50;
/* Drop (some of) the item */
- inven_drop(item, amt, p_ptr->py, p_ptr->px, FALSE);
+ inven_drop(item, amt, p_ptr->py, p_ptr->px, false);
}
@@ -559,18 +551,16 @@ void do_cmd_drop()
*/
void do_cmd_destroy()
{
- auto const &k_info = game->edit_data.k_info;
-
int old_number;
- bool_ force = FALSE;
+ bool force = false;
char o_name[80];
char out_val[160];
/* Hack -- force destruction */
- if (command_arg > 0) force = TRUE;
+ if (command_arg > 0) force = true;
/* Get an item */
@@ -601,7 +591,7 @@ void do_cmd_destroy()
/* Describe the object */
old_number = o_ptr->number;
o_ptr->number = amt;
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
o_ptr->number = old_number;
/* Verify unless quantity given */
@@ -629,28 +619,12 @@ void do_cmd_destroy()
/* Artifacts cannot be destroyed */
if (artifact_p(o_ptr))
{
- byte feel = SENSE_SPECIAL;
-
+ /* Don't use any energy */
energy_use = 0;
/* Message */
msg_format("You cannot destroy %s.", o_name);
- /* Hack -- Handle icky artifacts */
- if (cursed_p(o_ptr)) feel = SENSE_TERRIBLE;
-
- /* Hack -- inscribe the artifact */
- o_ptr->sense = feel;
-
- /* We have "felt" it (again) */
- o_ptr->ident |= (IDENT_SENSE);
-
- /* Combine the pack */
- p_ptr->notice |= (PN_COMBINE);
-
- /* Window stuff */
- p_ptr->window |= (PW_INVEN | PW_EQUIP);
-
/* Done */
return;
}
@@ -677,7 +651,7 @@ void do_cmd_destroy()
/* Eru wont be happy */
if (flags & TR_BLESSED)
{
- inc_piety(GOD_ERU, -10 * k_info[o_ptr->k_idx].level);
+ inc_piety(GOD_ERU, -10 * o_ptr->k_ptr->level);
}
/* Eliminate the item */
@@ -705,13 +679,13 @@ void do_cmd_observe()
/* Description */
char o_name[80];
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Describe */
cmsg_format(TERM_L_BLUE, "%s", o_name);
/* Describe it fully */
- if (!object_out_desc(o_ptr, NULL, FALSE, TRUE)) msg_print("You see nothing special.");
+ if (!object_out_desc(o_ptr, NULL, false, true)) msg_print("You see nothing special.");
}
@@ -776,7 +750,7 @@ void do_cmd_inscribe()
/* Describe the activity */
char o_name[80];
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Message */
msg_format("Inscribing %s.", o_name);
@@ -1032,7 +1006,7 @@ void do_cmd_locate()
x2 = x1 = panel_col_min;
/* Show panels until done */
- while (1)
+ while (true)
{
/* Describe the location */
if ((y2 == y1) && (x2 == x1))
@@ -1119,7 +1093,7 @@ void do_cmd_locate()
* The table of "symbol info" -- each entry is a string of the form
* "X:desc" where "X" is the trigger, and "desc" is the "info".
*/
-static cptr ident_info[] =
+static const char *ident_info[] =
{
" :A dark grid",
"!:A potion (or oil)",
@@ -1350,19 +1324,19 @@ void do_cmd_query_symbol()
char buf[128];
- bool_ all = FALSE;
+ bool all = false;
- bool_ uniq = FALSE;
+ bool uniq = false;
- bool_ norm = FALSE;
+ bool norm = false;
- bool_ name = FALSE;
+ bool name = false;
char temp[80] = "";
- bool_ recall = FALSE;
+ bool recall = false;
bool (*sort_by)(int,int) = nullptr;
@@ -1380,22 +1354,22 @@ void do_cmd_query_symbol()
/* Describe */
if (sym == KTRL('A'))
{
- all = TRUE;
+ all = true;
strcpy(buf, "Full monster list.");
}
else if (sym == KTRL('U'))
{
- all = uniq = TRUE;
+ all = uniq = true;
strcpy(buf, "Unique monster list.");
}
else if (sym == KTRL('N'))
{
- all = norm = TRUE;
+ all = norm = true;
strcpy(buf, "Non-unique monster list.");
}
else if (sym == KTRL('M'))
{
- all = name = TRUE;
+ all = name = true;
if (!get_string("Name:", temp, 70)) return;
strnfmt(buf, 128, "Monsters with a name \"%s\"", temp);
strlower(temp);
@@ -1491,7 +1465,7 @@ void do_cmd_query_symbol()
i = who.size() - 1;
/* Scan the monster memory */
- while (1)
+ while (true)
{
/* Extract a race */
auto r_idx = who[i];
@@ -1509,14 +1483,13 @@ void do_cmd_query_symbol()
Term_addstr( -1, TERM_WHITE, " [(r)ecall, ESC]");
/* Interact */
- while (1)
+ while (true)
{
/* Recall */
if (recall)
{
/* Save the screen */
- character_icky = TRUE;
- Term_save();
+ screen_save_no_flush();
/* Recall on screen */
screen_roff(who[i], 0);
@@ -1532,8 +1505,7 @@ void do_cmd_query_symbol()
if (recall)
{
/* Restore */
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
}
/* Normal commands */
@@ -1575,7 +1547,7 @@ void do_cmd_query_symbol()
/*
* Try to "sense" the grid's mana
*/
-bool_ do_cmd_sense_grid_mana()
+void do_cmd_sense_grid_mana()
{
int chance, i;
@@ -1603,7 +1575,7 @@ bool_ do_cmd_sense_grid_mana()
{
flush_on_failure();
msg_print("You failed to sense the grid's mana.");
- return FALSE;
+ return;
}
/* Try to give an "average" value */
@@ -1619,14 +1591,13 @@ bool_ do_cmd_sense_grid_mana()
{
msg_format("Average Area's mana: %d", (cave[p_ptr->py][p_ptr->px].mana / i) * i);
}
- return TRUE;
}
/*
* Try to add a CLI action.
*/
-void cli_add(cptr active, cptr trigger, cptr descr)
+void cli_add(const char *active, const char *trigger, const char *descr)
{
s16b num;
cli_comm *cli_ptr, *old_ptr;
@@ -1662,7 +1633,7 @@ void cli_add(cptr active, cptr trigger, cptr descr)
if (strchr(trigger, '\''))
{
char temp[80], *t;
- cptr s;
+ const char *s;
for (s = trigger, t = temp; ; s++, t++)
{
/* tokenize() causes each ' to be followed by another character,
@@ -1707,9 +1678,9 @@ void cli_add(cptr active, cptr trigger, cptr descr)
/*
* Get a string using CLI completion.
*/
-static bool_ get_string_cli(cptr prompt, char *buf, int len)
+static bool get_string_cli(const char *prompt, char *buf, int len)
{
- bool_ res;
+ bool res;
/* Paranoia XXX XXX XXX */
@@ -1756,7 +1727,7 @@ void do_cmd_cli()
/* Analyse the input */
for (cli_ptr = cli_info; cli_ptr->comm; cli_ptr++)
{
- if (!strcmp(buff, cli_ptr->comm))
+ if (equals(buff, cli_ptr->comm))
{
/* Process the command without keymaps or macros. */
command_new = cli_ptr->key;
@@ -1790,20 +1761,14 @@ void do_cmd_cli_help()
}
}
- /* Enter "icky" mode */
- character_icky = TRUE;
-
/* Save the screen */
- Term_save();
+ screen_save_no_flush();
/* Display the file contents */
show_string(w.c_str(), "Command line help");
/* Restore the screen */
- Term_load();
-
- /* Leave "icky" mode */
- character_icky = FALSE;
+ screen_load_no_flush();
}
@@ -1813,14 +1778,14 @@ void do_cmd_cli_help()
void do_cmd_html_dump()
{
char tmp_val[81];
- bool_ html = TRUE;
+ bool html = true;
term_win *save;
/* Save the screen */
save = Term_save_to();
if (wizard && get_check("WIZARD MODE: Do an help file dump?"))
- html = FALSE;
+ html = false;
/* Ask for a file */
if (html)
diff --git a/src/cmd3.hpp b/src/cmd3.hpp
index 97d3e22f..0212526c 100644
--- a/src/cmd3.hpp
+++ b/src/cmd3.hpp
@@ -1,9 +1,9 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void do_cmd_html_dump();
-void cli_add(cptr active, cptr trigger, cptr descr);
+void cli_add(const char *active, const char *trigger, const char *descr);
void do_cmd_cli();
void do_cmd_cli_help();
void do_cmd_inven();
@@ -20,4 +20,4 @@ void do_cmd_target();
void do_cmd_look();
void do_cmd_locate();
void do_cmd_query_symbol();
-bool_ do_cmd_sense_grid_mana();
+void do_cmd_sense_grid_mana();
diff --git a/src/cmd4.cc b/src/cmd4.cc
index a820da41..b24cc72d 100644
--- a/src/cmd4.cc
+++ b/src/cmd4.cc
@@ -35,20 +35,23 @@
#include "tables.hpp"
#include "town_type.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "xtra1.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
#include <algorithm>
+#include <boost/algorithm/string/predicate.hpp>
#include <cassert>
#include <fmt/format.h>
#include <memory>
#include <numeric>
#include <string>
+#include <unordered_set>
#include <vector>
+using boost::algorithm::equals;
+
/*
* Hack -- redraw the screen
*
@@ -62,13 +65,8 @@
*/
void do_cmd_redraw()
{
- int j;
-
- term *old = Term;
-
-
/* Hack -- react to changes */
- Term_xtra(TERM_XTRA_REACT, 0);
+ Term_xtra_react();
/* Combine and Reorder the pack (later) */
@@ -108,22 +106,16 @@ void do_cmd_redraw()
/* Redraw every window */
- for (j = 0; j < 8; j++)
+ for (int j = 0; j < 8; j++)
{
/* Dead window */
if (!angband_term[j]) continue;
- /* Activate */
- Term_activate(angband_term[j]);
-
/* Redraw */
- Term_redraw();
-
- /* Refresh */
- Term_fresh();
-
- /* Restore */
- Term_activate(old);
+ Term_with_active(angband_term[j], []() {
+ Term_redraw();
+ Term_fresh();
+ });
}
}
@@ -140,14 +132,11 @@ void do_cmd_change_name()
char tmp[160];
- /* Enter "icky" mode */
- character_icky = TRUE;
-
/* Save the screen */
- Term_save();
+ screen_save_no_flush();
/* Forever */
- while (1)
+ while (true)
{
/* keep mode below 5 */
mode = (mode + 5) % 5;
@@ -185,7 +174,7 @@ void do_cmd_change_name()
{
if (tmp[0] && (tmp[0] != ' '))
{
- file_character(tmp, FALSE);
+ file_character(tmp);
}
}
}
@@ -237,11 +226,7 @@ void do_cmd_change_name()
}
/* Restore the screen */
- Term_load();
-
- /* Leave "icky" mode */
- character_icky = FALSE;
-
+ screen_load_no_flush();
/* Redraw everything */
p_ptr->redraw |= (PR_WIPE | PR_FRAME | PR_MAP);
@@ -259,7 +244,7 @@ void do_cmd_message_one()
auto message = messages.at(0);
- cptr msg = format("> %s", message.text_with_count().c_str());
+ const char *msg = format("> %s", message.text_with_count().c_str());
/* Recall one message XXX XXX XXX */
display_message(0, 0, strlen(msg), message.color, msg);
@@ -300,14 +285,11 @@ void do_cmd_messages()
/* Start at leftmost edge */
u32b q = 0;
- /* Enter "icky" mode */
- character_icky = TRUE;
-
/* Save the screen */
- Term_save();
+ screen_save_no_flush();
/* Process requests until done */
- while (1)
+ while (true)
{
/* Clear screen */
Term_clear();
@@ -483,10 +465,7 @@ void do_cmd_messages()
}
/* Restore the screen */
- Term_load();
-
- /* Leave "icky" mode */
- character_icky = FALSE;
+ screen_load_no_flush();
}
// File-local
@@ -514,7 +493,7 @@ static void interact_with_options(std::vector<option_type> const &options, char
/* Interact with the player */
size_t k = 0; /* Currently selected option index */
- while (TRUE)
+ while (true)
{
/* Prompt XXX XXX XXX */
char buf[80];
@@ -540,7 +519,7 @@ static void interact_with_options(std::vector<option_type> const &options, char
}
/* Hilite current option */
- move_cursor(k + 2, 50);
+ Term_gotoxy(50, k + 2);
/* Get a key */
int ch = inkey();
@@ -591,7 +570,7 @@ static void interact_with_options(std::vector<option_type> const &options, char
{
break;
}
- *(options[k].o_var) = TRUE;
+ *(options[k].o_var) = true;
k = (k + 1) % n;
break;
}
@@ -605,7 +584,7 @@ static void interact_with_options(std::vector<option_type> const &options, char
break;
}
- *(options[k].o_var) = FALSE;
+ *(options[k].o_var) = false;
k = (k + 1) % n;
break;
}
@@ -627,12 +606,12 @@ static void interact_with_options(std::vector<option_type> const &options, char
/*
* Interact with some options for cheating
*/
-static void do_cmd_options_cheat(cptr info)
+static void do_cmd_options_cheat(const char *info)
{
// Interact
interact_with_options(options->cheat_options, info, interaction_mode_t::READ_WRITE);
- // If user toggled any of the options to TRUE, then we add those cheats
+ // If user toggled any of the options to true, then we add those cheats
// to the player's "noscore" flags. Note that it doesn't matter what the
// previous value was -- we don't "unset" noscore flags anyway.
for (auto const &option: options->cheat_options)
@@ -664,7 +643,7 @@ s16b toggle_frequency(s16b current)
/*
* Interact with some options for cheating
*/
-static void do_cmd_options_autosave(cptr info)
+static void do_cmd_options_autosave(const char *info)
{
char ch;
@@ -681,7 +660,7 @@ static void do_cmd_options_autosave(cptr info)
Term_clear();
/* Interact with the player */
- while (TRUE)
+ while (true)
{
/* Prompt XXX XXX XXX */
strnfmt(buf, 80,
@@ -712,7 +691,7 @@ static void do_cmd_options_autosave(cptr info)
/* Hilite current option */
- move_cursor(k + 2, 50);
+ Term_gotoxy(50, k + 2);
/* Get a key */
ch = inkey();
@@ -754,7 +733,7 @@ static void do_cmd_options_autosave(cptr info)
case 'Y':
case '6':
{
- (*options->autosave_options[k].o_var) = TRUE;
+ (*options->autosave_options[k].o_var) = true;
k = (k + 1) % n;
break;
@@ -764,7 +743,7 @@ static void do_cmd_options_autosave(cptr info)
case 'N':
case '4':
{
- (*options->autosave_options[k].o_var) = FALSE;
+ (*options->autosave_options[k].o_var) = false;
k = (k + 1) % n;
break;
@@ -793,7 +772,7 @@ static void do_cmd_options_autosave(cptr info)
/*
* Interact with some options
*/
-void do_cmd_options_aux(int page, cptr info, bool_ read_only)
+void do_cmd_options_aux(int page, const char *info, bool read_only)
{
// Scrape together all the options from the relevant page.
std::vector<option_type> page_options;
@@ -820,42 +799,24 @@ void do_cmd_options_aux(int page, cptr info, bool_ read_only)
*/
static void do_cmd_options_win()
{
- int i, j, d;
-
- int y = 0;
-
int x = 0;
-
- char ch;
-
- bool_ go = TRUE;
-
- u32b old_flag[8];
-
-
- /* Memorize old flags */
- for (j = 0; j < ANGBAND_TERM_MAX; j++)
- {
- /* Acquire current flags */
- old_flag[j] = window_flag[j];
- }
-
+ int y = 0;
/* Clear screen */
Term_clear();
/* Interact */
- while (go)
+ while (bool go = true)
{
/* Prompt XXX XXX XXX */
prt("Window Flags (<dir>, t, y, n, ESC) ", 0, 0);
/* Display the windows */
- for (j = 0; j < ANGBAND_TERM_MAX; j++)
+ for (int j = 0; j < ANGBAND_TERM_MAX; j++)
{
byte a = TERM_WHITE;
- cptr s = angband_term_name[j];
+ const char *s = angband_term_name[j];
/* Use color */
if (j == x) a = TERM_L_BLUE;
@@ -865,11 +826,11 @@ static void do_cmd_options_win()
}
/* Display the options */
- for (i = 0; i < 16; i++)
+ for (int i = 0; i < 16; i++)
{
byte a = TERM_WHITE;
- cptr str = window_flag_desc[i];
+ const char *str = window_flag_desc[i];
/* Use color */
if (i == y) a = TERM_L_BLUE;
@@ -881,7 +842,7 @@ static void do_cmd_options_win()
Term_putstr(0, i + 5, -1, a, str);
/* Display the windows */
- for (j = 0; j < ANGBAND_TERM_MAX; j++)
+ for (int j = 0; j < ANGBAND_TERM_MAX; j++)
{
byte a = TERM_WHITE;
@@ -902,14 +863,14 @@ static void do_cmd_options_win()
Term_gotoxy(35 + x * 5, y + 5);
/* Get key */
- ch = inkey();
+ char ch = inkey();
/* Analyze */
switch (ch)
{
case ESCAPE:
{
- go = FALSE;
+ go = false;
break;
}
@@ -918,13 +879,13 @@ static void do_cmd_options_win()
case 't':
{
/* Clear windows */
- for (j = 0; j < ANGBAND_TERM_MAX; j++)
+ for (int j = 0; j < ANGBAND_TERM_MAX; j++)
{
window_flag[j] &= ~(1L << y);
}
/* Clear flags */
- for (i = 0; i < 16; i++)
+ for (int i = 0; i < 16; i++)
{
window_flag[x] &= ~(1L << i);
}
@@ -955,7 +916,7 @@ static void do_cmd_options_win()
default:
{
- d = get_keymap_dir(ch);
+ int d = get_keymap_dir(ch);
x = (x + ddx[d] + 8) % 8;
y = (y + ddy[d] + 16) % 16;
@@ -967,28 +928,17 @@ static void do_cmd_options_win()
}
}
- /* Notice changes */
- for (j = 0; j < ANGBAND_TERM_MAX; j++)
+ /* Refresh all the terms */
+ for (int j = 0; j < ANGBAND_TERM_MAX; j++)
{
- term *old = Term;
-
/* Dead window */
if (!angband_term[j]) continue;
- /* Ignore non-changes */
- if (window_flag[j] == old_flag[j]) continue;
-
- /* Activate */
- Term_activate(angband_term[j]);
-
- /* Erase */
- Term_clear();
-
- /* Refresh */
- Term_fresh();
-
- /* Restore */
- Term_activate(old);
+ /* Redraw */
+ Term_with_active(angband_term[j], [] {
+ Term_clear();
+ Term_fresh();
+ });
}
}
@@ -997,7 +947,7 @@ static void do_cmd_options_win()
* Write all current options to the given preference file in the
* lib/user directory. Modified from KAmband 1.8.
*/
-static errr option_dump(cptr fname)
+static errr option_dump(const char *fname)
{
int i, j;
@@ -1104,7 +1054,7 @@ static void do_cmd_pref_file_hack(int row)
prt("File: ", row + 2, 0);
/* Default filename */
- std::string ftmp = fmt::format("{}.prf", game->player_base);
+ auto ftmp = name_file_pref(game->player_base);
/* Ask for a file (or cancel) */
if (!askfor_aux(&ftmp, 80))
@@ -1113,7 +1063,7 @@ static void do_cmd_pref_file_hack(int row)
}
/* Process the given filename */
- if (process_pref_file(ftmp.c_str()))
+ if (process_pref_file(ftmp))
{
/* Mention failure */
msg_format("Failed to load '%s'!", ftmp.c_str());
@@ -1141,7 +1091,7 @@ void do_cmd_options()
screen_save();
/* Interact */
- while (1)
+ while (true)
{
/* Clear screen */
Term_clear();
@@ -1209,7 +1159,7 @@ void do_cmd_options()
prt("File: ", 21, 0);
/* Default filename */
- auto ftmp = fmt::format("{}.prf", game->player_base);
+ auto ftmp = name_file_pref(game->player_base);
/* Ask for a file */
if (!askfor_aux(&ftmp, 80)) continue;
@@ -1233,7 +1183,7 @@ void do_cmd_options()
case '1':
{
/* Process the general options */
- do_cmd_options_aux(1, "User Interface Options", FALSE);
+ do_cmd_options_aux(1, "User Interface Options", false);
break;
}
@@ -1242,7 +1192,7 @@ void do_cmd_options()
case '2':
{
/* Spawn */
- do_cmd_options_aux(2, "Disturbance Options", FALSE);
+ do_cmd_options_aux(2, "Disturbance Options", false);
break;
}
@@ -1251,7 +1201,7 @@ void do_cmd_options()
case '3':
{
/* Spawn */
- do_cmd_options_aux(3, "Game-Play Options", FALSE);
+ do_cmd_options_aux(3, "Game-Play Options", false);
break;
}
@@ -1260,7 +1210,7 @@ void do_cmd_options()
case '4':
{
/* Spawn */
- do_cmd_options_aux(4, "Efficiency Options", FALSE);
+ do_cmd_options_aux(4, "Efficiency Options", false);
break;
}
@@ -1268,7 +1218,7 @@ void do_cmd_options()
/* ToME Options */
case '5':
{
- do_cmd_options_aux(5, "ToME Options", FALSE);
+ do_cmd_options_aux(5, "ToME Options", false);
break;
}
@@ -1276,7 +1226,7 @@ void do_cmd_options()
/* Birth Options - read only */
case '6':
{
- do_cmd_options_aux(6, "Birth Options(read only)", TRUE);
+ do_cmd_options_aux(6, "Birth Options(read only)", true);
break;
}
@@ -1322,7 +1272,7 @@ void do_cmd_options()
prt("Command: Base Delay Factor", 21, 0);
/* Get a new value */
- while (1)
+ while (true)
{
auto const msec = options->delay_factor_ms();
@@ -1357,7 +1307,7 @@ void do_cmd_options()
prt("Command: Hitpoint Warning", 18, 0);
/* Get a new value */
- while (1)
+ while (true)
{
prt(fmt::format("Current hitpoint warning: {:d}0%",
options->hitpoint_warn), 22, 0);
@@ -1427,7 +1377,7 @@ void do_cmd_pref()
/*
* Hack -- append all current macros to the given file
*/
-static errr macro_dump(cptr fname)
+static errr macro_dump(const char *fname)
{
int i;
@@ -1493,7 +1443,7 @@ static errr macro_dump(cptr fname)
*
* Note that both "flush()" calls are extremely important.
*/
-static void do_cmd_macro_aux(char *buf, bool_ macro_screen)
+static void do_cmd_macro_aux(char *buf, bool macro_screen)
{
int i, n = 0;
@@ -1504,7 +1454,7 @@ static void do_cmd_macro_aux(char *buf, bool_ macro_screen)
flush();
/* Do not process macros */
- inkey_base = TRUE;
+ inkey_base = true;
/* First key */
i = inkey();
@@ -1516,7 +1466,7 @@ static void do_cmd_macro_aux(char *buf, bool_ macro_screen)
buf[n++] = i;
/* Do not process macros */
- inkey_base = TRUE;
+ inkey_base = true;
/* Attempt to read a key */
i = inkey_scan();
@@ -1574,7 +1524,7 @@ static void do_cmd_macro_aux_keymap(char *buf)
/*
* Hack -- append all keymaps to the given file
*/
-static errr keymap_dump(cptr fname)
+static errr keymap_dump(const char *fname)
{
int i;
@@ -1608,7 +1558,7 @@ static errr keymap_dump(cptr fname)
/* Dump them */
for (i = 0; i < 256; i++)
{
- cptr act;
+ const char *act;
/* Loop up the keymap */
act = keymap_act[mode][i];
@@ -1654,16 +1604,11 @@ void do_cmd_macros()
/* Keymap mode */
int mode = get_keymap_mode();
-
- /* Enter "icky" mode */
- character_icky = TRUE;
-
/* Save screen */
- Term_save();
-
+ screen_save_no_flush();
/* Process requests until done */
- while (1)
+ while (true)
{
char buf[1024];
@@ -1715,7 +1660,7 @@ void do_cmd_macros()
prt("File: ", 18, 0);
/* Default filename */
- auto tmp = fmt::format("{}.prf", game->player_name);
+ auto tmp = name_file_pref(game->player_name);
/* Ask for a file */
if (!askfor_aux(&tmp, 80))
@@ -1724,7 +1669,7 @@ void do_cmd_macros()
}
/* Process the given filename */
- if (0 != process_pref_file(tmp.c_str()))
+ if (0 != process_pref_file(tmp))
{
/* Prompt */
msg_print("Could not load file!");
@@ -1741,7 +1686,7 @@ void do_cmd_macros()
prt("File: ", 18, 0);
/* Default filename */
- auto tmp = fmt::format("{}.prf", game->player_name);
+ auto tmp = name_file_pref(game->player_name);
/* Ask for a file */
if (!askfor_aux(&tmp, 80))
@@ -1768,7 +1713,7 @@ void do_cmd_macros()
prt("Trigger: ", 18, 0);
/* Get a macro trigger */
- do_cmd_macro_aux(buf, TRUE);
+ do_cmd_macro_aux(buf, true);
/* Acquire action */
k = macro_find_exact(buf);
@@ -1809,7 +1754,7 @@ void do_cmd_macros()
prt("Trigger: ", 18, 0);
/* Get a macro trigger */
- do_cmd_macro_aux(buf, TRUE);
+ do_cmd_macro_aux(buf, true);
/* Clear */
clear_from(20);
@@ -1844,7 +1789,7 @@ void do_cmd_macros()
prt("Trigger: ", 18, 0);
/* Get a macro trigger */
- do_cmd_macro_aux(buf, TRUE);
+ do_cmd_macro_aux(buf, true);
/* Link the macro */
macro_add(buf, buf);
@@ -1863,7 +1808,7 @@ void do_cmd_macros()
prt("File: ", 18, 0);
/* Default filename */
- auto tmp = fmt::format("{}.prf", game->player_name);
+ auto tmp = name_file_pref(game->player_name);
/* Ask for a file */
if (!askfor_aux(&tmp, 80))
@@ -1881,7 +1826,7 @@ void do_cmd_macros()
/* Query a keymap */
else if (i == '7')
{
- cptr act;
+ const char *act;
/* Prompt */
prt("Command: Query a keymap", 16, 0);
@@ -1980,8 +1925,6 @@ void do_cmd_macros()
/* Enter a new action */
else if (i == '0')
{
- char tmp[1024];
-
/* Prompt */
prt("Command: Enter a new action", 16, 0);
@@ -1989,7 +1932,7 @@ void do_cmd_macros()
Term_gotoxy(0, 22);
/* Hack -- limit the value */
- tmp[80] = '\0';
+ buf[80] = '\0';
/* Get an encoded action */
if (!askfor_aux(buf, 80)) continue;
@@ -2010,10 +1953,7 @@ void do_cmd_macros()
}
/* Load screen */
- Term_load();
-
- /* Leave "icky" mode */
- character_icky = FALSE;
+ screen_load_no_flush();
}
@@ -2026,24 +1966,13 @@ void do_cmd_visuals()
auto &f_info = game->edit_data.f_info;
auto &k_info = game->edit_data.k_info;
- int i;
-
- FILE *fff;
-
- char tmp[160];
-
char buf[1024];
-
- /* Enter "icky" mode */
- character_icky = TRUE;
-
/* Save the screen */
- Term_save();
-
+ screen_save_no_flush();
/* Interact until done */
- while (1)
+ while (true)
{
/* Clear screen */
Term_clear();
@@ -2067,7 +1996,7 @@ void do_cmd_visuals()
prt("Command: ", 15, 0);
/* Prompt */
- i = inkey();
+ int i = inkey();
/* Done */
if (i == ESCAPE) break;
@@ -2082,10 +2011,10 @@ void do_cmd_visuals()
prt("File: ", 17, 0);
/* Default filename */
- strnfmt(tmp, 160, "user-%s.prf", ANGBAND_SYS);
+ auto tmp = name_file_pref(fmt::format("user-{}", ANGBAND_SYS));
/* Query */
- if (!askfor_aux(tmp, 70)) continue;
+ if (!askfor_aux(&tmp, 70)) continue;
/* Process the given filename */
process_pref_file(tmp);
@@ -2101,16 +2030,16 @@ void do_cmd_visuals()
prt("File: ", 17, 0);
/* Default filename */
- strnfmt(tmp, 160, "user-%s.prf", ANGBAND_SYS);
+ auto tmp = name_file_pref(fmt::format("user-{}", ANGBAND_SYS));
/* Get a filename */
- if (!askfor_aux(tmp, 70)) continue;
+ if (!askfor_aux(&tmp, 70)) continue;
/* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_USER, tmp);
+ path_build(buf, 1024, ANGBAND_DIR_USER, tmp.c_str());
/* Append to the file */
- fff = my_fopen(buf, "a");
+ FILE *fff = my_fopen(buf, "a");
/* Failure */
if (!fff) continue;
@@ -2156,16 +2085,16 @@ void do_cmd_visuals()
prt("File: ", 17, 0);
/* Default filename */
- strnfmt(tmp, 160, "user-%s.prf", ANGBAND_SYS);
+ auto tmp = name_file_pref(fmt::format("user-{}", ANGBAND_SYS));
/* Get a filename */
- if (!askfor_aux(tmp, 70)) continue;
+ if (!askfor_aux(&tmp, 70)) continue;
/* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_USER, tmp);
+ path_build(buf, 1024, ANGBAND_DIR_USER, tmp.c_str());
/* Append to the file */
- fff = my_fopen(buf, "a");
+ FILE *fff = my_fopen(buf, "a");
/* Failure */
if (!fff) continue;
@@ -2175,18 +2104,15 @@ void do_cmd_visuals()
fprintf(fff, "# Object attr/char definitions\n\n");
/* Dump objects */
- for (std::size_t k = 0; k < k_info.size(); k++)
+ for (auto const &k_entry: k_info)
{
- object_kind *k_ptr = &k_info[k];
-
- /* Skip non-entries */
- if (!k_ptr->name) continue;
+ auto const k_ptr = k_entry.second;
/* Dump a comment */
- fprintf(fff, "# %s\n", k_ptr->name);
+ fprintf(fff, "# %s\n", k_ptr->name.c_str());
/* Dump the object attr/char info */
- fprintf(fff, "K:%zu:0x%02X:0x%02X\n\n", k,
+ fprintf(fff, "K:%d:0x%02X:0x%02X\n\n", k_entry.first,
(byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
}
@@ -2210,16 +2136,16 @@ void do_cmd_visuals()
prt("File: ", 17, 0);
/* Default filename */
- strnfmt(tmp, 160, "user-%s.prf", ANGBAND_SYS);
+ auto tmp = name_file_pref(fmt::format("user-{}", ANGBAND_SYS));
/* Get a filename */
- if (!askfor_aux(tmp, 70)) continue;
+ if (!askfor_aux(&tmp, 70)) continue;
/* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_USER, tmp);
+ path_build(buf, 1024, ANGBAND_DIR_USER, tmp.c_str());
/* Append to the file */
- fff = my_fopen(buf, "a");
+ FILE *fff = my_fopen(buf, "a");
/* Failure */
if (!fff) continue;
@@ -2234,10 +2160,13 @@ void do_cmd_visuals()
auto f_ptr = &f_info[f_idx];
/* Skip non-entries */
- if (!f_ptr->name) continue;
+ if (f_ptr->name.empty())
+ {
+ continue;
+ }
/* Dump a comment */
- fprintf(fff, "# %s\n", f_ptr->name);
+ fprintf(fff, "# %s\n", f_ptr->name.c_str());
/* Dump the feature attr/char info */
fprintf(fff, "F:%zu:0x%02X:0x%02X\n\n", f_idx,
@@ -2263,7 +2192,7 @@ void do_cmd_visuals()
prt("Command: Change monster attr/chars", 15, 0);
/* Hack -- query until done */
- while (1)
+ while (true)
{
auto r_ptr = &r_info[r];
@@ -2312,15 +2241,18 @@ void do_cmd_visuals()
/* Modify object attr/chars */
else if (i == '7')
{
- static int k = 0;
+ static auto const k_info_keys =
+ game->edit_data.k_info_keys();
+
+ static int k_idx = 0;
/* Prompt */
prt("Command: Change object attr/chars", 15, 0);
/* Hack -- query until done */
- while (1)
+ while (true)
{
- object_kind *k_ptr = &k_info[k];
+ auto k_ptr = k_info.at(k_info_keys[k_idx]);
byte da = k_ptr->d_attr;
char dc = k_ptr->d_char;
@@ -2330,7 +2262,7 @@ void do_cmd_visuals()
/* Label the object */
Term_putstr(5, 17, -1, TERM_WHITE,
format("Object = %d, Name = %-40.40s",
- k, k_ptr->name));
+ k_info_keys[k_idx], k_ptr->name.c_str()));
/* Label the Default values */
Term_putstr(10, 19, -1, TERM_WHITE,
@@ -2355,12 +2287,12 @@ void do_cmd_visuals()
if (i == ESCAPE) break;
/* Analyze */
- if (i == 'n') k = (k + k_info.size() + 1) % k_info.size();
- if (i == 'N') k = (k + k_info.size() - 1) % k_info.size();
- if (i == 'a') k_info[k].x_attr = (ca + 1);
- if (i == 'A') k_info[k].x_attr = (ca - 1);
- if (i == 'c') k_info[k].x_char = (cc + 1);
- if (i == 'C') k_info[k].x_char = (cc - 1);
+ if (i == 'n') k_idx = (k_idx + k_info_keys.size() + 1) % k_info_keys.size();
+ if (i == 'N') k_idx = (k_idx + k_info_keys.size() - 1) % k_info_keys.size();
+ if (i == 'a') k_ptr->x_attr = (ca + 1);
+ if (i == 'A') k_ptr->x_attr = (ca - 1);
+ if (i == 'c') k_ptr->x_char = (cc + 1);
+ if (i == 'C') k_ptr->x_char = (cc - 1);
}
}
@@ -2373,7 +2305,7 @@ void do_cmd_visuals()
prt("Command: Change feature attr/chars", 15, 0);
/* Hack -- query until done */
- while (1)
+ while (true)
{
auto f_ptr = &f_info[f];
@@ -2385,7 +2317,7 @@ void do_cmd_visuals()
/* Label the object */
Term_putstr(5, 17, -1, TERM_WHITE,
format("Terrain = %d, Name = %-40.40s",
- f, f_ptr->name));
+ f, f_ptr->name.c_str()));
/* Label the Default values */
Term_putstr(10, 19, -1, TERM_WHITE,
@@ -2446,10 +2378,7 @@ void do_cmd_visuals()
/* Restore the screen */
- Term_load();
-
- /* Leave "icky" mode */
- character_icky = FALSE;
+ screen_load_no_flush();
}
@@ -2462,20 +2391,13 @@ void do_cmd_colors()
FILE *fff;
- char tmp[160];
-
char buf[1024];
-
- /* Enter "icky" mode */
- character_icky = TRUE;
-
/* Save the screen */
- Term_save();
-
+ screen_save_no_flush();
/* Interact until done */
- while (1)
+ while (true)
{
/* Clear screen */
Term_clear();
@@ -2507,16 +2429,16 @@ void do_cmd_colors()
prt("File: ", 10, 0);
/* Default file */
- strnfmt(tmp, 160, "user-%s.prf", ANGBAND_SYS);
+ auto tmp = name_file_pref(fmt::format("user-{}", ANGBAND_SYS));
/* Query */
- if (!askfor_aux(tmp, 70)) continue;
+ if (!askfor_aux(&tmp, 70)) continue;
/* Process the given filename */
process_pref_file(tmp);
/* Mega-Hack -- react to changes */
- Term_xtra(TERM_XTRA_REACT, 0);
+ Term_xtra_react();
/* Mega-Hack -- redraw */
Term_redraw();
@@ -2532,13 +2454,13 @@ void do_cmd_colors()
prt("File: ", 10, 0);
/* Default filename */
- strnfmt(tmp, 160, "user-%s.prf", ANGBAND_SYS);
+ auto tmp = name_file_pref(fmt::format("user-{}", ANGBAND_SYS));
/* Get a filename */
- if (!askfor_aux(tmp, 70)) continue;
+ if (!askfor_aux(&tmp, 70)) continue;
/* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_USER, tmp);
+ path_build(buf, 1024, ANGBAND_DIR_USER, tmp.c_str());
/* Append to the file */
fff = my_fopen(buf, "a");
@@ -2558,7 +2480,7 @@ void do_cmd_colors()
int gv = angband_color_table[i][2];
int bv = angband_color_table[i][3];
- cptr name = "unknown";
+ const char *name = "unknown";
/* Skip non-entries */
if (!kv && !rv && !gv && !bv) continue;
@@ -2593,9 +2515,9 @@ void do_cmd_colors()
prt("Command: Modify colors", 8, 0);
/* Hack -- query until done */
- while (1)
+ while (true)
{
- cptr name;
+ const char *name;
/* Clear */
clear_from(10);
@@ -2648,7 +2570,7 @@ void do_cmd_colors()
if (i == 'B') angband_color_table[a][3] = (angband_color_table[a][3] - 1);
/* Hack -- react to changes */
- Term_xtra(TERM_XTRA_REACT, 0);
+ Term_xtra_react();
/* Hack -- redraw */
Term_redraw();
@@ -2667,10 +2589,7 @@ void do_cmd_colors()
/* Restore the screen */
- Term_load();
-
- /* Leave "icky" mode */
- character_icky = FALSE;
+ screen_load_no_flush();
}
@@ -2713,7 +2632,7 @@ void do_cmd_version()
/*
* Array of feeling strings
*/
-static cptr do_cmd_feeling_text[11] =
+static const char *do_cmd_feeling_text[11] =
{
"Looks like any other level.",
"You feel there is something special about this level.",
@@ -2736,6 +2655,7 @@ static cptr do_cmd_feeling_text[11] =
void do_cmd_feeling()
{
auto const &d_info = game->edit_data.d_info;
+ auto const &dungeon_flags = game->dungeon_flags;
/* Verify the feeling */
if (feeling < 0) feeling = 0;
@@ -2753,17 +2673,11 @@ void do_cmd_feeling()
return;
}
- /* No useful feeling in special levels */
- if (dungeon_flags & DF_DESC)
+ /* Do we have a description override? */
+ if (auto description = get_level_description())
{
- char buf[1024];
-
- if (get_dungeon_save(buf) || game->generate_special_feeling || (dungeon_flags & DF_DESC_ALWAYS))
- {
- if (!get_level_desc(buf)) msg_print("Someone forgot to describe this level!");
- else msg_print(buf);
- return;
- }
+ msg_print(*description);
+ return;
}
/* No useful feeling in quests */
@@ -2791,7 +2705,6 @@ void do_cmd_feeling()
else
msg_print(do_cmd_feeling_text[feeling]);
}
- return;
}
@@ -2815,7 +2728,7 @@ void do_cmd_load_screen()
byte a = 0;
char c = ' ';
- bool_ okay = TRUE;
+ bool okay = true;
FILE *fff;
@@ -2835,11 +2748,8 @@ void do_cmd_load_screen()
/* Retrieve the current screen size */
Term_get_size(&wid, &hgt);
- /* Enter "icky" mode */
- character_icky = TRUE;
-
/* Save the screen */
- Term_save();
+ screen_save_no_flush();
/* Clear the screen */
Term_clear();
@@ -2849,7 +2759,7 @@ void do_cmd_load_screen()
for (y = 0; okay; y++)
{
/* Get a line of data */
- if (my_fgets(fff, buf, 1024)) okay = FALSE;
+ if (my_fgets(fff, buf, 1024)) okay = false;
/* Stop on blank line */
if (!buf[0]) break;
@@ -2875,7 +2785,7 @@ void do_cmd_load_screen()
for (y = 0; okay; y++)
{
/* Get a line of data */
- if (my_fgets(fff, buf, 1024)) okay = FALSE;
+ if (my_fgets(fff, buf, 1024)) okay = false;
/* Stop on blank line */
if (!buf[0]) break;
@@ -2893,7 +2803,7 @@ void do_cmd_load_screen()
for (x = 0; x < len; x++)
{
/* Get the attr/char */
- (Term_what(x, y, &a, &c));
+ Term_what(x, y, &a, &c);
/* Look up the attr */
for (i = 0; i < 16; i++)
@@ -2918,10 +2828,7 @@ void do_cmd_load_screen()
/* Restore the screen */
- Term_load();
-
- /* Leave "icky" mode */
- character_icky = FALSE;
+ screen_load_no_flush();
}
@@ -2955,12 +2862,8 @@ void do_cmd_save_screen()
/* Retrieve the current screen size */
Term_get_size(&wid, &hgt);
- /* Enter "icky" mode */
- character_icky = TRUE;
-
/* Save the screen */
- Term_save();
-
+ screen_save_no_flush();
/* Dump the screen */
for (y = 0; y < hgt; y++)
@@ -2969,7 +2872,7 @@ void do_cmd_save_screen()
for (x = 0; x < wid; x++)
{
/* Get the attr/char */
- (Term_what(x, y, &a, &c));
+ Term_what(x, y, &a, &c);
/* Dump it */
buf[x] = c;
@@ -2993,7 +2896,7 @@ void do_cmd_save_screen()
for (x = 0; x < wid; x++)
{
/* Get the attr/char */
- (Term_what(x, y, &a, &c));
+ Term_what(x, y, &a, &c);
/* Dump it */
buf[x] = hack[a & 0x0F];
@@ -3020,10 +2923,7 @@ void do_cmd_save_screen()
/* Restore the screen */
- Term_load();
-
- /* Leave "icky" mode */
- character_icky = FALSE;
+ screen_load_no_flush();
}
@@ -3035,12 +2935,15 @@ void do_cmd_knowledge_artifacts()
auto const &k_info = game->edit_data.k_info;
auto const &a_info = game->edit_data.a_info;
+ auto const k_info_keys = game->edit_data.k_info_keys();
+
int i, z, x, y;
char base_name[80];
/* Scan the artifacts */
- std::vector<bool_> okay(a_info.size(), FALSE);
+ std::vector<bool> okay(a_info.size(), false);
+
for (std::size_t k = 0; k < a_info.size(); k++)
{
auto a_ptr = &a_info[k];
@@ -3052,13 +2955,13 @@ void do_cmd_knowledge_artifacts()
if (!a_ptr->cur_num) continue;
/* Assume okay */
- okay[k] = TRUE;
+ okay[k] = true;
}
- std::vector<bool_> okayk(k_info.size(), FALSE);
- for (std::size_t k = 0; k < k_info.size(); k++)
+ std::unordered_set<int> okayk;
+ for (auto const &k_entry: k_info)
{
- auto k_ptr = &k_info[k];
+ auto k_ptr = k_entry.second;
/* Skip "empty" artifacts */
if (!(k_ptr->flags & TR_NORM_ART)) continue;
@@ -3067,7 +2970,7 @@ void do_cmd_knowledge_artifacts()
if (!k_ptr->artifact) continue;
/* Assume okay */
- okayk[k] = TRUE;
+ okayk.insert(k_entry.first);
}
/* Check the dungeon */
@@ -3093,13 +2996,13 @@ void do_cmd_knowledge_artifacts()
if (object_known_p(o_ptr)) continue;
/* Note the artifact */
- if (k_info[o_ptr->k_idx].flags & TR_NORM_ART)
+ if (o_ptr->k_ptr->flags & TR_NORM_ART)
{
- okayk[o_ptr->k_idx] = FALSE;
+ okayk.erase(o_ptr->k_ptr->idx);
}
else
{
- okay[o_ptr->name1] = FALSE;
+ okay[o_ptr->name1] = false;
}
}
}
@@ -3111,10 +3014,8 @@ void do_cmd_knowledge_artifacts()
/* Scan all objects the monster carries */
for (auto const this_o_idx: m_list[i].hold_o_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
+ auto o_ptr = &o_list[this_o_idx];
/* Ignore random artifacts */
if (o_ptr->tval == TV_RANDART) continue;
@@ -3126,13 +3027,13 @@ void do_cmd_knowledge_artifacts()
if (object_known_p(o_ptr)) continue;
/* Note the artifact */
- if (k_info[o_ptr->k_idx].flags & TR_NORM_ART)
+ if (o_ptr->k_ptr->flags & TR_NORM_ART)
{
- okayk[o_ptr->k_idx] = FALSE;
+ okayk.erase(o_ptr->k_ptr->idx);
}
else
{
- okay[o_ptr->name1] = FALSE;
+ okay[o_ptr->name1] = false;
}
}
}
@@ -3140,10 +3041,10 @@ void do_cmd_knowledge_artifacts()
/* Check the p_ptr->inventory and equipment */
for (i = 0; i < INVEN_TOTAL; i++)
{
- object_type *o_ptr = &p_ptr->inventory[i];
+ auto o_ptr = &p_ptr->inventory[i];
/* Ignore non-objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr) continue;
/* Ignore random artifacts */
if (o_ptr->tval == TV_RANDART) continue;
@@ -3155,13 +3056,13 @@ void do_cmd_knowledge_artifacts()
if (object_known_p(o_ptr)) continue;
/* Note the artifact */
- if (k_info[o_ptr->k_idx].flags & TR_NORM_ART)
+ if (o_ptr->k_ptr->flags & TR_NORM_ART)
{
- okayk[o_ptr->k_idx] = FALSE;
+ okayk.erase(o_ptr->k_ptr->idx);
}
else
{
- okay[o_ptr->name1] = FALSE;
+ okay[o_ptr->name1] = false;
}
}
@@ -3205,36 +3106,35 @@ void do_cmd_knowledge_artifacts()
}
/* Describe the artifact */
- object_desc_store(base_name, q_ptr, FALSE, 0);
+ object_desc_store(base_name, q_ptr, false, 0);
}
/* Hack -- Build the artifact name */
w.write(" The {}\n", base_name);
}
- for (std::size_t k = 0; k < k_info.size(); k++)
+ for (auto const &k: k_info_keys)
{
/* List "dead" ones */
- if (!okayk[k]) continue;
+ if (!okayk.count(k))
+ {
+ continue;
+ }
/* Paranoia */
strcpy(base_name, "Unknown Artifact");
- /* Real object */
- if (k)
- {
- object_type forge;
- object_type *q_ptr;
+ object_type forge;
+ object_type *q_ptr;
- /* Get local object */
- q_ptr = &forge;
+ /* Get local object */
+ q_ptr = &forge;
- /* Create fake object */
- object_prep(q_ptr, k);
+ /* Create fake object */
+ object_prep(q_ptr, k);
- /* Describe the artifact */
- object_desc_store(base_name, q_ptr, FALSE, 0);
- }
+ /* Describe the artifact */
+ object_desc_store(base_name, q_ptr, false, 0);
/* Hack -- Build the artifact name */
w.write(" The {}\n", base_name);
@@ -3270,13 +3170,26 @@ static void do_cmd_knowledge_uniques()
{
auto r_ptr = &r_info[k];
- /* Only print Uniques */
- if ((r_ptr->flags & RF_UNIQUE) &&
- !(r_ptr->flags & RF_PET) &&
- !(r_ptr->flags & RF_NEUTRAL))
+ // Ignore non-uniques
+ if (!(r_ptr->flags & RF_UNIQUE))
+ {
+ continue;
+ }
+
+ // Exclude PET/NEUTRAL monsters
+ if ((r_ptr->flags & RF_PET) || (r_ptr->flags & RF_NEUTRAL))
{
- unique_r_idxs.push_back(k);
+ continue;
}
+
+ // Exclude JOKE monsters if we're playing without joke monsters
+ if (!options->joke_monsters && (r_ptr->flags & RF_JOKEANGBAND))
+ {
+ continue;
+ }
+
+ // Keep
+ unique_r_idxs.push_back(k);
}
// Sort races by level.
@@ -3295,7 +3208,7 @@ static void do_cmd_knowledge_uniques()
/* Only print Uniques */
if (r_ptr->flags & RF_UNIQUE)
{
- bool_ dead = (r_ptr->max_num == 0);
+ bool dead = (r_ptr->max_num == 0);
/* Print a message */
if (dead)
@@ -3333,10 +3246,10 @@ static void plural_aux(char *name)
/* "someone of something" */
else if (strstr(name, " of "))
{
- cptr aider = strstr(name, " of ");
+ const char *aider = strstr(name, " of ");
char dummy[80];
int i = 0;
- cptr ctr = name;
+ const char *ctr = name;
while (ctr < aider)
{
@@ -3380,25 +3293,25 @@ static void plural_aux(char *name)
{
strcpy(&name[name_len - 1], "ies");
}
- else if (name_len >= 4 && streq(&name[name_len - 4], "ouse"))
+ else if (name_len >= 4 && equals(&name[name_len - 4], "ouse"))
{
strcpy(&name[name_len - 4], "ice");
}
- else if (name_len >= 6 && streq(&name[name_len - 6], "kelman"))
+ else if (name_len >= 6 && equals(&name[name_len - 6], "kelman"))
{
strcpy(&name[name_len - 6], "kelmen");
}
- else if (name_len >= 2 && streq(&name[name_len - 2], "ex"))
+ else if (name_len >= 2 && equals(&name[name_len - 2], "ex"))
{
strcpy(&name[name_len - 2], "ices");
}
- else if (name_len >= 3 && streq(&name[name_len - 3], "olf"))
+ else if (name_len >= 3 && equals(&name[name_len - 3], "olf"))
{
strcpy(&name[name_len - 3], "olves");
}
/* Now begins sane cases */
- else if ((name_len >= 2 && streq(&name[name_len - 2], "ch")) || (name_len >= 1 && name[name_len - 1] == 's'))
+ else if ((name_len >= 2 && equals(&name[name_len - 2], "ch")) || (name_len >= 1 && name[name_len - 1] == 's'))
{
strcpy(&name[name_len], "es");
}
@@ -3525,7 +3438,7 @@ static void do_cmd_knowledge_kill_count()
if (r_ptr->flags & RF_UNIQUE)
{
- bool_ dead = (r_ptr->max_num == 0);
+ bool dead = (r_ptr->max_num == 0);
if (dead)
{
@@ -3573,48 +3486,6 @@ static void do_cmd_knowledge_kill_count()
/*
- * Display known objects
- */
-static void do_cmd_knowledge_objects()
-{
- auto const &k_info = game->edit_data.k_info;
-
- fmt::MemoryWriter w;
-
- /* Scan the object kinds */
- for (std::size_t k = 1; k < k_info.size(); k++)
- {
- auto k_ptr = &k_info[k];
-
- /* Hack -- skip artifacts */
- if (k_ptr->flags & (TR_INSTA_ART)) continue;
-
- /* List known flavored objects */
- if (k_ptr->flavor && k_ptr->aware)
- {
- object_type object_type_body;
-
- /* Get local object */
- object_type *i_ptr = &object_type_body;
-
- /* Create fake object */
- object_prep(i_ptr, k);
-
- /* Describe the object */
- char o_name[80];
- object_desc_store(o_name, i_ptr, FALSE, 0);
-
- /* Print a message */
- w.write(" {}\n", o_name);
- }
- }
-
- // Display
- show_string(w.c_str(), "Known Objects");
-}
-
-
-/*
* List recall depths
*/
static void do_cmd_knowledge_dungeons()
@@ -3761,9 +3632,6 @@ void do_cmd_knowledge_notes()
{
/* Spawn */
show_notes_file();
-
- /* Done */
- return;
}
@@ -3774,15 +3642,11 @@ void do_cmd_knowledge()
{
int i;
-
- /* Enter "icky" mode */
- character_icky = TRUE;
-
/* Save the screen */
- Term_save();
+ screen_save_no_flush();
/* Interact until done */
- while (1)
+ while (true)
{
/* Clear screen */
Term_clear();
@@ -3793,15 +3657,14 @@ void do_cmd_knowledge()
/* Give some choices */
prt("(1) Display known artifacts", 4, 5);
prt("(2) Display known uniques", 5, 5);
- prt("(3) Display known objects", 6, 5);
- prt("(4) Display kill count", 7, 5);
- prt("(5) Display recall depths", 8, 5);
- prt("(6) Display corruptions", 9, 5);
- prt("(7) Display current pets", 10, 5);
- prt("(8) Display current quests", 11, 5);
- prt("(9) Display current fates", 12, 5);
- prt("(0) Display known dungeon towns", 13, 5);
- prt("(A) Display notes", 14, 5);
+ prt("(3) Display kill count", 7, 5);
+ prt("(4) Display recall depths", 8, 5);
+ prt("(5) Display corruptions", 9, 5);
+ prt("(6) Display current pets", 10, 5);
+ prt("(7) Display current quests", 11, 5);
+ prt("(8) Display current fates", 12, 5);
+ prt("(9) Display known dungeon towns", 13, 5);
+ prt("(0) Display notes", 14, 5);
/* Prompt */
prt("Command: ", 16, 0);
@@ -3830,16 +3693,8 @@ void do_cmd_knowledge()
break;
}
- /* Objects */
- case '3':
- {
- do_cmd_knowledge_objects();
-
- break;
- }
-
/* Kill count */
- case '4':
+ case '3':
{
do_cmd_knowledge_kill_count();
@@ -3847,7 +3702,7 @@ void do_cmd_knowledge()
}
/* Recall depths */
- case '5':
+ case '4':
{
do_cmd_knowledge_dungeons();
@@ -3855,7 +3710,7 @@ void do_cmd_knowledge()
}
/* corruptions */
- case '6':
+ case '5':
{
do_cmd_knowledge_corruptions();
@@ -3863,7 +3718,7 @@ void do_cmd_knowledge()
}
/* Pets */
- case '7':
+ case '6':
{
do_cmd_knowledge_pets();
@@ -3871,7 +3726,7 @@ void do_cmd_knowledge()
}
/* Quests */
- case '8':
+ case '7':
{
do_cmd_knowledge_quests();
@@ -3879,7 +3734,7 @@ void do_cmd_knowledge()
}
/* Fates */
- case '9':
+ case '8':
{
do_cmd_knowledge_fates();
@@ -3887,7 +3742,7 @@ void do_cmd_knowledge()
}
/* Dungeon towns */
- case '0':
+ case '9':
{
do_cmd_knowledge_towns();
@@ -3895,8 +3750,7 @@ void do_cmd_knowledge()
}
/* Notes */
- case 'A':
- case 'a':
+ case '0':
{
do_cmd_knowledge_notes();
@@ -3917,10 +3771,7 @@ void do_cmd_knowledge()
}
/* Restore the screen */
- Term_load();
-
- /* Leave "icky" mode */
- character_icky = FALSE;
+ screen_load_no_flush();
}
@@ -3930,20 +3781,14 @@ void do_cmd_knowledge()
*/
void do_cmd_checkquest()
{
- /* Enter "icky" mode */
- character_icky = TRUE;
-
/* Save the screen */
- Term_save();
+ screen_save_no_flush();
/* Quest info */
do_cmd_knowledge_quests();
/* Restore the screen */
- Term_load();
-
- /* Leave "icky" mode */
- character_icky = FALSE;
+ screen_load_no_flush();
}
@@ -4132,7 +3977,7 @@ void macro_recorder_stop()
prt("Trigger: ", 0, 0);
/* Get a macro trigger */
- do_cmd_macro_aux(buf, FALSE);
+ do_cmd_macro_aux(buf, false);
/* Link the macro */
macro_add(buf, macro.c_str());
diff --git a/src/cmd4.hpp b/src/cmd4.hpp
index 39f1c16c..29f9134b 100644
--- a/src/cmd4.hpp
+++ b/src/cmd4.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void macro_recorder_start();
void macro_recorder_add(char c);
@@ -25,4 +25,4 @@ void do_cmd_checkquest();
void do_cmd_change_tactic(int i);
void do_cmd_change_movement(int i);
void do_cmd_time();
-void do_cmd_options_aux(int page, cptr info, bool_ read_only);
+void do_cmd_options_aux(int page, const char *info, bool read_only);
diff --git a/src/cmd5.cc b/src/cmd5.cc
index a93759b0..c030addd 100644
--- a/src/cmd5.cc
+++ b/src/cmd5.cc
@@ -37,12 +37,11 @@
#include "stats.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "wizard2.hpp"
#include "xtra1.hpp"
#include "xtra2.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
#include <boost/noncopyable.hpp>
@@ -91,29 +90,32 @@ static object_filter_t const &item_tester_hook_browsable()
/*
* Are we using a mage staff
*/
-bool_ is_magestaff()
+bool is_magestaff()
{
- int i;
-
-
- i = 0;
+ int i = 0;
while (p_ptr->body_parts[i] == INVEN_WIELD)
{
object_type *o_ptr = &p_ptr->inventory[INVEN_WIELD + i];
/* Wielding a mage staff */
- if ((o_ptr->k_idx) && (o_ptr->tval == TV_MSTAFF)) return (TRUE);
+ if ((o_ptr->k_ptr) && (o_ptr->tval == TV_MSTAFF))
+ {
+ return true;
+ }
/* Next slot */
i++;
/* Paranoia */
- if (i >= (INVEN_TOTAL - INVEN_WIELD)) break;
+ if (i >= (INVEN_TOTAL - INVEN_WIELD))
+ {
+ break;
+ }
}
/* Not wielding a mage staff */
- return (FALSE);
+ return false;
}
@@ -131,11 +133,9 @@ static int print_book(s16b sval, s32b spell_idx, object_type *obj)
for (auto spell_idx : school_book->spell_idxs)
{
byte color = TERM_L_DARK;
- bool_ is_ok;
char label[8];
- is_ok = is_ok_spell(spell_idx, obj->pval);
- if (is_ok)
+ if (is_ok_spell(spell_idx, obj->pval))
{
color = (get_mana(spell_idx) > get_power(spell_idx)) ? TERM_ORANGE : TERM_L_GREEN;
}
@@ -170,8 +170,7 @@ static void browse_school_spell(int book, int spell_idx, object_type *o_ptr)
I2A(0), I2A(num - 1));
/* Save the screen */
- character_icky = TRUE;
- Term_save();
+ screen_save_no_flush();
/* Display a list of spells */
print_book(book, spell_idx, o_ptr);
@@ -208,8 +207,7 @@ static void browse_school_spell(int book, int spell_idx, object_type *o_ptr)
/* Restore the screen */
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
/* Show choices */
window_stuff();
@@ -267,7 +265,7 @@ static void do_poly_wounds()
s16b change = damroll(p_ptr->lev, 5);
- bool_ Nasty_effect = (randint(5) == 1);
+ bool Nasty_effect = (randint(5) == 1);
if (!(wounds || hit_p || Nasty_effect)) return;
@@ -321,7 +319,7 @@ void do_poly_self()
}
/* Deformities are discriminated against! */
- dec_stat(A_CHR, randint(6), TRUE);
+ dec_stat(A_CHR, randint(6), true);
if (effect_msg[0])
{
@@ -358,7 +356,7 @@ void do_poly_self()
goalexpfact = 100 + 3 * rand_int(poly_power);
/* Roll until an appropriate selection is made */
- while (1)
+ while (true)
{
new_race = rand_int(race_info.size());
expfact = race_info[new_race].ps.exp;
@@ -450,7 +448,7 @@ void do_poly_self()
/*
* Fetch an item (teleport it right underneath the caster)
*/
-void fetch(int dir, int wgt, bool_ require_los)
+void fetch(int dir, int wgt, bool require_los)
{
/* Check to see if an object is already there */
if (!cave[p_ptr->py][p_ptr->px].o_idxs.empty())
@@ -492,7 +490,7 @@ void fetch(int dir, int wgt, bool_ require_los)
int ty = p_ptr->py; /* Where to drop the item */
int tx = p_ptr->px;
- while (1)
+ while (true)
{
ty += ddy[dir];
tx += ddx[dir];
@@ -529,7 +527,7 @@ void fetch(int dir, int wgt, bool_ require_los)
/* Feedback */
char o_name[80];
- object_desc(o_name, o_ptr, TRUE, 0);
+ object_desc(o_name, o_ptr, true, 0);
msg_format("%^s flies through the air to your feet.", o_name);
note_spot(p_ptr->py, p_ptr->px);
@@ -550,7 +548,7 @@ std::string symbiote_name(bool capitalize)
buf.reserve(32);
// Fallback; shouldn't ever be necessary
- if (!o_ptr->k_idx)
+ if (!o_ptr->k_ptr)
{
buf += "A non-existent symbiote";
}
@@ -667,12 +665,11 @@ static std::tuple<int, int> choose_monster_power(monster_race const *r_ptr, bool
label, (symbiosis ? "symbiote" : "body"));
/* Save the screen */
- character_icky = TRUE;
- Term_save();
+ screen_save_no_flush();
/* Get a spell from the user */
monster_power const *power = nullptr;
- bool_ flag = FALSE; // Nothing chosen yet
+ bool flag = false; // Nothing chosen yet
while (!flag)
{
/* Show the list */
@@ -732,7 +729,7 @@ static std::tuple<int, int> choose_monster_power(monster_race const *r_ptr, bool
char choice;
if (!get_com(out_val, &choice))
{
- flag = FALSE;
+ flag = false;
break;
}
@@ -757,7 +754,7 @@ static std::tuple<int, int> choose_monster_power(monster_race const *r_ptr, bool
else
{
/* Can't uppercase digits XXX XXX XXX */
- ask = FALSE;
+ ask = false;
i = choice - '0' + 26;
}
@@ -795,12 +792,11 @@ static std::tuple<int, int> choose_monster_power(monster_race const *r_ptr, bool
}
/* Stop the loop */
- flag = TRUE;
+ flag = true;
}
/* Restore the screen */
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
/* Abort if needed */
if (!flag || (power == nullptr))
@@ -817,6 +813,8 @@ static std::tuple<int, int> choose_monster_power(monster_race const *r_ptr, bool
*/
static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_spell_idx)
{
+ auto const &dungeon_flags = game->dungeon_flags;
+
assert(monster_spell_idx < monster_spell_flag_set::nbits);
/* Shorthand */
@@ -842,14 +840,14 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
case SF_MULTIPLY_IDX:
{
- do_cmd_wiz_named_friendly(p_ptr->body_monster, FALSE);
+ do_cmd_wiz_named_friendly(p_ptr->body_monster, false);
break;
}
case SF_S_ANIMAL_IDX:
{
- summon_specific_friendly(y, x, rlev, SUMMON_ANIMAL, TRUE);
+ summon_specific_friendly(y, x, rlev, SUMMON_ANIMAL, true);
break;
}
@@ -1469,7 +1467,7 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
{
for (int k = 0; k < 4; k++)
{
- summon_specific_friendly(y, x, rlev, SUMMON_ANIMAL, TRUE);
+ summon_specific_friendly(y, x, rlev, SUMMON_ANIMAL, true);
}
break;
@@ -1574,7 +1572,7 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
{
for (int k = 0; k < 1; k++)
{
- summon_specific_friendly(y, x, rlev, SUMMON_THUNDERLORD, TRUE);
+ summon_specific_friendly(y, x, rlev, SUMMON_THUNDERLORD, true);
}
break;
@@ -1587,7 +1585,7 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
for (int k = 0; k < 6; k++)
{
- summon_specific_friendly(y, x, rlev, SUMMON_KIN, TRUE);
+ summon_specific_friendly(y, x, rlev, SUMMON_KIN, true);
}
break;
@@ -1597,7 +1595,7 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
{
for (int k = 0; k < 1; k++)
{
- summon_specific_friendly(y, x, rlev, SUMMON_HI_DEMON, TRUE);
+ summon_specific_friendly(y, x, rlev, SUMMON_HI_DEMON, true);
}
break;
@@ -1607,7 +1605,7 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
{
for (int k = 0; k < 1; k++)
{
- summon_specific_friendly(y, x, rlev, 0, TRUE);
+ summon_specific_friendly(y, x, rlev, 0, true);
}
break;
@@ -1617,7 +1615,7 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
{
for (int k = 0; k < 6; k++)
{
- summon_specific_friendly(y, x, rlev, 0, TRUE);
+ summon_specific_friendly(y, x, rlev, 0, true);
}
break;
@@ -1627,7 +1625,7 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
{
for (int k = 0; k < 6; k++)
{
- summon_specific_friendly(y, x, rlev, SUMMON_ANT, TRUE);
+ summon_specific_friendly(y, x, rlev, SUMMON_ANT, true);
}
break;
@@ -1637,7 +1635,7 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
{
for (int k = 0; k < 6; k++)
{
- summon_specific_friendly(y, x, rlev, SUMMON_SPIDER, TRUE);
+ summon_specific_friendly(y, x, rlev, SUMMON_SPIDER, true);
}
break;
@@ -1647,7 +1645,7 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
{
for (int k = 0; k < 6; k++)
{
- summon_specific_friendly(y, x, rlev, SUMMON_HOUND, TRUE);
+ summon_specific_friendly(y, x, rlev, SUMMON_HOUND, true);
}
break;
@@ -1657,7 +1655,7 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
{
for (int k = 0; k < 6; k++)
{
- summon_specific_friendly(y, x, rlev, SUMMON_HYDRA, TRUE);
+ summon_specific_friendly(y, x, rlev, SUMMON_HYDRA, true);
}
break;
@@ -1667,7 +1665,7 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
{
for (int k = 0; k < 1; k++)
{
- summon_specific_friendly(y, x, rlev, SUMMON_ANGEL, TRUE);
+ summon_specific_friendly(y, x, rlev, SUMMON_ANGEL, true);
}
break;
@@ -1677,7 +1675,7 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
{
for (int k = 0; k < 1; k++)
{
- summon_specific_friendly(y, x, rlev, SUMMON_DEMON, TRUE);
+ summon_specific_friendly(y, x, rlev, SUMMON_DEMON, true);
}
break;
@@ -1687,7 +1685,7 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
{
for (int k = 0; k < 1; k++)
{
- summon_specific_friendly(y, x, rlev, SUMMON_UNDEAD, TRUE);
+ summon_specific_friendly(y, x, rlev, SUMMON_UNDEAD, true);
}
break;
@@ -1697,7 +1695,7 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
{
for (int k = 0; k < 1; k++)
{
- summon_specific_friendly(y, x, rlev, SUMMON_DRAGON, TRUE);
+ summon_specific_friendly(y, x, rlev, SUMMON_DRAGON, true);
}
break;
@@ -1707,7 +1705,7 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
{
for (int k = 0; k < 8; k++)
{
- summon_specific_friendly(y, x, rlev, SUMMON_HI_UNDEAD_NO_UNIQUES, TRUE);
+ summon_specific_friendly(y, x, rlev, SUMMON_HI_UNDEAD_NO_UNIQUES, true);
}
break;
@@ -1717,7 +1715,7 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
{
for (int k = 0; k < 8; k++)
{
- summon_specific_friendly(y, x, rlev, SUMMON_HI_DRAGON_NO_UNIQUES, TRUE);
+ summon_specific_friendly(y, x, rlev, SUMMON_HI_DRAGON_NO_UNIQUES, true);
}
break;
@@ -1727,7 +1725,7 @@ static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_s
{
for (int k = 0; k < 8; k++)
{
- summon_specific_friendly(y, x, rlev, SUMMON_WRAITH, TRUE);
+ summon_specific_friendly(y, x, rlev, SUMMON_WRAITH, true);
}
break;
@@ -1821,11 +1819,12 @@ boost::optional<int> get_item_hook_find_spell(object_filter_t const &)
return boost::none;
}
- int const spell = find_spell(buf);
- if (spell == -1)
+ auto spell_idx = find_spell(buf);
+ if (!spell_idx)
{
return boost::none;
}
+ int const spell = *spell_idx;
for (int i = 0; i < INVEN_TOTAL; i++)
{
@@ -1866,40 +1865,41 @@ boost::optional<int> get_item_hook_find_spell(object_filter_t const &)
/*
* Is the spell castable?
*/
-bool_ is_ok_spell(s32b spell_idx, s32b pval)
+bool is_ok_spell(s32b spell_idx, s32b pval)
{
spell_type *spell = spell_at(spell_idx);
// Calculate availability based on caster's skill level.
s32b level;
- bool_ na;
+ bool na;
get_level_school(spell, 50, 0, &level, &na);
if (na || (level == 0))
{
- return FALSE;
+ return false;
}
// Are we permitted to cast based on item pval? Only music
// spells have non-zero minimum PVAL.
- if (pval < spell_type_minimum_pval(spell))
+ s32b min_pval = spell_type_minimum_pval(spell);
+ if (min_pval > 0 && pval < min_pval)
{
- return FALSE;
+ return false;
}
// OK, we're permitted to cast it.
- return TRUE;
+ return true;
}
/*
* Get a spell from a book
*/
-s32b get_school_spell(cptr do_what, s16b force_book)
+s32b get_school_spell(const char *do_what, s16b force_book)
{
int i, item;
s32b spell = -1;
int num = 0;
s32b where = 1;
int ask;
- bool_ flag;
+ bool flag;
char out_val[160];
object_type *o_ptr, forge;
int tmp;
@@ -1952,7 +1952,7 @@ s32b get_school_spell(cptr do_what, s16b force_book)
}
/* Nothing chosen yet */
- flag = FALSE;
+ flag = false;
/* Show choices */
window_stuff();
@@ -1973,8 +1973,7 @@ s32b get_school_spell(cptr do_what, s16b force_book)
}
/* Save the screen */
- character_icky = TRUE;
- Term_save();
+ screen_save_no_flush();
/* Go */
if (hack_force_spell == -1)
@@ -1993,8 +1992,8 @@ s32b get_school_spell(cptr do_what, s16b force_book)
/* Restore and save screen; this prevents
subprompt from leaving garbage when going
around the loop multiple times. */
- Term_load();
- Term_save();
+ screen_load_no_flush();
+ screen_save_no_flush();
/* Display a list of spells */
where = print_book(sval, pval, o_ptr);
@@ -2002,7 +2001,7 @@ s32b get_school_spell(cptr do_what, s16b force_book)
/* Input */
if (!get_com(out_val, &choice))
{
- flag = FALSE;
+ flag = false;
break;
}
@@ -2031,16 +2030,11 @@ s32b get_school_spell(cptr do_what, s16b force_book)
}
else
{
- bool_ ok;
-
/* Save the spell index */
spell = spell_x(sval, pval, i);
- /* Do we need to do some pre test */
- ok = is_ok_spell(spell, o_ptr->pval);
-
/* Require "okay" spells */
- if (!ok)
+ if (!is_ok_spell(spell, o_ptr->pval))
{
bell();
msg_format("You may not %s that spell.", do_what);
@@ -2049,19 +2043,16 @@ s32b get_school_spell(cptr do_what, s16b force_book)
}
/* Stop the loop */
- flag = TRUE;
+ flag = true;
}
}
}
else
{
- bool_ ok;
-
/* Require "okay" spells */
- ok = is_ok_spell(hack_force_spell, hack_force_spell_pval);
- if (ok)
+ if (is_ok_spell(hack_force_spell, hack_force_spell_pval))
{
- flag = TRUE;
+ flag = true;
spell = hack_force_spell;
}
else
@@ -2074,9 +2065,7 @@ s32b get_school_spell(cptr do_what, s16b force_book)
/* Restore the screen */
- Term_load();
- character_icky = FALSE;
-
+ screen_load_no_flush();
/* Show choices */
window_stuff();
@@ -2113,7 +2102,7 @@ void cast_school_spell()
/* Actualy cast the choice */
if (spell != -1)
{
- lua_cast_school_spell(spell, FALSE);
+ lua_cast_school_spell(spell, false);
}
}
diff --git a/src/cmd5.hpp b/src/cmd5.hpp
index d25efb73..7ccdfecd 100644
--- a/src/cmd5.hpp
+++ b/src/cmd5.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_type_fwd.hpp"
#include "monster_race_fwd.hpp"
#include "monster_power_fwd.hpp"
@@ -8,16 +8,16 @@
#include <string>
#include <vector>
-bool_ is_magestaff();
+bool is_magestaff();
void do_cmd_browse_aux(object_type *o_ptr);
void do_cmd_browse();
-void fetch(int dir, int wgt, bool_ require_los);
+void fetch(int dir, int wgt, bool require_los);
void do_poly_self();
std::string symbiote_name(bool capitalize);
int use_symbiotic_power(int r_idx, bool great);
void use_monster_power(int r_idx, bool great);
-bool_ is_ok_spell(s32b spell_idx, s32b pval);
-s32b get_school_spell(cptr do_what, s16b force_book);
+bool is_ok_spell(s32b spell_idx, s32b pval);
+s32b get_school_spell(const char *do_what, s16b force_book);
void do_cmd_copy_spell();
void cast_school_spell();
std::vector<monster_power const *> extract_monster_powers(monster_race const *r_ptr, bool great);
diff --git a/src/cmd6.cc b/src/cmd6.cc
index e36f0cb6..2df580a5 100644
--- a/src/cmd6.cc
+++ b/src/cmd6.cc
@@ -20,7 +20,6 @@
#include "files.hpp"
#include "game.hpp"
#include "hook_eat_in.hpp"
-#include "hook_eat_out.hpp"
#include "hooks.hpp"
#include "lua_bind.hpp"
#include "mimic.hpp"
@@ -47,12 +46,12 @@
#include "store.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "variable.h"
#include "variable.hpp"
#include "wild.hpp"
#include "wizard2.hpp"
#include "xtra1.hpp"
#include "xtra2.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
#include <boost/algorithm/string/predicate.hpp>
@@ -77,7 +76,7 @@ static select_by_name_t select_object_by_name(std::string const &prompt)
{
object_type *o_ptr = get_object(i);
// Must have an actual item in the slot
- if (!o_ptr->k_idx)
+ if (!o_ptr->k_ptr)
{
continue;
}
@@ -146,14 +145,14 @@ static select_by_name_t select_object_by_name(std::string const &prompt)
* Determine the effects of eating a corpse. A corpse can be
* eaten whole or cut into pieces for later.
*/
-static void corpse_effect(object_type *o_ptr, bool_ cutting)
+static void corpse_effect(object_type *o_ptr, bool cutting)
{
auto const &r_info = game->edit_data.r_info;
auto r_ptr = &r_info[o_ptr->pval2];
/* Assume no bad effects */
- bool_ harmful = FALSE;
+ bool harmful = false;
byte method, effect, d_dice, d_side;
@@ -241,7 +240,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
if (!(p_ptr->resist_pois || p_ptr->oppose_pois))
{
set_poisoned(p_ptr->poisoned + dam + idam + 10);
- harmful = TRUE;
+ harmful = true;
}
break;
@@ -258,7 +257,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
/* Take damage */
take_hit(dam, "acidic food");
- harmful = TRUE;
+ harmful = true;
}
else
{
@@ -279,7 +278,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
/* Take damage */
take_hit(dam, "a fiery meal");
- harmful = TRUE;
+ harmful = true;
}
else
{
@@ -551,7 +550,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
{
/* Take damage */
acid_dam(brdam, "a gush of acid");
- harmful = TRUE;
+ harmful = true;
}
o_ptr->pval = 1;
}
@@ -572,7 +571,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
{
/* Take damage */
elec_dam(brdam, "an electric shock");
- harmful = TRUE;
+ harmful = true;
}
o_ptr->weight = o_ptr->weight - brpow;
o_ptr->pval = o_ptr->weight;
@@ -594,7 +593,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
{
/* Take damage */
fire_dam(brdam, "an explosion");
- harmful = TRUE;
+ harmful = true;
}
o_ptr->pval = 1;
}
@@ -615,7 +614,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
{
/* Take damage */
cold_dam(brdam, "a chilling blast");
- harmful = TRUE;
+ harmful = true;
}
o_ptr->weight = o_ptr->weight - brpow;
o_ptr->pval = o_ptr->weight;
@@ -645,7 +644,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
take_hit(brdam, "toxic gases");
o_ptr->weight = o_ptr->weight - brpow;
o_ptr->pval = o_ptr->weight;
- harmful = TRUE;
+ harmful = true;
}
/* Nether */
@@ -680,7 +679,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
/* Take damage */
take_hit(brdam, "an unholy blast");
- harmful = TRUE;
+ harmful = true;
o_ptr->weight = o_ptr->weight - brpow;
o_ptr->pval = o_ptr->weight;
}
@@ -784,7 +783,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
/* Take damage */
take_hit(brdam, "an explosion");
- harmful = TRUE;
+ harmful = true;
o_ptr->pval = 1;
}
@@ -803,7 +802,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
/* Take damage */
take_hit(dam, "acidic food");
}
- harmful = TRUE;
+ harmful = true;
}
/*
@@ -817,7 +816,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
{
set_poisoned(p_ptr->poisoned + rand_int(15) + 10);
}
- harmful = TRUE;
+ harmful = true;
}
/*
@@ -883,75 +882,75 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
}
if (r_ptr->spells & SF_S_THUNDERLORD)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_THUNDERLORD, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_THUNDERLORD, false);
}
if (r_ptr->spells & SF_S_DEMON)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DEMON, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DEMON, false);
}
if (r_ptr->spells & SF_S_KIN)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_KIN, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_KIN, false);
}
if (r_ptr->spells & SF_S_HI_DEMON)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_DEMON, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_DEMON, false);
}
if (r_ptr->spells & SF_S_MONSTER)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, 0, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, 0, false);
}
if (r_ptr->spells & SF_S_MONSTERS)
{
int k;
for (k = 0; k < 8; k++)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, 0, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, 0, false);
}
}
if (r_ptr->spells & SF_S_UNDEAD)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNDEAD, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNDEAD, false);
}
if (r_ptr->spells & SF_S_DRAGON)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DRAGON, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DRAGON, false);
}
if (r_ptr->spells & SF_S_ANT)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANT, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANT, false);
}
if (r_ptr->spells & SF_S_SPIDER)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_SPIDER, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_SPIDER, false);
}
if (r_ptr->spells & SF_S_HOUND)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HOUND, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HOUND, false);
}
if (r_ptr->spells & SF_S_HYDRA)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HYDRA, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HYDRA, false);
}
if (r_ptr->spells & SF_S_ANGEL)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANGEL, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANGEL, false);
}
if (r_ptr->spells & SF_S_HI_DRAGON)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_DRAGON, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_DRAGON, false);
}
if (r_ptr->spells & SF_S_HI_UNDEAD)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_UNDEAD, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_UNDEAD, false);
}
if (r_ptr->spells & SF_S_WRAITH)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_WRAITH, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_WRAITH, false);
}
if (r_ptr->spells & SF_S_UNIQUE)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNIQUE, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNIQUE, false);
}
}
}
@@ -977,13 +976,12 @@ static object_filter_t const &item_tester_hook_eatable()
void do_cmd_eat_food()
{
auto const &r_info = game->edit_data.r_info;
- auto const &k_info = game->edit_data.k_info;
- int ident, lev, fval = 0;
+ int fval = 0;
object_type *q_ptr, forge;
- bool_ destroy = TRUE;
+ bool destroy = true;
/* Get an item */
int item;
@@ -1003,18 +1001,11 @@ void do_cmd_eat_food()
/* Take a turn */
energy_use = 100;
- /* Identity not known yet */
- ident = FALSE;
-
- /* Object level */
- lev = k_info[o_ptr->k_idx].level;
-
/* Scripted foods */
hook_eat_in in = { o_ptr };
- hook_eat_out out = { FALSE };
- if (process_hooks_new(HOOK_EAT, &in, &out))
+ if (process_hooks_new(HOOK_EAT, &in, nullptr))
{
- ident = out.ident;
+ // Do nothing
}
/* (not quite) Normal foods */
else if (o_ptr->tval == TV_FOOD)
@@ -1026,7 +1017,6 @@ void do_cmd_eat_food()
{
p_ptr->hp_mod += 70;
msg_print("As you eat it you begin to feel your life flow getting stronger.");
- ident = TRUE;
p_ptr->update |= (PU_HP);
break;
@@ -1036,10 +1026,7 @@ void do_cmd_eat_food()
{
if (!(p_ptr->resist_pois || p_ptr->oppose_pois))
{
- if (set_poisoned(p_ptr->poisoned + rand_int(10) + 10))
- {
- ident = TRUE;
- }
+ set_poisoned(p_ptr->poisoned + rand_int(10) + 10);
}
break;
@@ -1049,10 +1036,7 @@ void do_cmd_eat_food()
{
if (!p_ptr->resist_blind)
{
- if (set_blind(p_ptr->blind + rand_int(200) + 200))
- {
- ident = TRUE;
- }
+ set_blind(p_ptr->blind + rand_int(200) + 200);
}
break;
@@ -1062,10 +1046,7 @@ void do_cmd_eat_food()
{
if (!p_ptr->resist_fear)
{
- if (set_afraid(p_ptr->afraid + rand_int(10) + 10))
- {
- ident = TRUE;
- }
+ set_afraid(p_ptr->afraid + rand_int(10) + 10);
}
break;
@@ -1075,10 +1056,7 @@ void do_cmd_eat_food()
{
if (!p_ptr->resist_conf)
{
- if (set_confused(p_ptr->confused + rand_int(10) + 10))
- {
- ident = TRUE;
- }
+ set_confused(p_ptr->confused + rand_int(10) + 10);
}
break;
@@ -1088,10 +1066,7 @@ void do_cmd_eat_food()
{
if (!p_ptr->resist_chaos)
{
- if (set_image(p_ptr->image + rand_int(250) + 250))
- {
- ident = TRUE;
- }
+ set_image(p_ptr->image + rand_int(250) + 250);
}
break;
@@ -1101,10 +1076,7 @@ void do_cmd_eat_food()
{
if (!p_ptr->free_act)
{
- if (set_paralyzed(rand_int(10) + 10))
- {
- ident = TRUE;
- }
+ set_paralyzed(rand_int(10) + 10);
}
break;
@@ -1115,8 +1087,6 @@ void do_cmd_eat_food()
take_hit(damroll(6, 6), "poisonous food");
do_dec_stat(A_STR, STAT_DEC_NORMAL);
- ident = TRUE;
-
break;
}
@@ -1125,8 +1095,6 @@ void do_cmd_eat_food()
take_hit(damroll(6, 6), "poisonous food");
do_dec_stat(A_CON, STAT_DEC_NORMAL);
- ident = TRUE;
-
break;
}
@@ -1135,8 +1103,6 @@ void do_cmd_eat_food()
take_hit(damroll(8, 8), "poisonous food");
do_dec_stat(A_INT, STAT_DEC_NORMAL);
- ident = TRUE;
-
break;
}
@@ -1145,8 +1111,6 @@ void do_cmd_eat_food()
take_hit(damroll(8, 8), "poisonous food");
do_dec_stat(A_WIS, STAT_DEC_NORMAL);
- ident = TRUE;
-
break;
}
@@ -1155,8 +1119,6 @@ void do_cmd_eat_food()
take_hit(damroll(10, 10), "poisonous food");
do_dec_stat(A_CON, STAT_DEC_NORMAL);
- ident = TRUE;
-
break;
}
@@ -1165,68 +1127,66 @@ void do_cmd_eat_food()
take_hit(damroll(10, 10), "poisonous food");
do_dec_stat(A_STR, STAT_DEC_NORMAL);
- ident = TRUE;
-
break;
}
case SV_FOOD_CURE_POISON:
{
- if (set_poisoned(0)) ident = TRUE;
+ set_poisoned(0);
break;
}
case SV_FOOD_CURE_BLINDNESS:
{
- if (set_blind(0)) ident = TRUE;
+ set_blind(0);
break;
}
case SV_FOOD_CURE_PARANOIA:
{
- if (set_afraid(0)) ident = TRUE;
+ set_afraid(0);
break;
}
case SV_FOOD_CURE_CONFUSION:
{
- if (set_confused(0)) ident = TRUE;
+ set_confused(0);
break;
}
case SV_FOOD_CURE_SERIOUS:
{
- if (hp_player(damroll(4, 8))) ident = TRUE;
+ hp_player(damroll(4, 8));
break;
}
case SV_FOOD_RESTORE_STR:
{
- if (do_res_stat(A_STR, TRUE)) ident = TRUE;
+ do_res_stat(A_STR, true);
break;
}
case SV_FOOD_RESTORE_CON:
{
- if (do_res_stat(A_CON, TRUE)) ident = TRUE;
+ do_res_stat(A_CON, true);
break;
}
case SV_FOOD_RESTORING:
{
- if (do_res_stat(A_STR, TRUE)) ident = TRUE;
- if (do_res_stat(A_INT, TRUE)) ident = TRUE;
- if (do_res_stat(A_WIS, TRUE)) ident = TRUE;
- if (do_res_stat(A_DEX, TRUE)) ident = TRUE;
- if (do_res_stat(A_CON, TRUE)) ident = TRUE;
- if (do_res_stat(A_CHR, TRUE)) ident = TRUE;
+ do_res_stat(A_STR, true);
+ do_res_stat(A_INT, true);
+ do_res_stat(A_WIS, true);
+ do_res_stat(A_DEX, true);
+ do_res_stat(A_CON, true);
+ do_res_stat(A_CHR, true);
break;
}
@@ -1270,9 +1230,6 @@ void do_cmd_eat_food()
msg_format("%s", rumour);
msg_print(NULL);
-
- ident = TRUE;
-
break;
}
@@ -1282,9 +1239,6 @@ void do_cmd_eat_food()
case SV_FOOD_JERKY:
{
msg_print("That tastes good.");
-
- ident = TRUE;
-
break;
}
@@ -1295,12 +1249,10 @@ void do_cmd_eat_food()
/* 2% chance of getting the mold power */
if (magik(2))
{
- p_ptr->powers_mod[PWR_GROW_MOLD] = TRUE;
+ p_ptr->powers_mod.insert(PWR_GROW_MOLD);
p_ptr->update |= PU_POWERS;
}
- ident = TRUE;
-
break;
}
@@ -1311,8 +1263,6 @@ void do_cmd_eat_food()
hp_player(damroll(4, 8));
set_food(PY_FOOD_MAX - 1);
- ident = TRUE;
-
break;
}
@@ -1321,15 +1271,10 @@ void do_cmd_eat_food()
{
msg_print("That tastes good.");
- ident = TRUE;
-
q_ptr = &forge;
object_prep(q_ptr, lookup_kind(TV_BOTTLE, 1));
q_ptr->number = 1;
- object_aware(q_ptr);
- object_known(q_ptr);
- q_ptr->ident |= IDENT_STOREB;
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
break;
}
@@ -1344,11 +1289,9 @@ void do_cmd_eat_food()
if (p_ptr->black_breath)
{
msg_print("The hold of the Black Breath on you is broken!");
- p_ptr->black_breath = FALSE;
+ p_ptr->black_breath = false;
}
- ident = TRUE;
-
break;
}
}
@@ -1364,7 +1307,7 @@ void do_cmd_eat_food()
{
case SV_CORPSE_CORPSE:
{
- bool_ no_meat = FALSE;
+ bool no_meat = false;
/* Not all is edible. Apologies if messy. */
@@ -1373,7 +1316,7 @@ void do_cmd_eat_food()
{
if (o_ptr->weight <= (r_ptr->weight * 3) / 5)
{
- no_meat = TRUE;
+ no_meat = true;
}
}
@@ -1382,7 +1325,7 @@ void do_cmd_eat_food()
{
if (o_ptr->weight <= (r_ptr->weight * 7) / 20)
{
- no_meat = TRUE;
+ no_meat = true;
}
}
@@ -1404,9 +1347,7 @@ void do_cmd_eat_food()
o_ptr->weight -= 10;
/* Corpses still have meat on them */
- destroy = FALSE;
-
- ident = TRUE;
+ destroy = false;
break;
}
@@ -1420,9 +1361,7 @@ void do_cmd_eat_food()
o_ptr->weight -= 10;
/* Corpses still have meat on them */
- destroy = FALSE;
-
- ident = TRUE;
+ destroy = false;
break;
}
@@ -1433,8 +1372,6 @@ void do_cmd_eat_food()
if (!o_ptr->timeout) msg_print("You quickly swallow the meat.");
else msg_print("That tastes good.");
- ident = TRUE;
-
/* Those darn microorganisms */
if (!o_ptr->timeout && (o_ptr->weight > o_ptr->pval) &&
!(p_ptr->resist_pois || p_ptr->oppose_pois))
@@ -1447,7 +1384,7 @@ void do_cmd_eat_food()
}
}
- corpse_effect(o_ptr, FALSE);
+ corpse_effect(o_ptr, false);
/* Less nutritious than food rations, but much more of it. */
fval = (o_ptr->timeout) ? 2000 : 2500;
@@ -1472,16 +1409,6 @@ void do_cmd_eat_food()
/* Combine / Reorder the pack (later) */
p_ptr->notice |= (PN_COMBINE | PN_REORDER);
- /* We have tried it */
- object_tried(o_ptr);
-
- /* The player is now aware of the object */
- if (ident && !object_aware_p(o_ptr))
- {
- object_aware(o_ptr);
- gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev);
- }
-
/* Window stuff */
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
@@ -1604,7 +1531,7 @@ void do_cmd_cut_corpse()
msg_print("You hack some meat off the corpse.");
- corpse_effect(o_ptr, TRUE);
+ corpse_effect(o_ptr, true);
/* Get local object */
object_type object_type_body;
@@ -1621,7 +1548,7 @@ void do_cmd_cut_corpse()
if (inven_carry_okay(i_ptr))
{
- inven_carry(i_ptr, TRUE);
+ inven_carry(i_ptr, true);
}
else
{
@@ -1666,11 +1593,7 @@ void do_cmd_cure_meat()
if (i_ptr->number > 1)
{
- /* Get a number */
- get_count(1, i_ptr->number);
-
- /* Save it */
- num = command_arg;
+ num = get_count(1, i_ptr->number);
}
else
{
@@ -1682,8 +1605,7 @@ void do_cmd_cure_meat()
/* Take a turn */
energy_use = 100;
- cptr q = "You soak the meat.";
- cptr s = "You soak the meat.";
+ const char *q = "You soak the meat.";
switch (i_ptr->sval)
{
@@ -1745,14 +1667,7 @@ void do_cmd_cure_meat()
}
/* Message */
- if (object_known_p(i_ptr))
- {
- msg_print(q);
- }
- else
- {
- msg_print(s);
- }
+ msg_print(q);
/* The meat is already spoiling */
if (((o_ptr->sval == SV_CORPSE_MEAT) && (o_ptr->weight > o_ptr->pval)) ||
@@ -1784,11 +1699,8 @@ static object_filter_t const &item_tester_hook_quaffable()
}
-static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
+static void quaff_potion(int tval, int sval, int pval2)
{
- int ident = FALSE;
-
-
/* "Traditional" potions */
if (tval == TV_POTION)
{
@@ -1799,15 +1711,12 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
case SV_POTION_SLIME_MOLD:
{
msg_print("You feel less thirsty.");
- ident = TRUE;
-
break;
}
case SV_POTION_SLOWNESS:
{
- if (set_slow(p_ptr->slow + randint(25) + 15)) ident = TRUE;
-
+ set_slow(p_ptr->slow + randint(25) + 15);
break;
}
@@ -1817,8 +1726,6 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
set_food(PY_FOOD_STARVE - 1);
set_poisoned(0);
set_paralyzed(4);
- ident = TRUE;
-
break;
}
@@ -1826,12 +1733,8 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
{
if (!(p_ptr->resist_pois || p_ptr->oppose_pois))
{
- if (set_poisoned(p_ptr->poisoned + rand_int(15) + 10))
- {
- ident = TRUE;
- }
+ set_poisoned(p_ptr->poisoned + rand_int(15) + 10);
}
-
break;
}
@@ -1839,12 +1742,8 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
{
if (!p_ptr->resist_blind)
{
- if (set_blind(p_ptr->blind + rand_int(100) + 100))
- {
- ident = TRUE;
- }
+ set_blind(p_ptr->blind + rand_int(100) + 100);
}
-
break;
}
@@ -1853,22 +1752,24 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
{
if (!((p_ptr->resist_conf) || (p_ptr->resist_chaos)))
{
- if (set_confused(p_ptr->confused + rand_int(20) + 15))
- {
- ident = TRUE;
- }
+ set_confused(p_ptr->confused + rand_int(20) + 15);
+
if (randint(2) == 1)
{
- if (set_image(p_ptr->image + rand_int(150) + 150))
- {
- ident = TRUE;
- }
+ set_image(p_ptr->image + rand_int(150) + 150);
}
+
if (randint(13) == 1)
{
- ident = TRUE;
- if (randint(3) == 1) lose_all_info();
- else wiz_dark();
+ if (randint(3) == 1)
+ {
+ lose_all_info();
+ }
+ else
+ {
+ wiz_dark();
+ }
+
teleport_player(100);
wiz_dark();
msg_print("You wake up elsewhere with a sore head...");
@@ -1883,10 +1784,7 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
{
if (!p_ptr->free_act)
{
- if (set_paralyzed(rand_int(4) + 4))
- {
- ident = TRUE;
- }
+ set_paralyzed(rand_int(4) + 4);
}
break;
@@ -1898,7 +1796,6 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
{
msg_print("You feel your memories fade.");
lose_exp(p_ptr->exp / 4);
- ident = TRUE;
}
break;
@@ -1908,56 +1805,48 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
{
msg_print("Your nerves and muscles feel weak and lifeless!");
take_hit(damroll(10, 10), "a potion of Ruination");
- dec_stat(A_DEX, 25, TRUE);
- dec_stat(A_WIS, 25, TRUE);
- dec_stat(A_CON, 25, TRUE);
- dec_stat(A_STR, 25, TRUE);
- dec_stat(A_CHR, 25, TRUE);
- dec_stat(A_INT, 25, TRUE);
- ident = TRUE;
-
+ dec_stat(A_DEX, 25, true);
+ dec_stat(A_WIS, 25, true);
+ dec_stat(A_CON, 25, true);
+ dec_stat(A_STR, 25, true);
+ dec_stat(A_CHR, 25, true);
+ dec_stat(A_INT, 25, true);
break;
}
case SV_POTION_DEC_STR:
{
- if (do_dec_stat(A_STR, STAT_DEC_NORMAL)) ident = TRUE;
-
+ do_dec_stat(A_STR, STAT_DEC_NORMAL);
break;
}
case SV_POTION_DEC_INT:
{
- if (do_dec_stat(A_INT, STAT_DEC_NORMAL)) ident = TRUE;
-
+ do_dec_stat(A_INT, STAT_DEC_NORMAL);
break;
}
case SV_POTION_DEC_WIS:
{
- if (do_dec_stat(A_WIS, STAT_DEC_NORMAL)) ident = TRUE;
-
+ do_dec_stat(A_WIS, STAT_DEC_NORMAL);
break;
}
case SV_POTION_DEC_DEX:
{
- if (do_dec_stat(A_DEX, STAT_DEC_NORMAL)) ident = TRUE;
-
+ do_dec_stat(A_DEX, STAT_DEC_NORMAL);
break;
}
case SV_POTION_DEC_CON:
{
- if (do_dec_stat(A_CON, STAT_DEC_NORMAL)) ident = TRUE;
-
+ do_dec_stat(A_CON, STAT_DEC_NORMAL);
break;
}
case SV_POTION_DEC_CHR:
{
- if (do_dec_stat(A_CHR, STAT_DEC_NORMAL)) ident = TRUE;
-
+ do_dec_stat(A_CHR, STAT_DEC_NORMAL);
break;
}
@@ -1967,8 +1856,6 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
take_hit(damroll(50, 20), "a potion of Detonation");
set_stun(p_ptr->stun + 75);
set_cut(p_ptr->cut + 5000);
- ident = TRUE;
-
break;
}
@@ -1976,49 +1863,36 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
{
msg_print("A feeling of Death flows through your body.");
take_hit(5000, "a potion of Death");
- ident = TRUE;
-
break;
}
case SV_POTION_INFRAVISION:
{
- if (set_tim_infra(p_ptr->tim_infra + 100 + randint(100)))
- {
- ident = TRUE;
- }
-
+ set_tim_infra(p_ptr->tim_infra + 100 + randint(100));
break;
}
case SV_POTION_DETECT_INVIS:
{
- if (set_tim_invis(p_ptr->tim_invis + 12 + randint(12)))
- {
- ident = TRUE;
- }
-
+ set_tim_invis(p_ptr->tim_invis + 12 + randint(12));
break;
}
case SV_POTION_SLOW_POISON:
{
- if (set_poisoned(p_ptr->poisoned / 2)) ident = TRUE;
-
+ set_poisoned(p_ptr->poisoned / 2);
break;
}
case SV_POTION_CURE_POISON:
{
- if (set_poisoned(0)) ident = TRUE;
-
+ set_poisoned(0);
break;
}
case SV_POTION_BOLDNESS:
{
- if (set_afraid(0)) ident = TRUE;
-
+ set_afraid(0);
break;
}
@@ -2026,7 +1900,7 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
{
if (!p_ptr->fast)
{
- if (set_fast(randint(25) + 15, 10)) ident = TRUE;
+ set_fast(randint(25) + 15, 10);
}
else
{
@@ -2038,94 +1912,79 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
case SV_POTION_RESIST_HEAT:
{
- if (set_oppose_fire(p_ptr->oppose_fire + randint(10) + 10))
- {
- ident = TRUE;
- }
-
+ set_oppose_fire(p_ptr->oppose_fire + randint(10) + 10);
break;
}
case SV_POTION_RESIST_COLD:
{
- if (set_oppose_cold(p_ptr->oppose_cold + randint(10) + 10))
- {
- ident = TRUE;
- }
-
+ set_oppose_cold(p_ptr->oppose_cold + randint(10) + 10);
break;
}
case SV_POTION_HEROISM:
{
- if (set_afraid(0)) ident = TRUE;
- if (set_hero(p_ptr->hero + randint(25) + 25)) ident = TRUE;
- if (hp_player(10)) ident = TRUE;
-
+ set_afraid(0);
+ set_hero(p_ptr->hero + randint(25) + 25);
+ hp_player(10);
break;
}
case SV_POTION_BESERK_STRENGTH:
{
- if (set_afraid(0)) ident = TRUE;
- if (set_shero(p_ptr->shero + randint(25) + 25)) ident = TRUE;
- if (hp_player(30)) ident = TRUE;
-
+ set_afraid(0);
+ set_shero(p_ptr->shero + randint(25) + 25);
+ hp_player(30);
break;
}
case SV_POTION_CURE_LIGHT:
{
- if (hp_player(damroll(2, 8))) ident = TRUE;
- if (set_blind(0)) ident = TRUE;
- if (set_cut(p_ptr->cut - 10)) ident = TRUE;
-
+ hp_player(damroll(2, 8));
+ set_blind(0);
+ set_cut(p_ptr->cut - 10);
break;
}
case SV_POTION_CURE_SERIOUS:
{
- if (hp_player(damroll(4, 8))) ident = TRUE;
- if (set_blind(0)) ident = TRUE;
- if (set_confused(0)) ident = TRUE;
- if (set_cut((p_ptr->cut / 2) - 50)) ident = TRUE;
-
+ hp_player(damroll(4, 8));
+ set_blind(0);
+ set_confused(0);
+ set_cut((p_ptr->cut / 2) - 50);
break;
}
case SV_POTION_CURE_CRITICAL:
{
- if (hp_player(damroll(6, 8))) ident = TRUE;
- if (set_blind(0)) ident = TRUE;
- if (set_confused(0)) ident = TRUE;
- if (set_poisoned(0)) ident = TRUE;
- if (set_stun(0)) ident = TRUE;
- if (set_cut(0)) ident = TRUE;
-
+ hp_player(damroll(6, 8));
+ set_blind(0);
+ set_confused(0);
+ set_poisoned(0);
+ set_stun(0);
+ set_cut(0);
break;
}
case SV_POTION_HEALING:
{
- if (hp_player(300)) ident = TRUE;
- if (set_blind(0)) ident = TRUE;
- if (set_confused(0)) ident = TRUE;
- if (set_poisoned(0)) ident = TRUE;
- if (set_stun(0)) ident = TRUE;
- if (set_cut(0)) ident = TRUE;
-
+ hp_player(300);
+ set_blind(0);
+ set_confused(0);
+ set_poisoned(0);
+ set_stun(0);
+ set_cut(0);
break;
}
case SV_POTION_STAR_HEALING:
{
- if (hp_player(1200)) ident = TRUE;
- if (set_blind(0)) ident = TRUE;
- if (set_confused(0)) ident = TRUE;
- if (set_poisoned(0)) ident = TRUE;
- if (set_stun(0)) ident = TRUE;
- if (set_cut(0)) ident = TRUE;
-
+ hp_player(1200);
+ set_blind(0);
+ set_confused(0);
+ set_poisoned(0);
+ set_stun(0);
+ set_cut(0);
break;
}
@@ -2140,19 +1999,17 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
set_image(0);
set_stun(0);
set_cut(0);
- do_res_stat(A_STR, TRUE);
- do_res_stat(A_CON, TRUE);
- do_res_stat(A_DEX, TRUE);
- do_res_stat(A_WIS, TRUE);
- do_res_stat(A_INT, TRUE);
- do_res_stat(A_CHR, TRUE);
+ do_res_stat(A_STR, true);
+ do_res_stat(A_CON, true);
+ do_res_stat(A_DEX, true);
+ do_res_stat(A_WIS, true);
+ do_res_stat(A_INT, true);
+ do_res_stat(A_CHR, true);
if (p_ptr->black_breath)
{
msg_print("The hold of the Black Breath on you is broken!");
}
- p_ptr->black_breath = FALSE;
- ident = TRUE;
-
+ p_ptr->black_breath = false;
break;
}
@@ -2165,7 +2022,6 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
msg_print("Your feel your head clear.");
p_ptr->redraw |= (PR_FRAME);
p_ptr->window |= (PW_PLAYER);
- ident = TRUE;
}
break;
@@ -2173,104 +2029,90 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
case SV_POTION_RESTORE_EXP:
{
- if (restore_level()) ident = TRUE;
-
+ restore_level();
break;
}
case SV_POTION_RES_STR:
{
- if (do_res_stat(A_STR, TRUE)) ident = TRUE;
-
+ do_res_stat(A_STR, true);
break;
}
case SV_POTION_RES_INT:
{
- if (do_res_stat(A_INT, TRUE)) ident = TRUE;
-
+ do_res_stat(A_INT, true);
break;
}
case SV_POTION_RES_WIS:
{
- if (do_res_stat(A_WIS, TRUE)) ident = TRUE;
-
+ do_res_stat(A_WIS, true);
break;
}
case SV_POTION_RES_DEX:
{
- if (do_res_stat(A_DEX, TRUE)) ident = TRUE;
-
+ do_res_stat(A_DEX, true);
break;
}
case SV_POTION_RES_CON:
{
- if (do_res_stat(A_CON, TRUE)) ident = TRUE;
-
+ do_res_stat(A_CON, true);
break;
}
case SV_POTION_RES_CHR:
{
- if (do_res_stat(A_CHR, TRUE)) ident = TRUE;
-
+ do_res_stat(A_CHR, true);
break;
}
case SV_POTION_INC_STR:
{
- if (do_inc_stat(A_STR)) ident = TRUE;
-
+ do_inc_stat(A_STR);
break;
}
case SV_POTION_INC_INT:
{
- if (do_inc_stat(A_INT)) ident = TRUE;
-
+ do_inc_stat(A_INT);
break;
}
case SV_POTION_INC_WIS:
{
- if (do_inc_stat(A_WIS)) ident = TRUE;
-
+ do_inc_stat(A_WIS);
break;
}
case SV_POTION_INC_DEX:
{
- if (do_inc_stat(A_DEX)) ident = TRUE;
-
+ do_inc_stat(A_DEX);
break;
}
case SV_POTION_INC_CON:
{
- if (do_inc_stat(A_CON)) ident = TRUE;
-
+ do_inc_stat(A_CON);
break;
}
case SV_POTION_INC_CHR:
{
- if (do_inc_stat(A_CHR)) ident = TRUE;
-
+ do_inc_stat(A_CHR);
break;
}
case SV_POTION_AUGMENTATION:
{
- if (do_inc_stat(A_STR)) ident = TRUE;
- if (do_inc_stat(A_INT)) ident = TRUE;
- if (do_inc_stat(A_WIS)) ident = TRUE;
- if (do_inc_stat(A_DEX)) ident = TRUE;
- if (do_inc_stat(A_CON)) ident = TRUE;
- if (do_inc_stat(A_CHR)) ident = TRUE;
-
+ do_inc_stat(A_STR);
+ do_inc_stat(A_INT);
+ do_inc_stat(A_WIS);
+ do_inc_stat(A_DEX);
+ do_inc_stat(A_CON);
+ do_inc_stat(A_CHR);
break;
}
@@ -2278,8 +2120,6 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
{
msg_print("An image of your surroundings forms in your mind...");
wiz_lite();
- ident = TRUE;
-
break;
}
@@ -2296,8 +2136,6 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
detect_objects_gold(DEFAULT_RADIUS);
detect_objects_normal(DEFAULT_RADIUS);
identify_pack();
- ident = TRUE;
-
break;
}
@@ -2307,9 +2145,7 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
{
msg_print("You feel more experienced.");
gain_exp(100000L);
- ident = TRUE;
}
-
break;
}
@@ -2320,47 +2156,38 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20);
set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20);
set_oppose_pois(p_ptr->oppose_pois + randint(20) + 20);
- ident = TRUE;
-
break;
}
case SV_POTION_CURING:
{
- if (hp_player(50)) ident = TRUE;
- if (set_blind(0)) ident = TRUE;
- if (set_poisoned(0)) ident = TRUE;
- if (set_confused(0)) ident = TRUE;
- if (set_stun(0)) ident = TRUE;
- if (set_cut(0)) ident = TRUE;
- if (set_image(0)) ident = TRUE;
- if (heal_insanity(50)) ident = TRUE;
-
+ hp_player(50);
+ set_blind(0);
+ set_poisoned(0);
+ set_confused(0);
+ set_stun(0);
+ set_cut(0);
+ set_image(0);
+ heal_insanity(50);
break;
}
case SV_POTION_INVULNERABILITY:
{
set_invuln(p_ptr->invuln + randint(7) + 7);
- ident = TRUE;
-
break;
}
case SV_POTION_NEW_LIFE:
{
do_cmd_rerate();
- ident = TRUE;
-
break;
}
case SV_POTION_BLOOD:
{
msg_print("You feel the blood of life running through your veins!");
- ident = TRUE;
p_ptr->allow_one_death++;
-
break;
}
@@ -2379,20 +2206,14 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
msg_print("You feel the dark corruptions of Morgoth coming over you!");
gain_random_corruption();
- ident = TRUE;
break;
}
case SV_POTION_INVIS:
{
int t = 30 + randint(30);
-
- if (set_invis(p_ptr->tim_invis + t, 35))
- {
- ident = TRUE;
- }
+ set_invis(p_ptr->tim_invis + t, 35);
set_tim_invis(p_ptr->tim_invis + t);
-
break;
}
@@ -2400,7 +2221,6 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
{
p_ptr->skill_points += rand_range(4, 10 + luck( -4, 4));
cmsg_format(TERM_L_GREEN, "You can increase %d more skills.", p_ptr->skill_points);
-
break;
}
@@ -2429,8 +2249,6 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
/* Recalculate bonuses */
p_ptr->update |= (PU_BONUS);
-
- ident = TRUE;
}
break;
@@ -2438,29 +2256,25 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
case SV_POTION2_CURE_LIGHT_SANITY:
{
- if (heal_insanity(damroll(4, 8))) ident = TRUE;
-
+ heal_insanity(damroll(4, 8));
break;
}
case SV_POTION2_CURE_SERIOUS_SANITY:
{
- if (heal_insanity(damroll(8, 8))) ident = TRUE;
-
+ heal_insanity(damroll(8, 8));
break;
}
case SV_POTION2_CURE_CRITICAL_SANITY:
{
- if (heal_insanity(damroll(12, 8))) ident = TRUE;
-
+ heal_insanity(damroll(12, 8));
break;
}
case SV_POTION2_CURE_SANITY:
{
- if (heal_insanity(damroll(10, 100))) ident = TRUE;
-
+ heal_insanity(damroll(10, 100));
break;
}
@@ -2470,8 +2284,6 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
}
}
}
-
- return (ident);
}
@@ -2480,10 +2292,6 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
*/
void do_cmd_quaff_potion()
{
- auto const &k_info = game->edit_data.k_info;
-
- int ident, lev;
-
/* Get an item */
int item;
if (!get_item(&item,
@@ -2499,49 +2307,29 @@ void do_cmd_quaff_potion()
/* Get the item */
object_type *o_ptr = get_object(item);
-
/* Take a turn */
energy_use = 100;
- /* Not identified yet */
- ident = FALSE;
-
- /* Object level */
- lev = k_info[o_ptr->k_idx].level;
-
/* Demon Breath corruption can spoil potions. */
if (player_has_corruption(CORRUPT_DEMON_BREATH) && magik(9))
{
msg_print("Your demon breath spoils the potion!");
- ident = FALSE;
}
else
{
/* Normal potion handling */
- ident = quaff_potion(o_ptr->tval, o_ptr->sval, o_ptr->pval, o_ptr->pval2);
+ quaff_potion(o_ptr->tval, o_ptr->sval, o_ptr->pval2);
}
/* Combine / Reorder the pack (later) */
p_ptr->notice |= (PN_COMBINE | PN_REORDER);
- /* The item has been tried */
- object_tried(o_ptr);
-
- /* An identification was made */
- if (ident && !object_aware_p(o_ptr))
- {
- object_aware(o_ptr);
- gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev);
- }
-
/* Window stuff */
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
-
/* Potions can feed the player */
set_food(p_ptr->food + o_ptr->pval);
-
/* Destroy potion */
inc_stack_size(item, -1);
}
@@ -2614,13 +2402,7 @@ static void do_cmd_fill_bottle()
object_prep(q_ptr, lookup_kind(tval, sval));
q_ptr->number = amt;
- if (c_ptr->info & CAVE_IDNT)
- {
- object_aware(q_ptr);
- object_known(q_ptr);
- }
-
- inven_carry(q_ptr, TRUE);
+ inven_carry(q_ptr, true);
c_ptr->special2 -= amt;
@@ -2628,8 +2410,6 @@ static void do_cmd_fill_bottle()
{
cave_set_feat(p_ptr->py, p_ptr->px, FEAT_EMPTY_FOUNTAIN);
}
-
- return;
}
@@ -2642,8 +2422,6 @@ void do_cmd_drink_fountain()
cave_type *c_ptr = &cave[p_ptr->py][p_ptr->px];
- bool_ ident;
-
int tval, sval, pval = 0;
char ch;
@@ -2682,9 +2460,9 @@ void do_cmd_drink_fountain()
sval = c_ptr->special - SV_POTION_LAST;
}
- for (auto const &k_ref: k_info)
+ for (auto const &k_entry: k_info)
{
- auto k_ptr = &k_ref;
+ auto const &k_ptr = k_entry.second;
if (k_ptr->tval != tval) continue;
if (k_ptr->sval != sval) continue;
@@ -2694,7 +2472,7 @@ void do_cmd_drink_fountain()
break;
}
- ident = quaff_potion(tval, sval, pval, 0);
+ quaff_potion(tval, sval, 0);
c_ptr->special2--;
@@ -2702,8 +2480,6 @@ void do_cmd_drink_fountain()
{
cave_set_feat(p_ptr->py, p_ptr->px, FEAT_EMPTY_FOUNTAIN);
}
-
- if (ident) c_ptr->info |= CAVE_IDNT;
}
}
@@ -2711,22 +2487,20 @@ void do_cmd_drink_fountain()
/*
* Curse the players armor
*/
-bool_ curse_armor()
+static void curse_armor()
{
- object_type *o_ptr;
-
- char o_name[80];
-
-
/* Curse the body armor */
- o_ptr = &p_ptr->inventory[INVEN_BODY];
+ auto o_ptr = &p_ptr->inventory[INVEN_BODY];
/* Nothing to curse */
- if (!o_ptr->k_idx) return (FALSE);
-
+ if (!o_ptr->k_ptr)
+ {
+ return;
+ }
/* Describe */
- object_desc(o_name, o_ptr, FALSE, 3);
+ char o_name[80];
+ object_desc(o_name, o_ptr, false, 3);
/* Attempt a saving throw for artifacts */
if (artifact_p(o_ptr) && (rand_int(100) < 50))
@@ -2751,10 +2525,7 @@ bool_ curse_armor()
o_ptr->ac = 0;
o_ptr->dd = 0;
o_ptr->ds = 0;
- o_ptr->art_flags = object_flag_set();
-
- /* Curse it */
- o_ptr->ident |= (IDENT_CURSED);
+ o_ptr->art_flags = TR_CURSED;
/* Recalculate bonuses */
p_ptr->update |= (PU_BONUS);
@@ -2765,30 +2536,26 @@ bool_ curse_armor()
/* Window stuff */
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
}
-
- return (TRUE);
}
/*
* Curse the players weapon
*/
-bool_ curse_weapon()
+static void curse_weapon()
{
- object_type *o_ptr;
-
- char o_name[80];
-
-
/* Curse the weapon */
- o_ptr = &p_ptr->inventory[INVEN_WIELD];
+ auto o_ptr = &p_ptr->inventory[INVEN_WIELD];
/* Nothing to curse */
- if (!o_ptr->k_idx) return (FALSE);
-
+ if (!o_ptr->k_ptr)
+ {
+ return;
+ }
/* Describe */
- object_desc(o_name, o_ptr, FALSE, 3);
+ char o_name[80];
+ object_desc(o_name, o_ptr, false, 3);
/* Attempt a saving throw */
if (artifact_p(o_ptr) && (rand_int(100) < 50))
@@ -2813,11 +2580,7 @@ bool_ curse_weapon()
o_ptr->ac = 0;
o_ptr->dd = 0;
o_ptr->ds = 0;
- o_ptr->art_flags = object_flag_set();
-
-
- /* Curse it */
- o_ptr->ident |= (IDENT_CURSED);
+ o_ptr->art_flags = TR_CURSED;
/* Recalculate bonuses */
p_ptr->update |= (PU_BONUS);
@@ -2828,9 +2591,6 @@ bool_ curse_weapon()
/* Window stuff */
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
}
-
- /* Notice */
- return (TRUE);
}
@@ -2858,8 +2618,8 @@ static object_filter_t const &item_tester_hook_readable()
void do_cmd_read_scroll()
{
auto const &d_info = game->edit_data.d_info;
- auto const &k_info = game->edit_data.k_info;
auto &r_info = game->edit_data.r_info;
+ auto const &dungeon_flags = game->dungeon_flags;
/* Check some conditions */
if (p_ptr->blind)
@@ -2898,21 +2658,14 @@ void do_cmd_read_scroll()
/* Take a turn */
energy_use = 100;
- /* Not identified yet */
- int ident = FALSE;
-
- /* Object level */
- int lev = k_info[o_ptr->k_idx].level;
-
/* Assume the scroll will get used up */
- int used_up = TRUE;
+ int used_up = true;
/* Corruption */
if (player_has_corruption(CORRUPT_BALROG_AURA) && magik(5))
{
msg_print("Your demon aura burns the scroll before you read it!");
- used_up = TRUE;
- ident = FALSE;
+ used_up = true;
}
/* Scrolls */
@@ -2923,7 +2676,6 @@ void do_cmd_read_scroll()
{
case SV_SCROLL_MASS_RESURECTION:
{
- ident = TRUE;
msg_print("You feel the souls of the dead coming back "
"from the Halls of Mandos.");
@@ -2946,14 +2698,13 @@ void do_cmd_read_scroll()
if (!get_check("Do you really want to leave your body? "
"(beware, it'll be destroyed!) "))
{
- used_up = FALSE;
+ used_up = false;
break;
}
- do_cmd_leave_body(FALSE);
+ do_cmd_leave_body(false);
- ident = TRUE;
- used_up = TRUE;
+ used_up = true;
break;
}
@@ -2961,9 +2712,9 @@ void do_cmd_read_scroll()
/* original didn't set used_up flag ??? -- pelpel */
case SV_SCROLL_RESET_RECALL:
{
- if (!reset_recall(TRUE))
+ if (!reset_recall(true))
{
- used_up = FALSE;
+ used_up = false;
break;
}
@@ -2971,8 +2722,7 @@ void do_cmd_read_scroll()
d_info[p_ptr->recall_dungeon].name.c_str(),
max_dlv[p_ptr->recall_dungeon]);
- ident = TRUE;
- used_up = TRUE;
+ used_up = true;
break;
}
@@ -2996,8 +2746,7 @@ void do_cmd_read_scroll()
msg_print(NULL);
msg_print("The scroll disappears in a puff of smoke!");
- fates[i].know = TRUE;
- ident = TRUE;
+ fates[i].know = true;
break;
}
@@ -3011,7 +2760,8 @@ void do_cmd_read_scroll()
{
set_blind(p_ptr->blind + 3 + randint(5));
}
- if (unlite_area(10, 3)) ident = TRUE;
+
+ unlite_area(10, 3);
break;
}
@@ -3021,22 +2771,18 @@ void do_cmd_read_scroll()
msg_print("There is a high-pitched humming noise.");
aggravate_monsters(1);
- ident = TRUE;
-
break;
}
case SV_SCROLL_CURSE_ARMOR:
{
- if (curse_armor()) ident = TRUE;
-
+ curse_armor();
break;
}
case SV_SCROLL_CURSE_WEAPON:
{
- if (curse_weapon()) ident = TRUE;
-
+ curse_weapon();
break;
}
@@ -3044,22 +2790,14 @@ void do_cmd_read_scroll()
{
for (int k = 0; k < randint(3); k++)
{
- if (summon_specific(p_ptr->py, p_ptr->px, dun_level, 0))
- {
- ident = TRUE;
- }
+ summon_specific(p_ptr->py, p_ptr->px, dun_level, 0);
}
-
break;
}
case SV_SCROLL_SUMMON_MINE:
{
- if (summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_MINE, FALSE))
- {
- ident = TRUE;
- }
-
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_MINE, false);
break;
}
@@ -3067,39 +2805,26 @@ void do_cmd_read_scroll()
{
for (int k = 0; k < randint(3); k++)
{
- if (summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNDEAD))
- {
- ident = TRUE;
- }
+ summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNDEAD);
}
-
break;
}
case SV_SCROLL_PHASE_DOOR:
{
teleport_player(10);
-
- ident = TRUE;
-
break;
}
case SV_SCROLL_TELEPORT:
{
teleport_player(100);
-
- ident = TRUE;
-
break;
}
case SV_SCROLL_TELEPORT_LEVEL:
{
teleport_player_level();
-
- ident = TRUE;
-
break;
}
@@ -3107,44 +2832,22 @@ void do_cmd_read_scroll()
{
if ((dungeon_flags & DF_ASK_LEAVE) && !get_check("Leave this unique level forever? "))
{
- used_up = FALSE;
+ used_up = false;
}
else
{
recall_player(21, 15);
-
- ident = TRUE;
}
break;
}
- case SV_SCROLL_IDENTIFY:
- {
- ident = TRUE;
-
- if (!ident_spell()) used_up = FALSE;
-
- break;
- }
-
- case SV_SCROLL_STAR_IDENTIFY:
- {
- ident = TRUE;
-
- if (!identify_fully()) used_up = FALSE;
-
- break;
- }
-
case SV_SCROLL_REMOVE_CURSE:
{
if (remove_curse())
{
msg_print("You feel as if someone is watching over you.");
- ident = TRUE;
}
-
break;
}
@@ -3153,146 +2856,132 @@ void do_cmd_read_scroll()
if (remove_all_curse())
{
msg_print("You feel as if someone is watching over you.");
- ident = TRUE;
}
-
break;
}
case SV_SCROLL_ENCHANT_ARMOR:
{
- ident = TRUE;
-
- if (!enchant_spell(0, 0, 1, 0)) used_up = FALSE;
-
+ if (!enchant_spell(0, 0, 1, 0))
+ {
+ used_up = false;
+ }
break;
}
case SV_SCROLL_ENCHANT_WEAPON_TO_HIT:
{
- if (!enchant_spell(1, 0, 0, 0)) used_up = FALSE;
-
- ident = TRUE;
-
+ if (!enchant_spell(1, 0, 0, 0))
+ {
+ used_up = false;
+ }
break;
}
case SV_SCROLL_ENCHANT_WEAPON_TO_DAM:
{
- if (!enchant_spell(0, 1, 0, 0)) used_up = FALSE;
-
- ident = TRUE;
-
+ if (!enchant_spell(0, 1, 0, 0))
+ {
+ used_up = false;
+ }
break;
}
case SV_SCROLL_ENCHANT_WEAPON_PVAL:
{
- if (!enchant_spell(0, 0, 0, 1)) used_up = FALSE;
-
- ident = TRUE;
-
+ if (!enchant_spell(0, 0, 0, 1))
+ {
+ used_up = false;
+ }
break;
}
case SV_SCROLL_STAR_ENCHANT_ARMOR:
{
- if (!enchant_spell(0, 0, randint(3) + 2, 0)) used_up = FALSE;
-
- ident = TRUE;
-
+ if (!enchant_spell(0, 0, randint(3) + 2, 0))
+ {
+ used_up = false;
+ }
break;
}
case SV_SCROLL_STAR_ENCHANT_WEAPON:
{
- if (!enchant_spell(randint(3), randint(3), 0, 0)) used_up = FALSE;
-
- ident = TRUE;
-
+ if (!enchant_spell(randint(3), randint(3), 0, 0))
+ {
+ used_up = false;
+ }
break;
}
case SV_SCROLL_RECHARGING:
{
- if (!recharge(60)) used_up = FALSE;
-
- ident = TRUE;
-
+ if (!recharge(60))
+ {
+ used_up = false;
+ }
break;
}
case SV_SCROLL_LIGHT:
{
- if (lite_area(damroll(2, 8), 2)) ident = TRUE;
-
+ lite_area(damroll(2, 8), 2);
break;
}
case SV_SCROLL_MAPPING:
{
map_area();
-
- ident = TRUE;
-
break;
}
case SV_SCROLL_DETECT_GOLD:
{
- if (detect_treasure(DEFAULT_RADIUS)) ident = TRUE;
- if (detect_objects_gold(DEFAULT_RADIUS)) ident = TRUE;
-
+ detect_treasure(DEFAULT_RADIUS);
+ detect_objects_gold(DEFAULT_RADIUS);
break;
}
case SV_SCROLL_DETECT_ITEM:
{
- if (detect_objects_normal(DEFAULT_RADIUS)) ident = TRUE;
-
+ detect_objects_normal(DEFAULT_RADIUS);
break;
}
case SV_SCROLL_DETECT_DOOR:
{
- if (detect_doors(DEFAULT_RADIUS)) ident = TRUE;
- if (detect_stairs(DEFAULT_RADIUS)) ident = TRUE;
-
+ detect_doors(DEFAULT_RADIUS);
+ detect_stairs(DEFAULT_RADIUS);
break;
}
case SV_SCROLL_DETECT_INVIS:
{
- if (detect_monsters_invis(DEFAULT_RADIUS)) ident = TRUE;
-
+ detect_monsters_invis(DEFAULT_RADIUS);
break;
}
case SV_SCROLL_SATISFY_HUNGER:
{
- if (set_food(PY_FOOD_MAX - 1)) ident = TRUE;
-
+ set_food(PY_FOOD_MAX - 1);
break;
}
case SV_SCROLL_BLESSING:
{
- if (set_blessed(p_ptr->blessed + randint(12) + 6)) ident = TRUE;
-
+ set_blessed(p_ptr->blessed + randint(12) + 6);
break;
}
case SV_SCROLL_HOLY_CHANT:
{
- if (set_blessed(p_ptr->blessed + randint(24) + 12)) ident = TRUE;
-
+ set_blessed(p_ptr->blessed + randint(24) + 12);
break;
}
case SV_SCROLL_HOLY_PRAYER:
{
- if (set_blessed(p_ptr->blessed + randint(48) + 24)) ident = TRUE;
-
+ set_blessed(p_ptr->blessed + randint(48) + 24);
break;
}
@@ -3301,8 +2990,7 @@ void do_cmd_read_scroll()
if (p_ptr->confusing == 0)
{
msg_print("Your hands begin to glow.");
- p_ptr->confusing = TRUE;
- ident = TRUE;
+ p_ptr->confusing = true;
}
break;
@@ -3310,21 +2998,13 @@ void do_cmd_read_scroll()
case SV_SCROLL_PROTECTION_FROM_EVIL:
{
- int k = 3 * p_ptr->lev;
- if (set_protevil(p_ptr->protevil + randint(25) + k))
- {
- ident = TRUE;
- }
-
+ set_protevil(p_ptr->protevil + randint(25) + (3 * p_ptr->lev));
break;
}
case SV_SCROLL_RUNE_OF_PROTECTION:
{
warding_glyph();
-
- ident = TRUE;
-
break;
}
@@ -3340,51 +3020,36 @@ void do_cmd_read_scroll()
msg_print("The dungeon trembles...");
}
- ident = TRUE;
-
break;
}
case SV_SCROLL_DISPEL_UNDEAD:
{
- if (dispel_undead(60)) ident = TRUE;
-
+ dispel_undead(60);
break;
}
case SV_SCROLL_GENOCIDE:
{
- genocide(TRUE);
-
- ident = TRUE;
-
+ genocide();
break;
}
case SV_SCROLL_MASS_GENOCIDE:
{
- mass_genocide(TRUE);
-
- ident = TRUE;
-
+ mass_genocide();
break;
}
case SV_SCROLL_ACQUIREMENT:
{
- acquirement(p_ptr->py, p_ptr->px, 1, TRUE, FALSE);
-
- ident = TRUE;
-
+ acquirement(p_ptr->py, p_ptr->px, 1, true);
break;
}
case SV_SCROLL_STAR_ACQUIREMENT:
{
- acquirement(p_ptr->py, p_ptr->px, randint(2) + 1, TRUE, FALSE);
-
- ident = TRUE;
-
+ acquirement(p_ptr->py, p_ptr->px, randint(2) + 1, true);
break;
}
@@ -3400,12 +3065,10 @@ void do_cmd_read_scroll()
if (!p_ptr->oppose_fire && !p_ptr->resist_fire &&
!p_ptr->immune_fire)
{
- take_hit(50 + randint(50) + (p_ptr->sensible_fire) ? 20 : 0,
+ take_hit(50 + randint(50) + (p_ptr->sensible_fire ? 20 : 0),
"a Scroll of Fire");
}
- ident = TRUE;
-
break;
}
@@ -3420,8 +3083,6 @@ void do_cmd_read_scroll()
take_hit(100 + randint(100), "a Scroll of Ice");
}
- ident = TRUE;
-
break;
}
@@ -3434,8 +3095,6 @@ void do_cmd_read_scroll()
take_hit(111 + randint(111), "a Scroll of Chaos");
}
- ident = TRUE;
-
break;
}
@@ -3485,16 +3144,15 @@ void do_cmd_read_scroll()
msg_print("The scroll disappears in a puff of smoke!");
- ident = TRUE;
-
break;
}
case SV_SCROLL_ARTIFACT:
{
- ident = TRUE;
-
- if (!artifact_scroll()) used_up = FALSE;
+ if (!artifact_scroll())
+ {
+ used_up = false;
+ }
break;
}
@@ -3547,7 +3205,7 @@ void do_cmd_read_scroll()
screen_save();
/* Get the filename */
- cptr q = format("book-%d.txt", o_ptr->sval);
+ const char *q = format("book-%d.txt", o_ptr->sval);
/* Peruse the help file */
show_file(q, NULL);
@@ -3558,10 +3216,10 @@ void do_cmd_read_scroll()
/* Inscriptions become known upon reading */
if (o_ptr->sval >= 100)
{
- p_ptr->inscriptions[o_ptr->sval - 100] = TRUE;
+ p_ptr->inscriptions[o_ptr->sval - 100] = true;
}
- used_up = FALSE;
+ used_up = false;
}
}
@@ -3569,16 +3227,6 @@ void do_cmd_read_scroll()
/* Combine / Reorder the pack (later) */
p_ptr->notice |= (PN_COMBINE | PN_REORDER);
- /* The item was tried */
- object_tried(o_ptr);
-
- /* An identification was made */
- if (ident && !object_aware_p(o_ptr))
- {
- object_aware(o_ptr);
- gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev);
- }
-
/* Window stuff */
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
@@ -3618,34 +3266,26 @@ void unset_stick_mode()
/*
* Activate a device
*/
-static void activate_stick(object_type *o_ptr, bool_ *obvious, bool_ *use_charge)
+static void activate_stick(object_type *o_ptr, bool *use_charge)
{
spell_type *spell = spell_at(o_ptr->pval2);
- casting_result ret;
- assert(obvious != NULL);
assert(use_charge != NULL);
set_stick_mode(o_ptr);
- ret = spell_type_produce_effect(spell);
+ auto ret = spell_type_produce_effect(spell);
unset_stick_mode();
switch (ret)
{
case NO_CAST:
- *use_charge = FALSE;
- *obvious = FALSE;
- break;
- case CAST_HIDDEN:
- *use_charge = TRUE;
- *obvious = FALSE;
+ *use_charge = false;
break;
- case CAST_OBVIOUS:
- *use_charge = TRUE;
- *obvious = TRUE;
+ case CAST:
+ *use_charge = true;
break;
default:
- assert(FALSE);
+ assert(false);
}
}
@@ -3659,7 +3299,7 @@ static void activate_stick(object_type *o_ptr, bool_ *obvious, bool_ *use_charge
*/
void do_cmd_use_staff()
{
- bool_ obvious, use_charge;
+ bool use_charge;
/* No magic */
if (p_ptr->antimagic)
@@ -3734,20 +3374,16 @@ void do_cmd_use_staff()
{
flush_on_failure();
msg_print("The staff has no charges left.");
- o_ptr->ident |= (IDENT_EMPTY);
return;
}
/* Analyze the staff */
- activate_stick(o_ptr, &obvious, &use_charge);
+ activate_stick(o_ptr, &use_charge);
/* Combine / Reorder the pack (later) */
p_ptr->notice |= (PN_COMBINE | PN_REORDER);
- /* Tried the item */
- object_tried(o_ptr);
-
/* An identification was made */
/* Window stuff */
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
@@ -3759,12 +3395,6 @@ void do_cmd_use_staff()
return;
}
- /* An identification was made */
- if (obvious)
- {
- object_aware(o_ptr);
- }
-
/* Use a single charge */
o_ptr->pval--;
@@ -3788,7 +3418,7 @@ void do_cmd_use_staff()
/* Unstack the used item */
o_ptr->number--;
- item = inven_carry(q_ptr, FALSE);
+ item = inven_carry(q_ptr, false);
/* Message */
msg_print("You unstack your staff.");
@@ -3830,7 +3460,7 @@ void do_cmd_use_staff()
*/
void do_cmd_aim_wand()
{
- bool_ obvious, use_charge;
+ bool use_charge;
/* No magic */
if (p_ptr->antimagic)
@@ -3899,31 +3529,21 @@ void do_cmd_aim_wand()
{
flush_on_failure();
msg_print("The wand has no charges left.");
- o_ptr->ident |= (IDENT_EMPTY);
return;
}
/* Analyze the wand */
- activate_stick(o_ptr, &obvious, &use_charge);
+ activate_stick(o_ptr, &use_charge);
/* Combine / Reorder the pack (later) */
p_ptr->notice |= (PN_COMBINE | PN_REORDER);
- /* Mark it as tried */
- object_tried(o_ptr);
-
/* Hack -- some uses are "free" */
if (!use_charge)
{
return;
}
- /* An identification was made */
- if (obvious)
- {
- object_aware(o_ptr);
- }
-
/* Window stuff */
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
@@ -4043,15 +3663,16 @@ void zap_combine_rod_tip(object_type *q_ptr, int tip_item)
void do_cmd_zap_rod()
{
auto const &k_info = game->edit_data.k_info;
+ auto const &dungeon_flags = game->dungeon_flags;
- int item, ident, chance, dir, lev;
+ int item, chance, dir;
int cost;
- bool_ require_dir;
+ bool require_dir;
/* Hack -- let perception get aborted */
- bool_ use_charge = TRUE;
+ bool use_charge = true;
/* No magic */
@@ -4095,7 +3716,7 @@ void do_cmd_zap_rod()
/* Non-directed rods */
if (o_ptr->pval < SV_ROD_MIN_DIRECTION)
{
- require_dir = FALSE;
+ require_dir = false;
}
/* Some rods always require direction */
@@ -4106,20 +3727,20 @@ void do_cmd_zap_rod()
case SV_ROD_HAVOC:
case SV_ROD_HOME:
{
- require_dir = FALSE;
+ require_dir = false;
break;
}
default:
{
- require_dir = TRUE;
+ require_dir = true;
break;
}
}
}
- /* Get a direction (unless KNOWN not to need it) */
- if (!object_aware_p(o_ptr) || require_dir)
+ /* Get a direction */
+ if (require_dir)
{
/* Get a direction, allow cancel */
if (!get_aim_dir(&dir)) return;
@@ -4136,12 +3757,9 @@ void do_cmd_zap_rod()
energy_use /= 2;
}
- /* Not identified yet */
- ident = FALSE;
-
/* Extract the item level */
- auto tip_ptr = &k_info[lookup_kind(TV_ROD, o_ptr->pval)];
- lev = k_info[lookup_kind(TV_ROD, o_ptr->pval)].level;
+ auto const &tip_ptr = k_info.at(lookup_kind(TV_ROD, o_ptr->pval));
+ auto const lev = tip_ptr->level;
/* Base chance of success */
chance = p_ptr->skill_dev;
@@ -4207,27 +3825,14 @@ void do_cmd_zap_rod()
{
case SV_ROD_HOME:
{
- ident = TRUE;
-
do_cmd_home_trump();
-
break;
}
case SV_ROD_DETECT_DOOR:
{
- if (detect_doors(DEFAULT_RADIUS)) ident = TRUE;
- if (detect_stairs(DEFAULT_RADIUS)) ident = TRUE;
-
- break;
- }
-
- case SV_ROD_IDENTIFY:
- {
- ident = TRUE;
-
- if (!ident_spell()) use_charge = FALSE;
-
+ detect_doors(DEFAULT_RADIUS);
+ detect_stairs(DEFAULT_RADIUS);
break;
}
@@ -4235,13 +3840,11 @@ void do_cmd_zap_rod()
{
if ((dungeon_flags & DF_ASK_LEAVE) && !get_check("Leave this unique level forever? "))
{
- use_charge = FALSE;
+ use_charge = false;
}
else
{
recall_player(21, 15);
-
- ident = TRUE;
}
break;
@@ -4249,60 +3852,50 @@ void do_cmd_zap_rod()
case SV_ROD_ILLUMINATION:
{
- if (lite_area(damroll(2, 8), 2)) ident = TRUE;
-
+ lite_area(damroll(2, 8), 2);
break;
}
case SV_ROD_MAPPING:
{
map_area();
-
- ident = TRUE;
-
break;
}
case SV_ROD_DETECTION:
{
detect_all(DEFAULT_RADIUS);
-
- ident = TRUE;
-
break;
}
case SV_ROD_CURING:
{
- if (set_blind(0)) ident = TRUE;
- if (set_poisoned(0)) ident = TRUE;
- if (set_confused(0)) ident = TRUE;
- if (set_stun(0)) ident = TRUE;
- if (set_cut(0)) ident = TRUE;
- if (set_image(0)) ident = TRUE;
-
+ set_blind(0);
+ set_poisoned(0);
+ set_confused(0);
+ set_stun(0);
+ set_cut(0);
+ set_image(0);
break;
}
case SV_ROD_HEALING:
{
- if (hp_player(500)) ident = TRUE;
- if (set_stun(0)) ident = TRUE;
- if (set_cut(0)) ident = TRUE;
-
+ hp_player(500);
+ set_stun(0);
+ set_cut(0);
break;
}
case SV_ROD_RESTORATION:
{
- if (restore_level()) ident = TRUE;
- if (do_res_stat(A_STR, TRUE)) ident = TRUE;
- if (do_res_stat(A_INT, TRUE)) ident = TRUE;
- if (do_res_stat(A_WIS, TRUE)) ident = TRUE;
- if (do_res_stat(A_DEX, TRUE)) ident = TRUE;
- if (do_res_stat(A_CON, TRUE)) ident = TRUE;
- if (do_res_stat(A_CHR, TRUE)) ident = TRUE;
-
+ restore_level();
+ do_res_stat(A_STR, true);
+ do_res_stat(A_INT, true);
+ do_res_stat(A_WIS, true);
+ do_res_stat(A_DEX, true);
+ do_res_stat(A_CON, true);
+ do_res_stat(A_CHR, true);
break;
}
@@ -4310,20 +3903,18 @@ void do_cmd_zap_rod()
{
if (!p_ptr->fast)
{
- if (set_fast(randint(30) + 15, 10)) ident = TRUE;
+ set_fast(randint(30) + 15, 10);
}
else
{
set_fast(p_ptr->fast + 5, 10);
}
-
break;
}
case SV_ROD_TELEPORT_AWAY:
{
- if (teleport_monster(dir)) ident = TRUE;
-
+ teleport_monster(dir);
break;
}
@@ -4331,118 +3922,84 @@ void do_cmd_zap_rod()
{
msg_print("A line of blue shimmering light appears.");
lite_line(dir);
-
- ident = TRUE;
-
break;
}
case SV_ROD_SLEEP_MONSTER:
{
- if (sleep_monster(dir)) ident = TRUE;
-
+ sleep_monster(dir);
break;
}
case SV_ROD_SLOW_MONSTER:
{
- if (slow_monster(dir)) ident = TRUE;
-
+ slow_monster(dir);
break;
}
case SV_ROD_DRAIN_LIFE:
{
- if (drain_life(dir, 75)) ident = TRUE;
-
+ drain_life(dir, 75);
break;
}
case SV_ROD_POLYMORPH:
{
- if (poly_monster(dir)) ident = TRUE;
-
+ poly_monster(dir);
break;
}
case SV_ROD_ACID_BOLT:
{
fire_bolt_or_beam(10, GF_ACID, dir, damroll(6, 8));
-
- ident = TRUE;
-
break;
}
case SV_ROD_ELEC_BOLT:
{
fire_bolt_or_beam(10, GF_ELEC, dir, damroll(3, 8));
-
- ident = TRUE;
-
break;
}
case SV_ROD_FIRE_BOLT:
{
fire_bolt_or_beam(10, GF_FIRE, dir, damroll(8, 8));
-
- ident = TRUE;
-
break;
}
case SV_ROD_COLD_BOLT:
{
fire_bolt_or_beam(10, GF_COLD, dir, damroll(5, 8));
-
- ident = TRUE;
-
break;
}
case SV_ROD_ACID_BALL:
{
fire_ball(GF_ACID, dir, 60, 2);
-
- ident = TRUE;
-
break;
}
case SV_ROD_ELEC_BALL:
{
fire_ball(GF_ELEC, dir, 32, 2);
-
- ident = TRUE;
-
break;
}
case SV_ROD_FIRE_BALL:
{
fire_ball(GF_FIRE, dir, 72, 2);
-
- ident = TRUE;
-
break;
}
case SV_ROD_COLD_BALL:
{
fire_ball(GF_COLD, dir, 48, 2);
-
- ident = TRUE;
-
break;
}
case SV_ROD_HAVOC:
{
call_chaos();
-
- ident = TRUE;
-
break;
}
@@ -4454,16 +4011,6 @@ void do_cmd_zap_rod()
/* Combine / Reorder the pack (later) */
p_ptr->notice |= (PN_COMBINE | PN_REORDER);
- /* Tried the object */
- object_tried(o_ptr);
-
- /* Successfully determined the object function */
- if (ident && !object_aware_p(o_ptr))
- {
- object_aware(o_ptr);
- gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev);
- }
-
/* Window stuff */
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
@@ -4505,7 +4052,7 @@ int ring_of_power()
/* Select power to use */
- while (TRUE)
+ while (true)
{
if (!get_com("[S]ummon a wraith, [R]ule the world or "
"[C]ast a powerful attack? ", &ch))
@@ -4536,7 +4083,7 @@ int ring_of_power()
/* Rewrite this -- pelpel */
if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2),
(plev > 47 ? SUMMON_HI_UNDEAD_NO_UNIQUES : SUMMON_UNDEAD),
- (((plev > 24) && (randint(3) == 1)) ? TRUE : FALSE)))
+ (((plev > 24) && (randint(3) == 1)) ? true : false)))
{
msg_print("Cold winds begin to blow around you, "
"carrying with them the stench of decay...");
@@ -4555,7 +4102,7 @@ int ring_of_power()
autosave_checkpoint();
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
timeout = 250 + rand_int(250);
}
@@ -4588,7 +4135,7 @@ int ring_of_power()
/*
* Enchant some bolts
*/
-bool_ brand_bolts()
+bool brand_bolts()
{
int i;
@@ -4617,13 +4164,13 @@ bool_ brand_bolts()
o_ptr->name2 = EGO_FLAME;
/* Apply the ego */
- apply_magic(o_ptr, dun_level, FALSE, FALSE, FALSE);
+ apply_magic(o_ptr, dun_level, false, false, false);
/* Enchant */
enchant(o_ptr, rand_int(3) + 4, ENCH_TOHIT | ENCH_TODAM);
/* Notice */
- return (TRUE);
+ return true;
}
/* Flush */
@@ -4633,7 +4180,7 @@ bool_ brand_bolts()
msg_print("The fiery enchantment failed.");
/* Notice */
- return (TRUE);
+ return true;
}
@@ -4683,7 +4230,7 @@ static bool eternal_flame_item_tester_hook(object_type const *o_ptr)
if ((o_ptr->name1 > 0) ||
(o_ptr->name2 > 0))
{
- return FALSE;
+ return false;
}
return (get_eternal_artifact_idx(o_ptr) >= 0);
@@ -4711,7 +4258,7 @@ static bool activate_eternal_flame(int flame_item)
object_type *o_ptr = get_object(item);
o_ptr->name1 = artifact_idx;
- apply_magic(o_ptr, -1, TRUE, TRUE, TRUE);
+ apply_magic(o_ptr, -1, true, true, true);
o_ptr->found = OBJ_FOUND_SELFMADE;
@@ -4745,12 +4292,12 @@ static void activate_radagast()
{
cmsg_print(TERM_GREEN, "The staff's power cleanses you completely!");
remove_all_curse();
- do_res_stat(A_STR, TRUE);
- do_res_stat(A_CON, TRUE);
- do_res_stat(A_DEX, TRUE);
- do_res_stat(A_WIS, TRUE);
- do_res_stat(A_INT, TRUE);
- do_res_stat(A_CHR, TRUE);
+ do_res_stat(A_STR, true);
+ do_res_stat(A_CON, true);
+ do_res_stat(A_DEX, true);
+ do_res_stat(A_WIS, true);
+ do_res_stat(A_INT, true);
+ do_res_stat(A_CHR, true);
restore_level();
// clean_corruptions(); TODO: Do we want to implement this?
hp_player(5000);
@@ -4767,7 +4314,7 @@ static void activate_radagast()
{
msg_print("The hold of the Black Breath on you is broken!");
}
- p_ptr->black_breath = FALSE;
+ p_ptr->black_breath = false;
p_ptr->update |= PU_BONUS;
p_ptr->window |= PW_PLAYER;
@@ -4796,7 +4343,6 @@ static void activate_valaroma()
*/
void do_cmd_activate()
{
- auto const &k_info = game->edit_data.k_info;
auto const &a_info = game->edit_data.a_info;
int item, lev, chance;
@@ -4832,7 +4378,7 @@ void do_cmd_activate()
energy_use = 100;
/* Extract the item level */
- lev = k_info[o_ptr->k_idx].level;
+ lev = o_ptr->k_ptr->level;
/* Hack -- Use artifact level instead */
if (artifact_p(o_ptr))
@@ -4912,7 +4458,7 @@ void do_cmd_activate()
/* New mostly unified activation code
This has to be early to allow artifacts to override normal items -- neil */
- if ( activation_aux(o_ptr, TRUE, item) == NULL )
+ if ( activation_aux(o_ptr, true, item) == NULL )
{
/* Window stuff */
p_ptr->window |= (PW_INVEN | PW_EQUIP);
@@ -4955,17 +4501,17 @@ void do_cmd_activate()
msg_print("Oops. That object cannot be activated.");
}
-const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
+const char *activation_aux(object_type * o_ptr, bool doit, int item)
{
- auto const &k_info = game->edit_data.k_info;
auto const &a_info = game->edit_data.a_info;
auto const &e_info = game->edit_data.e_info;
+ auto const &dungeon_flags = game->dungeon_flags;
int plev = get_skill(SKILL_DEVICE);
int i = 0, ii = 0, ij = 0, k, dir, dummy = 0;
int chance;
- bool_ is_junkart = (o_ptr->tval == TV_RANDART);
+ bool is_junkart = (o_ptr->tval == TV_RANDART);
int spell = 0;
@@ -4991,7 +4537,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
/* Intrinsic to item type (rings of Ice, etc) */
if (!spell)
- spell = k_info[o_ptr->k_idx].activate;
+ spell = o_ptr->k_ptr->activate;
/* Complain about mis-configured .txt files? */
if (!spell)
@@ -5080,17 +4626,6 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
break;
}
- case ACT_KNOWLEDGE:
- {
- if (!doit) return "whispers from beyond(sanity drain) every 100+d200 turns";
- identify_fully();
- take_sanity_hit(damroll(10, 7), "the sounds of the dead");
-
- o_ptr->timeout = rand_int(200) + 100;
-
- break;
- }
-
case ACT_UNDEATH:
{
if (!doit) return "ruination every 10+d10 turns";
@@ -5193,7 +4728,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
set_cut(0);
if (p_ptr->black_breath)
{
- p_ptr->black_breath = FALSE;
+ p_ptr->black_breath = false;
msg_print("The hold of the Black Breath on you is broken!");
}
@@ -5213,65 +4748,6 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
}
- /* The Stone of Lore is perilous, for the sake of game balance. */
- case ACT_STONE_LORE:
- {
- if (!doit) return "perilous identify every turn";
- msg_print("The stone reveals hidden mysteries...");
- if (!ident_spell()) break;
-
- if (p_ptr->has_ability(AB_PERFECT_CASTING))
- {
- /* Sufficient mana */
- if (20 <= p_ptr->csp)
- {
- /* Use some mana */
- p_ptr->csp -= 20;
- }
-
- /* Over-exert the player */
- else
- {
- int oops = 20 - p_ptr->csp;
-
- /* No mana left */
- p_ptr->csp = 0;
- p_ptr->csp_frac = 0;
-
- /* Message */
- msg_print("You are too weak to control the stone!");
-
- /* Hack -- Bypass free action */
- set_paralyzed(randint(5 * oops + 1));
-
- /* Confusing. */
- set_confused(p_ptr->confused +
- randint(5 * oops + 1));
- }
-
- /* Redraw mana */
- p_ptr->redraw |= (PR_FRAME);
- }
-
- take_hit(damroll(1, 12), "perilous secrets");
-
- /* Confusing. */
- if (rand_int(5) == 0)
- {
- set_confused(p_ptr->confused + randint(10));
- }
-
- /* Exercise a little care... */
- if (rand_int(20) == 0)
- {
- take_hit(damroll(4, 10), "perilous secrets");
- }
-
- o_ptr->timeout = 1;
-
- break;
- }
-
case ACT_RAZORBACK:
{
if (!doit) return "star ball (150) every 1000 turns";
@@ -5412,7 +4888,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
autosave_checkpoint();
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
}
break;
@@ -5446,7 +4922,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
{
if (!doit) return "summon the Legion of the Dawn every 500+d500 turns";
msg_print("You summon the Legion of the Dawn.");
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DAWN, TRUE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DAWN, true);
o_ptr->timeout = 500 + randint(500);
@@ -5495,7 +4971,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
{
msg_print("The hold of the Black Breath on you is broken!");
}
- p_ptr->black_breath = FALSE;
+ p_ptr->black_breath = false;
hp_player(100);
o_ptr->timeout = 200;
@@ -5535,7 +5011,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
else
{
if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2),
- SUMMON_THUNDERLORD, (plev == 50 ? TRUE : FALSE)))
+ SUMMON_THUNDERLORD, (plev == 50 ? true : false)))
{
msg_print("A Thunderlord comes from thin air!");
msg_print("'I will help you in your difficult task.'");
@@ -5566,7 +5042,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
msg_print("Your pick twists in your hands.");
if (!get_aim_dir(&dir)) break;
- if (passwall(dir, TRUE))
+ if (passwall(dir, true))
{
msg_print("A passage opens, and you step through.");
}
@@ -5625,7 +5101,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
msg_print("Your horn calls for help.");
for (i = 0; i < 15; i++)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2), SUMMON_HUMAN, TRUE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2), SUMMON_HUMAN, true);
}
o_ptr->timeout = 1000;
@@ -6121,7 +5597,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
{
if (!doit) return "genocide every 500 turns";
msg_print("It glows deep blue...");
- genocide(TRUE);
+ genocide();
o_ptr->timeout = 500;
@@ -6132,7 +5608,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
{
if (!doit) return "mass genocide every 1000 turns";
msg_print("It lets out a long, shrill note...");
- mass_genocide(TRUE);
+ mass_genocide();
o_ptr->timeout = 1000;
@@ -6197,7 +5673,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
case ACT_SUMMON_ANIMAL:
{
if (!doit) return "summon animal every 200+d300 turns";
- summon_specific_friendly(p_ptr->py, p_ptr->px, plev, SUMMON_ANIMAL_RANGER, TRUE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, plev, SUMMON_ANIMAL_RANGER, true);
o_ptr->timeout = 200 + randint(300);
@@ -6208,7 +5684,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
{
if (!doit) return "summon phantasmal servant every 200+d200 turns";
msg_print("You summon a phantasmal servant.");
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_PHANTOM, TRUE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_PHANTOM, true);
o_ptr->timeout = 200 + randint(200);
@@ -6229,7 +5705,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
else
{
if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2),
- SUMMON_ELEMENTAL, (plev == 50 ? TRUE : FALSE)))
+ SUMMON_ELEMENTAL, (plev == 50 ? true : false)))
{
msg_print("An elemental materialises...");
msg_print("It seems obedient to you.");
@@ -6255,7 +5731,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
else
{
if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2),
- SUMMON_DEMON, (plev == 50 ? TRUE : FALSE)))
+ SUMMON_DEMON, (plev == 50 ? true : false)))
{
msg_print("The area fills with a stench of sulphur and brimstone.");
msg_print("'What is thy bidding... Master?'");
@@ -6283,7 +5759,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
{
if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2),
(plev > 47 ? SUMMON_HI_UNDEAD_NO_UNIQUES : SUMMON_UNDEAD),
- (((plev > 24) && (randint(3) == 1)) ? TRUE : FALSE)))
+ (((plev > 24) && (randint(3) == 1)) ? true : false)))
{
msg_print("Cold winds begin to blow around you, carrying with them the stench of decay...");
msg_print("Ancient, long-dead forms arise from the ground to serve you!");
@@ -6347,12 +5823,12 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
{
if (!doit) return format("restore stats and life levels every %d turns", (is_junkart ? 200 : 750));
msg_print("It glows a deep green...");
- do_res_stat(A_STR, TRUE);
- do_res_stat(A_INT, TRUE);
- do_res_stat(A_WIS, TRUE);
- do_res_stat(A_DEX, TRUE);
- do_res_stat(A_CON, TRUE);
- do_res_stat(A_CHR, TRUE);
+ do_res_stat(A_STR, true);
+ do_res_stat(A_INT, true);
+ do_res_stat(A_WIS, true);
+ do_res_stat(A_DEX, true);
+ do_res_stat(A_CON, true);
+ do_res_stat(A_CHR, true);
restore_level();
o_ptr->timeout = 750;
@@ -6529,33 +6005,11 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
case ACT_DETECT_XTRA:
{
- if (!doit) return "detection and identify true every 1000 turns";
+ if (!doit) return "detection every 500 turns";
msg_print("It glows brightly...");
detect_all(DEFAULT_RADIUS);
- identify_fully();
-
- o_ptr->timeout = 1000;
- break;
- }
-
- case ACT_ID_FULL:
- {
- if (!doit) return "identify true every 750 turns";
- msg_print("It glows yellow...");
- identify_fully();
-
- o_ptr->timeout = 750;
-
- break;
- }
-
- case ACT_ID_PLAIN:
- {
- if (!doit) return "identify spell every 10 turns";
- if (!ident_spell()) break;
-
- o_ptr->timeout = 10;
+ o_ptr->timeout = 500;
break;
}
@@ -6710,12 +6164,12 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
msg_print("Your nerves and muscles feel weak and lifeless!");
take_hit(damroll(10, 10), "activating Ruination");
- dec_stat(A_DEX, 25, TRUE);
- dec_stat(A_WIS, 25, TRUE);
- dec_stat(A_CON, 25, TRUE);
- dec_stat(A_STR, 25, TRUE);
- dec_stat(A_CHR, 25, TRUE);
- dec_stat(A_INT, 25, TRUE);
+ dec_stat(A_DEX, 25, true);
+ dec_stat(A_WIS, 25, true);
+ dec_stat(A_CON, 25, true);
+ dec_stat(A_STR, 25, true);
+ dec_stat(A_CHR, 25, true);
+ dec_stat(A_INT, 25, true);
/* Timeout is set before return */
@@ -6735,7 +6189,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
case ACT_UNINT:
{
if (!doit) return "decreasing Intelligence";
- dec_stat(A_INT, 25, FALSE);
+ dec_stat(A_INT, 25, false);
/* Timeout is set before return */
@@ -6745,7 +6199,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
case ACT_UNSTR:
{
if (!doit) return "decreasing Strength";
- dec_stat(A_STR, 25, FALSE);
+ dec_stat(A_STR, 25, false);
/* Timeout is set before return */
@@ -6755,7 +6209,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
case ACT_UNCON:
{
if (!doit) return "decreasing Constitution";
- dec_stat(A_CON, 25, FALSE);
+ dec_stat(A_CON, 25, false);
/* Timeout is set before return */
@@ -6765,7 +6219,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
case ACT_UNCHR:
{
if (!doit) return "decreasing Charisma";
- dec_stat(A_CHR, 25, FALSE);
+ dec_stat(A_CHR, 25, false);
/* Timeout is set before return */
@@ -6775,7 +6229,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
case ACT_UNDEX:
{
if (!doit) return "decreasing Dexterity";
- dec_stat(A_DEX, 25, FALSE);
+ dec_stat(A_DEX, 25, false);
/* Timeout is set before return */
@@ -6785,7 +6239,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
case ACT_UNWIS:
{
if (!doit) return "decreasing Wisdom";
- dec_stat(A_WIS, 25, FALSE);
+ dec_stat(A_WIS, 25, false);
/* Timeout is set before return */
@@ -6795,12 +6249,12 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
case ACT_STATLOSS:
{
if (!doit) return "stat loss";
- dec_stat(A_STR, 15, FALSE);
- dec_stat(A_INT, 15, FALSE);
- dec_stat(A_WIS, 15, FALSE);
- dec_stat(A_DEX, 15, FALSE);
- dec_stat(A_CON, 15, FALSE);
- dec_stat(A_CHR, 15, FALSE);
+ dec_stat(A_STR, 15, false);
+ dec_stat(A_INT, 15, false);
+ dec_stat(A_WIS, 15, false);
+ dec_stat(A_DEX, 15, false);
+ dec_stat(A_CON, 15, false);
+ dec_stat(A_CHR, 15, false);
/* Timeout is set before return */
@@ -6810,12 +6264,12 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
case ACT_HISTATLOSS:
{
if (!doit) return "high stat loss";
- dec_stat(A_STR, 25, FALSE);
- dec_stat(A_INT, 25, FALSE);
- dec_stat(A_WIS, 25, FALSE);
- dec_stat(A_DEX, 25, FALSE);
- dec_stat(A_CON, 25, FALSE);
- dec_stat(A_CHR, 25, FALSE);
+ dec_stat(A_STR, 25, false);
+ dec_stat(A_INT, 25, false);
+ dec_stat(A_WIS, 25, false);
+ dec_stat(A_DEX, 25, false);
+ dec_stat(A_CON, 25, false);
+ dec_stat(A_CHR, 25, false);
/* Timeout is set before return */
@@ -6945,7 +6399,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
case ACT_PET_SUMMON:
{
if (!doit) return "summon pet every 101 turns";
- summon_specific_friendly(p_ptr->py, p_ptr->px, max_dlv[dungeon_type], 0, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, max_dlv[dungeon_type], 0, false);
/* Timeout is set before return */
/*FINDME*/
@@ -7081,7 +6535,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
case ACT_ACQUIREMENT:
{
if (!doit) return "acquirement every 3000 turns";
- acquirement(p_ptr->py, p_ptr->px, 1, FALSE, FALSE);
+ acquirement(p_ptr->py, p_ptr->px, 1, false);
/* Timeout is set before return */
@@ -7176,7 +6630,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
if (c_ptr->m_idx)
{
/* Update the monster */
- update_mon(c_ptr->m_idx, FALSE);
+ update_mon(c_ptr->m_idx, false);
}
/* Redraw */
@@ -7185,7 +6639,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
}
}
- if (!get_aim_dir(&dir)) return (FALSE);
+ if (!get_aim_dir(&dir)) return nullptr;
msg_print("The light around you is absorbed... "
"and released in a powerful bolt!");
@@ -7581,7 +7035,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
if (!doit) return "grow mushrooms every 50+d50 turns";
msg_print("You twirl and spores fly everywhere!");
for (i = 0; i < 8; i++)
- summon_specific_friendly(p_ptr->py, p_ptr->px, p_ptr->lev, SUMMON_BIZARRE1, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, p_ptr->lev, SUMMON_BIZARRE1, false);
o_ptr->timeout = randint(50) + 50;
diff --git a/src/cmd6.hpp b/src/cmd6.hpp
index 076a9abb..2d17c6cf 100644
--- a/src/cmd6.hpp
+++ b/src/cmd6.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_type_fwd.hpp"
void set_stick_mode(object_type *o_ptr);
@@ -11,7 +11,7 @@ void do_cmd_read_scroll();
void do_cmd_aim_wand();
void do_cmd_use_staff();
void do_cmd_zap_rod();
-const char *activation_aux(object_type *o_ptr, bool_ desc, int item);
+const char *activation_aux(object_type *o_ptr, bool desc, int item);
void do_cmd_activate();
void do_cmd_cut_corpse();
void do_cmd_cure_meat();
diff --git a/src/cmd7.cc b/src/cmd7.cc
index ec13c908..0b9a8a82 100644
--- a/src/cmd7.cc
+++ b/src/cmd7.cc
@@ -35,11 +35,10 @@
#include "stats.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "xtra1.hpp"
#include "xtra2.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
#include <fmt/format.h>
@@ -112,8 +111,6 @@ void mindcraft_info(char *p, int power)
*/
void mimic_info(char *p, int power)
{
- auto const &k_info = game->edit_data.k_info;
-
int plev = get_skill(SKILL_MIMICRY);
object_type *o_ptr = &p_ptr->inventory[INVEN_OUTER];
@@ -124,7 +121,7 @@ void mimic_info(char *p, int power)
switch (power)
{
case 0:
- strnfmt(p, 80, " dur %d", k_info[o_ptr->k_idx].pval2 + get_skill_scale(SKILL_MIMICRY, 1000));
+ strnfmt(p, 80, " dur %d", o_ptr->k_ptr->pval2 + get_skill_scale(SKILL_MIMICRY, 1000));
break;
case 1:
strnfmt(p, 80, " dur %d+d20", 10 + plev);
@@ -212,18 +209,18 @@ static void display_magic_powers(
/*
* Allow user to choose a magic power.
*
- * If a valid spell is chosen, saves it in '*sn' and returns TRUE
- * If the user hits escape, returns FALSE, and set '*sn' to -1
- * If there are no legal choices, returns FALSE, and sets '*sn' to -2
+ * If a valid spell is chosen, saves it in '*sn' and returns true
+ * If the user hits escape, returns false, and set '*sn' to -1
+ * If there are no legal choices, returns false, and sets '*sn' to -2
*
* The "prompt" should be "cast", "recite", or "study"
- * The "known" should be TRUE for cast/pray, FALSE for study
+ * The "known" should be true for cast/pray, false for study
*
* nb: This function has a (trivial) display bug which will be obvious
* when you run it. It's probably easy to fix but I haven't tried,
* sorry.
*/
-static bool_ get_magic_power(int *sn, magic_power *powers, int max_powers,
+static bool get_magic_power(int *sn, magic_power *powers, int max_powers,
void (*power_info)(char *p, int power), int plev, int cast_stat)
{
int i;
@@ -240,11 +237,11 @@ static bool_ get_magic_power(int *sn, magic_power *powers, int max_powers,
char out_val[160];
- cptr p = "power";
+ const char *p = "power";
magic_power spell;
- bool_ flag;
+ bool flag;
/* Assume cancelled */
@@ -257,12 +254,12 @@ static bool_ get_magic_power(int *sn, magic_power *powers, int max_powers,
if (powers[*sn].min_lev <= plev)
{
/* Success */
- return (TRUE);
+ return true;
}
}
/* Nothing chosen yet */
- flag = FALSE;
+ flag = false;
/* Count number of powers that satisfies minimum plev requirement */
for (i = 0; i < max_powers; i++)
@@ -278,8 +275,7 @@ static bool_ get_magic_power(int *sn, magic_power *powers, int max_powers,
p, I2A(0), I2A(num - 1), toupper(I2A(0)), toupper(I2A(num - 1)), p);
/* Save the screen */
- character_icky = TRUE;
- Term_save();
+ screen_save_no_flush();
/* Show the list */
display_magic_powers(powers, max_powers, power_info, plev, cast_stat, y, x);
@@ -310,11 +306,10 @@ static bool_ get_magic_power(int *sn, magic_power *powers, int max_powers,
if (info)
{
c_prt(TERM_L_BLUE, spell.desc, 1, 0);
+ inkey();
/* Restore the screen */
- inkey();
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
/* Redisplay choices */
display_magic_powers(powers, max_powers, power_info, plev, cast_stat, y, x);
@@ -322,15 +317,17 @@ static bool_ get_magic_power(int *sn, magic_power *powers, int max_powers,
}
/* Stop the loop */
- flag = TRUE;
+ flag = true;
}
/* Restore the screen */
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
/* Abort if needed */
- if (!flag) return (FALSE);
+ if (!flag)
+ {
+ return false;
+ }
/* Save the choice */
(*sn) = i;
@@ -339,7 +336,7 @@ static bool_ get_magic_power(int *sn, magic_power *powers, int max_powers,
repeat_push(*sn);
/* Success */
- return (TRUE);
+ return true;
}
@@ -349,6 +346,8 @@ static bool_ get_magic_power(int *sn, magic_power *powers, int max_powers,
*/
void do_cmd_mindcraft()
{
+ auto const &dungeon_flags = game->dungeon_flags;
+
int n = 0, b = 0;
int chance;
@@ -457,7 +456,7 @@ void do_cmd_mindcraft()
msg_print("Your mind unleashes its power in an uncontrollable storm!");
project(1, 2 + plev / 10, p_ptr->py, p_ptr->px, plev * 2,
GF_MANA, PROJECT_JUMP | PROJECT_KILL | PROJECT_GRID | PROJECT_ITEM);
- p_ptr->csp = MAX(0, p_ptr->csp - plev * MAX(1, plev / 10));
+ p_ptr->csp = std::max(0, p_ptr->csp - plev * std::max(1, plev / 10));
}
}
}
@@ -611,15 +610,8 @@ void do_cmd_mindcraft()
break;
}
- /* Psychometry */
- case 7:
- {
- ident_spell();
- break;
- }
-
/* Mindwave */
- case 8:
+ case 7:
{
msg_print("Mind-warping forces emanate from your brain!");
if (plev < 25)
@@ -636,7 +628,7 @@ void do_cmd_mindcraft()
}
/* Adrenaline */
- case 9:
+ case 8:
{
set_afraid(0);
set_stun(0);
@@ -667,7 +659,7 @@ void do_cmd_mindcraft()
}
/* Psychic Drain */
- case 10:
+ case 9:
{
if (!get_aim_dir(&dir)) return;
@@ -682,7 +674,7 @@ void do_cmd_mindcraft()
}
/* Telekinesis */
- case 11:
+ case 10:
{
msg_print("A wave of pure physical force radiates out from your body!");
project(0, 3 + plev / 10, p_ptr->py, p_ptr->px,
@@ -729,7 +721,7 @@ void do_cmd_mindcraft()
/* Damage WIS (possibly permanently) */
if (rand_int(100) < 50)
{
- bool_ perm = (rand_int(100) < 25);
+ bool perm = (rand_int(100) < 25);
/* Message */
msg_print("You have damaged your mind!");
@@ -764,13 +756,6 @@ static int get_mimic_chance(int mimic)
void do_cmd_mimic_lore()
{
- auto const &k_info = game->edit_data.k_info;
-
- int fail;
-
- object_type *o_ptr;
-
-
/* Player has to be able to see */
if (p_ptr->blind || no_lite())
{
@@ -797,7 +782,7 @@ void do_cmd_mimic_lore()
/* Not in mimic forms -- Allow transformations */
else
{
- o_ptr = &p_ptr->inventory[INVEN_OUTER];
+ object_type const *o_ptr = &p_ptr->inventory[INVEN_OUTER];
if ((o_ptr->tval != TV_CLOAK) || (o_ptr->sval != SV_MIMIC_CLOAK))
{
@@ -806,7 +791,7 @@ void do_cmd_mimic_lore()
}
/* Calculate failure rate */
- fail = get_mimic_chance(o_ptr->pval2);
+ auto const fail = get_mimic_chance(o_ptr->pval2);
if (fail > 75)
{
@@ -832,7 +817,7 @@ void do_cmd_mimic_lore()
/* Success */
else
{
- set_mimic(k_info[o_ptr->k_idx].pval2 + get_skill_scale(SKILL_MIMICRY, 1000), o_ptr->pval2, get_skill(SKILL_MIMICRY));
+ set_mimic(o_ptr->k_ptr->pval2 + get_skill_scale(SKILL_MIMICRY, 1000), o_ptr->pval2, get_skill(SKILL_MIMICRY));
}
}
@@ -874,11 +859,11 @@ void do_cmd_mimic()
magic_power spell;
- static bool_ added_hooks = FALSE;
+ static bool added_hooks = false;
if(!added_hooks)
{
add_hook_new(HOOK_FORBID_TRAVEL, mimic_forbid_travel, "mimic_forbid_travel", NULL);
- added_hooks = TRUE;
+ added_hooks = true;
}
/* No magic */
@@ -1136,7 +1121,7 @@ void do_cmd_mimic()
/* Damage WIS (possibly permanently) */
if (rand_int(100) < 50)
{
- bool_ perm = (rand_int(100) < 25);
+ bool perm = (rand_int(100) < 25);
/* Message */
msg_print("You have damaged your mind!");
@@ -1183,7 +1168,7 @@ void do_cmd_beastmaster()
/* XXX XXX */
if (rand_int(80-(plev) - p_ptr->stat_use[5]-p_ptr->to_s) < 20)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, plev, rand_int(plev / 2), FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, plev, rand_int(plev / 2), false);
}
}
else msg_print("You can't summon more pets");
@@ -1308,11 +1293,8 @@ static random_spell* select_spell_from_batch(std::size_t batch)
char which;
random_spell* ret = nullptr;
- /* Enter "icky" mode */
- character_icky = TRUE;
-
/* Save the screen */
- Term_save();
+ screen_save_no_flush();
int const mut_max = (random_spells.size() < (batch + 1) * 10)
? random_spells.size() - batch * 10
@@ -1323,7 +1305,7 @@ static random_spell* select_spell_from_batch(std::size_t batch)
prt(tmp, 0, 0);
- while (1)
+ while (true)
{
/* Print power list */
print_spell_batch(batch, mut_max);
@@ -1373,10 +1355,7 @@ static random_spell* select_spell_from_batch(std::size_t batch)
}
/* Restore the screen */
- Term_load();
-
- /* Leave "icky" mode */
- character_icky = FALSE;
+ screen_load_no_flush();
/* Return selection */
return (ret);
@@ -1413,26 +1392,20 @@ static random_spell* select_spell()
/* How many spells in the last batch? */
int batch_max = (random_spells.size() - 1) / 10;
- /* Enter "icky" mode */
- character_icky = TRUE;
-
/* Save the screen */
- Term_save();
+ screen_save_no_flush();
strnfmt(tmp, 160, "(a-%c) Select batch of powers: ", I2A(batch_max));
prt(tmp, 0, 0);
- while (1)
+ while (true)
{
which = inkey();
if (which == ESCAPE)
{
- Term_load();
-
ret = NULL;
-
break;
}
@@ -1440,10 +1413,7 @@ static random_spell* select_spell()
{
if (batch_max == 0)
{
- Term_load();
-
ret = select_spell_from_batch(0);
-
break;
}
@@ -1453,10 +1423,7 @@ static random_spell* select_spell()
which = tolower(which);
if (isalpha(which) && (A2I(which) <= batch_max))
{
- Term_load();
-
ret = select_spell_from_batch(A2I(which));
-
break;
}
else
@@ -1465,8 +1432,8 @@ static random_spell* select_spell()
}
}
- /* Leave "icky" mode */
- character_icky = FALSE;
+ /* Restore screen */
+ screen_load_no_flush();
return (ret);
}
@@ -1689,7 +1656,7 @@ void brand_ammo(int brand_type, int bolts_only)
o_ptr->name2 = aura_type;
/* Apply the ego */
- apply_magic(o_ptr, dun_level, FALSE, FALSE, FALSE);
+ apply_magic(o_ptr, dun_level, false, false, false);
o_ptr->discount = 100;
enchant(o_ptr, rand_int(3) + 4, ENCH_TOHIT | ENCH_TODAM);
@@ -1710,7 +1677,7 @@ void summon_monster(int sumtype)
/* Take a turn */
energy_use = 100;
- if (summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level + randint(5), sumtype, TRUE))
+ if (summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level + randint(5), sumtype, true))
{
msg_print("You summon some help.");
}
@@ -1747,7 +1714,7 @@ void do_cmd_possessor()
}
- while (TRUE)
+ while (true)
{
if (!get_com("Use your [R]ace powers or your [I]ncarnating powers?", &ch))
{
@@ -1789,7 +1756,7 @@ void do_cmd_possessor()
}
else
{
- do_cmd_leave_body(TRUE);
+ do_cmd_leave_body(true);
}
}
else
@@ -1857,7 +1824,7 @@ void do_cmd_archer()
strnfmt(com, 80, "Create [S]hots? ");
}
- while (TRUE)
+ while (true)
{
if (!get_com(com, &ch))
{
@@ -1905,14 +1872,12 @@ void do_cmd_archer()
q_ptr->number = (byte)rand_range(15, 30);
else
q_ptr->number = 1;
- object_aware(q_ptr);
- object_known(q_ptr);
- q_ptr->ident |= IDENT_MENTAL;
- apply_magic(q_ptr, dun_level, TRUE, TRUE, (magik(20)) ? TRUE : FALSE);
+
+ apply_magic(q_ptr, dun_level, true, true, (magik(20)) ? true : false);
q_ptr->discount = 90;
q_ptr->found = OBJ_FOUND_SELFMADE;
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
msg_print("You make some ammo.");
@@ -1944,10 +1909,8 @@ void do_cmd_archer()
q_ptr->number = (byte)rand_range(15, 30);
else
q_ptr->number = 1;
- object_aware(q_ptr);
- object_known(q_ptr);
- q_ptr->ident |= IDENT_MENTAL;
- apply_magic(q_ptr, dun_level, TRUE, TRUE, (magik(20)) ? TRUE : FALSE);
+
+ apply_magic(q_ptr, dun_level, true, true, (magik(20)) ? true : false);
q_ptr->discount = 90;
q_ptr->found = OBJ_FOUND_SELFMADE;
@@ -1955,7 +1918,7 @@ void do_cmd_archer()
inc_stack_size(item, -1);
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
}
/**********Create bolts*********/
@@ -1980,10 +1943,8 @@ void do_cmd_archer()
q_ptr->number = (byte)rand_range(15, 30);
else
q_ptr->number = 1;
- object_aware(q_ptr);
- object_known(q_ptr);
- q_ptr->ident |= IDENT_MENTAL;
- apply_magic(q_ptr, dun_level, TRUE, TRUE, (magik(20)) ? TRUE : FALSE);
+
+ apply_magic(q_ptr, dun_level, true, true, (magik(20)) ? true : false);
q_ptr->discount = 90;
q_ptr->found = OBJ_FOUND_SELFMADE;
@@ -1991,7 +1952,7 @@ void do_cmd_archer()
inc_stack_size(item, -1);
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
}
}
@@ -2012,7 +1973,7 @@ void do_cmd_set_piercing()
strnfmt(com, 80, "Allow shots to pierce? ");
- while (TRUE)
+ while (true)
{
if (!get_com(com, &ch))
{
@@ -2070,6 +2031,8 @@ void necro_info(char *p, int power)
*/
void do_cmd_necromancer()
{
+ auto &k_info = game->edit_data.k_info;
+
int n = 0, b = 0;
int chance;
int dir;
@@ -2238,23 +2201,20 @@ void do_cmd_necromancer()
object_type forge, *o_ptr = &forge;
int k_idx = test_item_name("& Necromantic Teeth~");
- k_allow_special[k_idx] = TRUE;
+ k_info[k_idx]->allow_special = true;
object_prep(o_ptr, k_idx);
- apply_magic(o_ptr, plev * 2, TRUE, TRUE, TRUE);
+ apply_magic(o_ptr, plev * 2, true, true, true);
o_ptr->art_flags |= TR_TEMPORARY;
o_ptr->timeout = dur;
/* These objects are "storebought" */
- o_ptr->ident |= IDENT_MENTAL;
o_ptr->number = 1;
- object_aware(o_ptr);
- object_known(o_ptr);
- inven_carry(o_ptr, FALSE);
+ inven_carry(o_ptr, false);
- k_allow_special[k_idx] = FALSE;
+ k_info[k_idx]->allow_special = false;
break;
}
@@ -2347,7 +2307,7 @@ void do_cmd_necromancer()
/* Damage CON (possibly permanently) */
if (rand_int(100) < 50)
{
- bool_ perm = (rand_int(100) < 25);
+ bool perm = (rand_int(100) < 25);
/* Message */
msg_print("You have damaged your body!");
@@ -2373,7 +2333,7 @@ s32b sroot(s32b n)
if (n < 2) return (n);
- while (1)
+ while (true)
{
s32b err = (i - n / (i + 1)) / 2;
@@ -2422,7 +2382,7 @@ void do_cmd_unbeliever()
/* Select what to do */
- while (TRUE)
+ while (true)
{
if (!get_com("Disrupt [C]ontinuum or [D]estroy Doors", &ch))
{
@@ -2520,10 +2480,10 @@ void do_cmd_summoner_extract()
/* Get the item */
object_type *o_ptr = get_object(item);
- bool_ partial;
+ bool partial;
if (r_info[o_ptr->pval2].flags & RF_UNIQUE)
{
- partial = FALSE;
+ partial = false;
}
else
{
@@ -2550,10 +2510,7 @@ void do_cmd_summoner_extract()
q_ptr->pval2 = 0;
q_ptr->number = 1;
q_ptr->found = OBJ_FOUND_SELFMADE;
- object_aware(q_ptr);
- object_known(q_ptr);
- q_ptr->ident |= IDENT_MENTAL;
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
msg_print("You extract a totem from the dead corpse.");
energy_use += 100;
@@ -2566,7 +2523,7 @@ void summon_true(int r_idx, int item)
int i, status, x = 1, y = 1, rx, ry = 0, chance;
- bool_ used;
+ bool used;
auto r_ptr = &r_info[r_idx];
@@ -2575,7 +2532,7 @@ void summon_true(int r_idx, int item)
if (r_ptr->flags & RF_UNIQUE)
{
/* Because it's unique, it will always be destroyed */
- used = TRUE;
+ used = true;
/* About twice as hard as non-uniques */
chance = (get_skill(SKILL_SUMMON) * 70 / (r_ptr->level + 1));
@@ -2595,16 +2552,16 @@ void summon_true(int r_idx, int item)
{
if (get_skill(SKILL_SUMMON) == 0)
{
- used = TRUE;
+ used = true;
}
else
{
/* It can be used multiple times */
- used = FALSE;
+ used = false;
/* But it is not 100% sure (note: skill > 0) */
chance = (r_ptr->level * 25 / get_skill(SKILL_SUMMON));
- if (magik(chance)) used = TRUE;
+ if (magik(chance)) used = true;
}
chance = (get_skill(SKILL_SUMMON) * 130 / (r_ptr->level + 1));
@@ -2640,8 +2597,8 @@ void summon_true(int r_idx, int item)
}
/* Summon the monster */
- bypass_r_ptr_max_num = TRUE;
- if (!(i = place_monster_one (y, x, r_idx, 0, 0, status)))
+ bypass_r_ptr_max_num = true;
+ if (!(i = place_monster_one (y, x, r_idx, 0, false, status)))
{
msg_print("The summoning fails.");
}
@@ -2650,7 +2607,7 @@ void summon_true(int r_idx, int item)
m_list[i].status = status;
m_list[i].mflag |= MFLAG_NO_DROP;
}
- bypass_r_ptr_max_num = FALSE;
+ bypass_r_ptr_max_num = false;
/* Destroy the totem if the used flag is set */
if (used)
@@ -2658,9 +2615,6 @@ void summon_true(int r_idx, int item)
/* Eliminate the totem */
inc_stack_size(item, -1);
}
-
- /* Done */
- return;
}
@@ -2668,7 +2622,8 @@ void do_cmd_summoner_summon()
{
int item, x = 1, y = 1, rx, ry, m_idx = 0, i;
- cptr q, s;
+ const char *q;
+ const char *s;
monster_type *m_ptr;
@@ -2714,10 +2669,10 @@ void do_cmd_summoner_summon()
}
/* Summon the monster */
- bypass_r_ptr_max_num = TRUE;
- place_monster_one_no_drop = TRUE;
- m_idx = place_monster_one(y, x, o_ptr->pval, 0, 0, MSTATUS_PET);
- bypass_r_ptr_max_num = FALSE;
+ bypass_r_ptr_max_num = true;
+ place_monster_one_no_drop = true;
+ m_idx = place_monster_one(y, x, o_ptr->pval, 0, false, MSTATUS_PET);
+ bypass_r_ptr_max_num = false;
/* Failure. */
if (!m_idx)
@@ -2766,7 +2721,7 @@ void do_cmd_summoner()
}
/* Select what to do */
- while (TRUE)
+ while (true)
{
if (!get_com("[E]xtract a totem, [S]ummon", &ch))
{
@@ -2839,8 +2794,6 @@ void use_ability_blade()
{
msg_format("You will usually dodge successfully a level %d monster.", dun_level);
}
-
- return;
}
/*
@@ -2996,8 +2949,6 @@ void do_cmd_symbiotic()
object_aware(q_ptr);
object_known(q_ptr);
- q_ptr->ident |= IDENT_STOREB;
-
drop_near(q_ptr, 0, y, x);
delete_monster(y, x);
@@ -3042,19 +2993,18 @@ void do_cmd_symbiotic()
if (d >= 100) return;
- if ((m_idx = place_monster_one(y, x, o_ptr->pval, 0, FALSE, MSTATUS_PET)) == 0) return;
+ if ((m_idx = place_monster_one(y, x, o_ptr->pval, 0, false, MSTATUS_PET)) == 0) return;
- /* TODO fix this hack hack hack hackity hack with ToME 3 flags */
/* Have to be careful here; releasing the symbiote into a
- * dungeon with leveled monsters will level the symbiote
- * before we can get hold of it. We'll be nice and use the
- * larger of the saved exp and the exp that the newly-generated
- * monster starts with. */
+ * dungeon with leveled monsters will level the symbiote
+ * before we can get hold of it. We'll be nice and use the
+ * larger of the saved exp and the exp that the newly-generated
+ * monster starts with. */
m_ptr = &m_list[m_idx];
if (m_ptr->exp < o_ptr->exp)
{
m_ptr->exp = o_ptr->exp;
- monster_check_experience(m_idx, TRUE);
+ monster_check_experience(m_idx, true);
if (m_ptr->level != o_ptr->elevel)
cmsg_format(TERM_VIOLET, "ERROR: level-%d HYPNOS becomes level-%d symbiote", o_ptr->elevel, m_ptr->level);
}
@@ -3084,7 +3034,7 @@ void do_cmd_symbiotic()
{
s32b percent1, percent2;
- if (!o_ptr->k_idx)
+ if (!o_ptr->k_ptr)
{
msg_print("You are not in symbiosis.");
break;
@@ -3115,7 +3065,7 @@ void do_cmd_symbiotic()
/* Minor Symbiotic Powers */
case 4:
{
- if (!o_ptr->k_idx)
+ if (!o_ptr->k_ptr)
{
msg_print("You are not in symbiosis.");
break;
@@ -3130,17 +3080,20 @@ void do_cmd_symbiotic()
/* Heal Symbiote */
case 5:
{
- int hp;
-
- if (!o_ptr->k_idx)
+ if (!o_ptr->k_ptr)
{
msg_print("You are not in symbiosis.");
break;
}
- hp = o_ptr->pval3 * (15 + get_skill_scale(SKILL_SYMBIOTIC, 35)) / 100;
+ int const hp =
+ o_ptr->pval3 * (15 + get_skill_scale(SKILL_SYMBIOTIC, 35)) / 100;
+
o_ptr->pval2 += hp;
- if (o_ptr->pval2 > o_ptr->pval3) o_ptr->pval2 = o_ptr->pval3;
+ if (o_ptr->pval2 > o_ptr->pval3)
+ {
+ o_ptr->pval2 = o_ptr->pval3;
+ }
msg_format("%s is healed.", symbiote_name(true).c_str());
@@ -3154,13 +3107,13 @@ void do_cmd_symbiotic()
/* Major Symbiotic Powers */
case 6:
{
- if (!o_ptr->k_idx)
+ if (!o_ptr->k_ptr)
{
msg_print("You are not in symbiosis.");
break;
}
- if(0 > use_symbiotic_power(o_ptr->pval, true))
+ if (0 > use_symbiotic_power(o_ptr->pval, true))
return;
break;
@@ -3169,7 +3122,7 @@ void do_cmd_symbiotic()
/* Summon never-moving pet */
case 7:
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_MINE, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_MINE, false);
break;
}
@@ -3228,7 +3181,7 @@ void do_cmd_symbiotic()
/* Damage CON (possibly permanently) */
if (rand_int(100) < 50)
{
- bool_ perm = (rand_int(100) < 25);
+ bool perm = (rand_int(100) < 25);
/* Message */
msg_print("You have damaged your body!");
@@ -3275,13 +3228,10 @@ void do_cmd_create_boulder()
/* Hack -- Give the player some shots */
object_prep(q_ptr, lookup_kind(TV_JUNK, SV_BOULDER));
q_ptr->number = (byte)rand_range(2, 5);
- object_aware(q_ptr);
- object_known(q_ptr);
- q_ptr->ident |= IDENT_MENTAL;
q_ptr->discount = 90;
q_ptr->found = OBJ_FOUND_SELFMADE;
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
msg_print("You make some boulders.");
diff --git a/src/cmd7.hpp b/src/cmd7.hpp
index b9d518b2..e7dcb2ae 100644
--- a/src/cmd7.hpp
+++ b/src/cmd7.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_type_fwd.hpp"
void do_cmd_pray();
diff --git a/src/config.h b/src/config.hpp
index 290ec624..eb7795b4 100644
--- a/src/config.h
+++ b/src/config.hpp
@@ -68,34 +68,6 @@
#define MONSTER_FLOW_DEPTH 32
-
-
-/*
- * OPTION: Set the "default" path to the angband "lib" directory.
- *
- * See "main.c" for usage, and note that this value is only used on
- * certain machines, primarily Unix machines. If this value is used,
- * it will be over-ridden by the "ANGBAND_PATH" environment variable,
- * if that variable is defined and accessable. The final slash is
- * optional, but it may eventually be required.
- *
- * Using the value "./lib/" below tells Angband that, by default,
- * the user will run "angband" from the same directory that contains
- * the "lib" directory. This is a reasonable (but imperfect) default.
- *
- * If at all possible, you should change this value to refer to the
- * actual location of the "lib" folder, for example, "/tmp/angband/lib/"
- * or "/usr/games/lib/angband/", or "/pkg/angband/lib".
- *
- * Additional note -- if you are planning to use makefile.org, don't bother
- * setting this variable, as it is overridden by a value set near the top of
- * that file.
- */
-#ifndef DEFAULT_PATH
-# define DEFAULT_PATH "./lib/"
-#endif
-
-
/*
* Where to put the user's files.
*/
@@ -103,12 +75,6 @@
/*
- * OPTION: Person to bother if something goes wrong.
- */
-#define MAINTAINER "darkgod@t-o-m-e.net"
-
-
-/*
* OPTION: Default font (when using X11).
*/
#define DEFAULT_X11_FONT "9x15"
diff --git a/src/corrupt.cc b/src/corrupt.cc
index bd3ae5f0..b11f161c 100644
--- a/src/corrupt.cc
+++ b/src/corrupt.cc
@@ -13,6 +13,7 @@
#include "xtra1.hpp"
#include "xtra2.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#include <cassert>
#include <fmt/format.h>
@@ -25,11 +26,11 @@ struct corruption_type
{
int modules[3]; /* Modules where this corruption is available; terminated with -1 entry */
byte color;
- cptr group;
- cptr name;
- cptr get_text;
- cptr lose_text; /* If NULL, the corruption is NOT removable by any means */
- cptr desc;
+ const char *group;
+ const char *name;
+ const char *get_text;
+ const char *lose_text; /* If NULL, the corruption is NOT removable by any means */
+ const char *desc;
s16b depends[5]; /* terminated by a -1 entry */
s16b opposes[5]; /* terminated by a -1 entry */
void (*gain_callback)(); /* callback to invoke when gained */
@@ -51,7 +52,7 @@ static void player_gain_vampire_teeth()
player_race_mod *rmp_ptr = NULL;
- switch_subrace(SUBRACE_SAVE, TRUE);
+ switch_subrace(SUBRACE_SAVE, true);
rmp_ptr = &race_mod_info[SUBRACE_SAVE];
subrace_add_power(rmp_ptr, PWR_VAMPIRISM);
@@ -90,7 +91,7 @@ static void player_gain_vampire()
if (rmp_ptr->title == "Vampire")
{
- rmp_ptr->place = FALSE;
+ rmp_ptr->place = false;
}
else
{
@@ -172,7 +173,7 @@ corruption_type corruptions[CORRUPTIONS_MAX] =
"The presence of the Balrog seems to abandon you.",
" Allows you to turn into a Balrog at will\n"
" You need Balrog Wings, Balrog Aura and Balrog Strength to activate it",
- { CORRUPT_BALROG_AURA, CORRUPT_BALROG_WINGS, CORRUPT_BALROG_STRENGTH },
+ { CORRUPT_BALROG_AURA, CORRUPT_BALROG_WINGS, CORRUPT_BALROG_STRENGTH, -1 },
{ -1 },
NULL,
PWR_BALROG,
@@ -236,7 +237,7 @@ corruption_type corruptions[CORRUPTIONS_MAX] =
"You lose your attunement to the demon realm.",
" Provides access to the demon school skill and the use of demonic equipment\n"
" You need Demon Spirit, Demon Hide and Demon Breath to activate it",
- { CORRUPT_DEMON_SPIRIT, CORRUPT_DEMON_HIDE, CORRUPT_DEMON_BREATH },
+ { CORRUPT_DEMON_SPIRIT, CORRUPT_DEMON_HIDE, CORRUPT_DEMON_BREATH, -1 },
{ -1 },
NULL,
-1,
@@ -572,22 +573,6 @@ corruption_type corruptions[CORRUPTIONS_MAX] =
PWR_ILLUMINE,
},
- { /* 28 */
- { MODULE_THEME, -1 },
- TERM_RED,
- NULL /* no group */,
- "Detect Curses",
- "You can feel evil magics.",
- "You can no longer feel evil magics.",
- " You can feel the danger of evil magic.\n"
- " It detects cursed items in the inventory\n"
- " Level=7, Cost=14, Stat=WIS, Difficulty=14",
- { -1 },
- { -1 },
- NULL,
- PWR_DET_CURSE,
- },
-
{ /* 29 */
{ MODULE_THEME, -1 },
TERM_RED,
@@ -682,19 +667,19 @@ void init_corruptions()
/*
* Corruptions
*/
-bool_ player_has_corruption(int corruption_idx)
+bool player_has_corruption(int corruption_idx)
{
if (corruption_idx < 0)
{
- return FALSE;
+ return false;
}
- return (p_ptr->corruptions[corruption_idx]);
+ return p_ptr->corruptions[corruption_idx];
}
-static bool_ player_can_gain_corruption(int corruption_idx)
+static bool player_can_gain_corruption(int corruption_idx)
{
- bool_ allowed = TRUE; /* Allowed by default */
+ bool allowed = true; /* Allowed by default */
assert(corruption_idx >= 0);
@@ -703,7 +688,7 @@ static bool_ player_can_gain_corruption(int corruption_idx)
/* Ok trolls should not get this one. never. */
if (rp_ptr->title == "Troll")
{
- allowed = FALSE;
+ allowed = false;
}
}
@@ -714,14 +699,14 @@ static bool_ player_can_gain_corruption(int corruption_idx)
if (rp_ptr->title == "Maia")
{
/* We use a whitelist of corruptions for Maiar */
- bool_ allow = FALSE;
+ bool allow = false;
if ((corruption_idx == CORRUPT_BALROG_AURA) ||
(corruption_idx == CORRUPT_BALROG_WINGS) ||
(corruption_idx == CORRUPT_BALROG_STRENGTH) ||
(corruption_idx == CORRUPT_BALROG_FORM) ||
(corruption_idx == CORRUPT_DEMON_BREATH))
{
- allow = TRUE;
+ allow = true;
};
/* Mix result into 'allowed' flag */
@@ -733,10 +718,10 @@ static bool_ player_can_gain_corruption(int corruption_idx)
return allowed;
}
-static bool_ player_allow_corruption(int corruption_idx)
+static bool player_allow_corruption(int corruption_idx)
{
int i;
- bool_ found = FALSE;
+ bool found = false;
corruption_type *c_ptr = NULL;
assert(corruption_idx < CORRUPTIONS_MAX);
@@ -747,13 +732,13 @@ static bool_ player_allow_corruption(int corruption_idx)
{
if (c_ptr->modules[i] == game_module_idx)
{
- found = TRUE;
+ found = true;
}
}
if (!found)
{
- return FALSE;
+ return false;
}
/* Vampire teeth is special */
@@ -761,18 +746,18 @@ static bool_ player_allow_corruption(int corruption_idx)
{
if (race_flags_p(PR_NO_SUBRACE_CHANGE))
{
- return TRUE;
+ return true;
}
else
{
- return FALSE;
+ return false;
}
}
- return TRUE;
+ return true;
}
-static void player_set_corruption(int c, bool_ set)
+static void player_set_corruption(int c, bool set)
{
p_ptr->corruptions[c] = set;
p_ptr->redraw = p_ptr->redraw | PR_FRAME;
@@ -782,13 +767,12 @@ static void player_set_corruption(int c, bool_ set)
void player_gain_corruption(int corruption_idx)
{
- corruption_type *c_ptr = NULL;
assert(corruption_idx >= 0);
assert(corruption_idx < CORRUPTIONS_MAX);
- c_ptr = &corruptions[corruption_idx];
+ corruption_type *c_ptr = &corruptions[corruption_idx];
/* Set the player's corruption flag */
- player_set_corruption(corruption_idx, TRUE);
+ player_set_corruption(corruption_idx, true);
/* Invoke callback if necessary */
if (c_ptr->gain_callback)
@@ -802,7 +786,7 @@ static void player_lose_corruption(int corruption_idx)
assert(corruption_idx >= 0);
assert(corruption_idx < CORRUPTIONS_MAX);
- player_set_corruption(corruption_idx, FALSE);
+ player_set_corruption(corruption_idx, false);
/* Currently no corruptions need any special handling when lost */
}
@@ -815,9 +799,9 @@ static void player_lose_corruption(int corruption_idx)
* 3) have none of its opposing corruptions
* 4) pass the possible tests
*/
-static bool_ test_depend_corrupt(s16b corrupt_idx, bool_ can_gain)
+static bool test_depend_corrupt(s16b corrupt_idx, bool can_gain)
{
- s16b i;
+ size_t i;
corruption_type *c_ptr = NULL;
assert(corrupt_idx >= 0);
@@ -829,30 +813,30 @@ static bool_ test_depend_corrupt(s16b corrupt_idx, bool_ can_gain)
{
if (p_ptr->corruptions[corrupt_idx])
{
- return FALSE;
+ return false;
}
} else {
if (!p_ptr->corruptions[corrupt_idx])
{
- return FALSE;
+ return false;
}
}
/* Go through all dependencies */
- for (i=0; c_ptr->depends[i] >= 0; i++)
+ for (i=0; i < std::size(c_ptr->depends) && c_ptr->depends[i] >= 0; i++)
{
- if (!test_depend_corrupt(c_ptr->depends[i], FALSE))
+ if (!test_depend_corrupt(c_ptr->depends[i], false))
{
- return FALSE;
+ return false;
}
}
/* Go through all opposers */
- for (i=0; c_ptr->opposes[i] >= 0; i++)
+ for (i=0; i < std::size(c_ptr->depends) && c_ptr->opposes[i] >= 0; i++)
{
- if (test_depend_corrupt(c_ptr->opposes[i], FALSE))
+ if (test_depend_corrupt(c_ptr->opposes[i], false))
{
- return FALSE;
+ return false;
}
}
@@ -869,7 +853,7 @@ void gain_random_corruption()
max = 0;
for (i=0; i < CORRUPTIONS_MAX; i++)
{
- if (test_depend_corrupt(i, TRUE) &&
+ if (test_depend_corrupt(i, true) &&
player_allow_corruption(i))
{
pos[max] = i;
@@ -907,8 +891,8 @@ void lose_corruption()
max = 0;
for (i = 0; i < CORRUPTIONS_MAX; i++)
{
- bool_ is_removable = (corruptions[i].lose_text != NULL);
- if (test_depend_corrupt(i, FALSE) && is_removable)
+ bool is_removable = (corruptions[i].lose_text != NULL);
+ if (test_depend_corrupt(i, false) && is_removable)
{
pos[max] = i;
max = max + 1;
@@ -927,7 +911,7 @@ void lose_corruption()
/* Ok now lets see if it broke some dependencies */
for (i = 0; i < max - 1; i++)
{
- if (p_ptr->corruptions[pos[i]] != test_depend_corrupt(pos[i], FALSE))
+ if (p_ptr->corruptions[pos[i]] != test_depend_corrupt(pos[i], false))
{
remove_corruption(pos[i]);
}
@@ -977,7 +961,7 @@ std::string dump_corruptions(bool color, bool header)
* Get the power granted by a corruption. Returns -1
* if the given corruption does not grant a power.
*/
-s16b get_corruption_power(int corruption_idx)
+boost::optional<int> get_corruption_power(int corruption_idx)
{
corruption_type *c_ptr = NULL;
@@ -986,13 +970,13 @@ s16b get_corruption_power(int corruption_idx)
c_ptr = &corruptions[corruption_idx];
- if ((c_ptr->power >= 0) && (c_ptr->power < POWER_MAX))
+ if (c_ptr->power >= 0)
{
return c_ptr->power;
}
else
{
assert(c_ptr->power == -1); /* Sanity check: Should always be the case. */
- return -1;
+ return boost::none;
}
}
diff --git a/src/corrupt.hpp b/src/corrupt.hpp
index 77a7496e..9e185201 100644
--- a/src/corrupt.hpp
+++ b/src/corrupt.hpp
@@ -1,13 +1,12 @@
-#include "h-basic.h"
-
+#include <boost/optional.hpp>
#include <string>
void gain_random_corruption();
std::string dump_corruptions(bool color, bool header);
void lose_corruption();
-bool_ player_has_corruption(int corruption_idx);
+bool player_has_corruption(int corruption_idx);
void player_gain_corruption(int corruption_idx);
-s16b get_corruption_power(int corruption_idx);
+boost::optional<int> get_corruption_power(int corruption_idx);
/*
* Corruptions
@@ -40,7 +39,6 @@ s16b get_corruption_power(int corruption_idx);
#define MUT1_SWAP_POS 25
#define MUT1_SHRIEK 26
#define MUT1_ILLUMINE 27
-#define MUT1_DET_CURSE 28
#define MUT1_BERSERK 29
#define MUT1_MIDAS_TCH 30
#define MUT1_GROW_MOLD 31
diff --git a/src/defines.h b/src/defines.hpp
index 4a2ad0e0..16fe0951 100644
--- a/src/defines.h
+++ b/src/defines.hpp
@@ -1,7 +1,4 @@
-/* File: defines.h */
-
-/* Purpose: global constants and macro definitions */
-
+#pragma once
/*
* Do not edit this file unless you know *exactly* what you are doing.
@@ -37,8 +34,8 @@
*/
#ifndef IS_CVS
-#define IS_CVS " (ah)"
-/* #define IS_CVS " (ah, git)" */
+/* #define IS_CVS " (ah)" */
+#define IS_CVS " (ah, git)"
#endif
#define USER_PATH_VERSION "/2.4"
@@ -146,7 +143,7 @@
#define MA_FULL_SLOW 0x0010
/* Mindcraft */
-#define MAX_MINDCRAFT_POWERS 12
+#define MAX_MINDCRAFT_POWERS 11
/* Necromancy */
#define MAX_NECRO_POWERS 6
@@ -510,17 +507,6 @@
/* Explosive rune */
#define FEAT_MINOR_GLYPH 0x40
-/* Pattern */
-#define FEAT_PATTERN_START 0x41
-#define FEAT_PATTERN_1 0x42
-#define FEAT_PATTERN_2 0x43
-#define FEAT_PATTERN_3 0x44
-#define FEAT_PATTERN_4 0x45
-#define FEAT_PATTERN_END 0x46
-#define FEAT_PATTERN_OLD 0x47
-#define FEAT_PATTERN_XTRA1 0x48
-#define FEAT_PATTERN_XTRA2 0x49
-
/* Shops */
#define FEAT_SHOP 0x4A
@@ -735,7 +721,6 @@
#define ACT_FUNDIN 30
#define ACT_EOL 31
#define ACT_UMBAR 32
-#define ACT_KNOWLEDGE 34
#define ACT_UNDEATH 35
#define ACT_THRAIN 36
#define ACT_BARAHIR 37
@@ -744,7 +729,6 @@
#define ACT_NENYA 40
#define ACT_VILYA 41
#define ACT_POWER 42
-#define ACT_STONE_LORE 43
#define ACT_RAZORBACK 44
#define ACT_BLADETURNER 45
#define ACT_MEDIATOR 46
@@ -811,8 +795,6 @@
#define ACT_MAP_LIGHT 112
#define ACT_DETECT_ALL 113
#define ACT_DETECT_XTRA 114
-#define ACT_ID_FULL 115
-#define ACT_ID_PLAIN 116
#define ACT_RUNE_EXPLO 117
#define ACT_RUNE_PROT 118
#define ACT_SATIATE 119
@@ -927,9 +909,7 @@
#define TV_BOTTLE 2 /* Empty bottles ('!') */
#define TV_SPIKE 5 /* Spikes ('~') */
#define TV_MSTAFF 6 /* Mage Staffs */
-#define TV_CHEST 7 /* Chests ('~') */
#define TV_PARCHMENT 8 /* Parchments from Kamband */
-#define TV_PARCHEMENT 8 /* compatibility define */
#define TV_CORPSE 9 /* Monster corpses */
#define TV_EGG 10 /* Monster Eggs */
#define TV_JUNK 11 /* Sticks, Pottery, etc ('~') */
@@ -1188,36 +1168,18 @@
#define SV_LITE_TORCH_EVER 2
#define SV_LITE_DWARVEN 3
#define SV_LITE_FEANORIAN 4
-#define SV_LITE_GALADRIEL 100
-#define SV_LITE_ELENDIL 101
-#define SV_LITE_THRAIN 102
-#define SV_LITE_UNDEATH 103
-#define SV_LITE_PALANTIR 104
-#define SV_ANCHOR_SPACETIME 105
-#define SV_STONE_LORE 106
/* The "sval" codes for TV_AMULET */
#define SV_AMULET_DOOM 0
-#define SV_AMULET_TELEPORT 1
-#define SV_AMULET_SLOW_DIGEST 3
-#define SV_AMULET_RESIST_ACID 4
#define SV_AMULET_BRILLANCE 6
#define SV_AMULET_CHARISMA 7
#define SV_AMULET_THE_MAGI 8
#define SV_AMULET_REFLECTION 9
-#define SV_AMULET_CARLAMMAS 10
-#define SV_AMULET_INGWE 11
-#define SV_AMULET_DWARVES 12
#define SV_AMULET_NO_MAGIC 13
#define SV_AMULET_NO_TELE 14
#define SV_AMULET_RESISTANCE 15
-#define SV_AMULET_NOTHING 16
#define SV_AMULET_SERPENT 17
-#define SV_AMULET_TORIS_MEJISTOS 18
-#define SV_AMULET_ELESSAR 19
-#define SV_AMULET_EVENSTAR 20
-#define SV_AMULET_SUSTENANCE 21
#define SV_AMULET_TELEPATHY 22
#define SV_AMULET_TRICKERY 23
#define SV_AMULET_WEAPONMASTERY 24
@@ -1225,33 +1187,16 @@
#define SV_AMULET_INFRA 26
#define SV_AMULET_SPELL 27
#define SV_AMULET_WISDOM 28
-#define SV_AMULET_RESIST_ELEC 29
-#define SV_AMULET_REGEN 30
/* The sval codes for TV_RING */
#define SV_RING_WOE 0
-#define SV_RING_AGGRAVATION 1
#define SV_RING_WEAKNESS 2
#define SV_RING_STUPIDITY 3
-#define SV_RING_TELEPORTATION 4
#define SV_RING_SPECIAL 5
-#define SV_RING_SLOW_DIGESTION 6
-#define SV_RING_FEATHER_FALL 7
-#define SV_RING_RESIST_FIRE 8
-#define SV_RING_RESIST_COLD 9
-#define SV_RING_SUSTAIN_STR 10
-#define SV_RING_SUSTAIN_INT 11
-#define SV_RING_SUSTAIN_WIS 12
-#define SV_RING_SUSTAIN_CON 13
-#define SV_RING_SUSTAIN_DEX 14
-#define SV_RING_SUSTAIN_CHR 15
#define SV_RING_PROTECTION 16
#define SV_RING_ACID 17
#define SV_RING_FLAMES 18
#define SV_RING_ICE 19
-#define SV_RING_RESIST_POIS 20
-#define SV_RING_FREE_ACTION 21
-#define SV_RING_SEE_INVIS 22
#define SV_RING_STR 24
#define SV_RING_INT 25
#define SV_RING_DEX 26
@@ -1260,95 +1205,15 @@
#define SV_RING_DAMAGE 29
#define SV_RING_SLAYING 30
#define SV_RING_SPEED 31
-#define SV_RING_BARAHIR 32
-#define SV_RING_TULKAS 33
-#define SV_RING_NARYA 34
-#define SV_RING_NENYA 35
-#define SV_RING_VILYA 36
#define SV_RING_POWER 37
-#define SV_RING_RES_FEAR 38
-#define SV_RING_RES_LD 39
-#define SV_RING_RES_NETHER 40
-#define SV_RING_RES_NEXUS 41
-#define SV_RING_RES_SOUND 42
-#define SV_RING_RES_CONFUSION 43
-#define SV_RING_RES_SHARDS 44
-#define SV_RING_RES_DISENCHANT 45
-#define SV_RING_RES_CHAOS 46
-#define SV_RING_RES_BLINDNESS 47
#define SV_RING_LORDLY 48
#define SV_RING_ATTACKS 49
-#define SV_RING_NOTHING 50
-#define SV_RING_PRECONITION 51
-#define SV_RING_FLAR 52
#define SV_RING_INVIS 53
-#define SV_RING_FLYING 54
-#define SV_RING_WRAITH 55
-#define SV_RING_ELEC 56
-#define SV_RING_DURIN 57
-#define SV_RING_SPELL 58
#define SV_RING_CRIT 59
-/* The "sval" codes for TV_STAFF */
-#define SV_STAFF_SCHOOL 1
-#define SV_STAFF_NOTHING 2
-
-/* needed for monster traps */
-#define SV_STAFF_LIGHT 3
-#define SV_STAFF_FIERY_SHIELD 4
-#define SV_STAFF_REMOVE_CURSES 5
-#define SV_STAFF_WINGS_WIND 6
-#define SV_STAFF_SHAKE 7
-#define SV_STAFF_DISARM 8
-#define SV_STAFF_TELEPORTATION 9
-#define SV_STAFF_PROBABILITY_TRAVEL 10
-#define SV_STAFF_RECOVERY 11
-#define SV_STAFF_HEALING 12
-#define SV_STAFF_VISION 13
-#define SV_STAFF_IDENTIFY 14
-#define SV_STAFF_SENSE_HIDDEN 15
-#define SV_STAFF_REVEAL_WAYS 16
-#define SV_STAFF_SENSE_MONSTER 17
-#define SV_STAFF_GENOCIDE 18
-#define SV_STAFF_SUMMON 19
-#define SV_STAFF_WISH 20
-#define SV_STAFF_MANA 21
-#define SV_STAFF_MITHRANDIR 22
-
-/* The "sval" codes for TV_WAND */
-#define SV_WAND_SCHOOL 1
-#define SV_WAND_NOTHING 2
-
-/* needed for monster traps */
-#define SV_WAND_MANATHRUST 3
-#define SV_WAND_FIREFLASH 4
-#define SV_WAND_FIREWALL 5
-#define SV_WAND_TIDAL_WAVE 6
-#define SV_WAND_ICE_STORM 7
-#define SV_WAND_NOXIOUS_CLOUD 8
-#define SV_WAND_POISON_BLOOD 9
-#define SV_WAND_THUNDERSTORM 10
-#define SV_WAND_DIG 11
-#define SV_WAND_STONE_PRISON 12
-#define SV_WAND_STRIKE 13
-#define SV_WAND_TELEPORT_AWAY 14
-#define SV_WAND_SUMMON_ANIMAL 15
-#define SV_WAND_MAGELOCK 16
-#define SV_WAND_SLOW_MONSTER 17
-#define SV_WAND_SPEED 18
-#define SV_WAND_BANISHMENT 19
-#define SV_WAND_DISPERSE_MAGIC 20
-#define SV_WAND_CHARM 21
-#define SV_WAND_CONFUSE 22
-#define SV_WAND_DEMON_BLADE 23
-#define SV_WAND_HEAL_MONSTER 24
-#define SV_WAND_HASTE_MONSTER 25
-#define SV_WAND_THRAIN 26
-
/* The "sval" codes for TV_ROD(Rod Tips) */
#define SV_ROD_NOTHING 0
#define SV_ROD_DETECT_DOOR 1
-#define SV_ROD_IDENTIFY 2
#define SV_ROD_RECALL 3
#define SV_ROD_ILLUMINATION 4
#define SV_ROD_MAPPING 5
@@ -1378,14 +1243,7 @@
/* The "sval" codes for TV_ROD_MAIN(Rods) */
/* Note that the sval is the max mana capacity of the rod */
-#define SV_ROD_WOODEN 10
-#define SV_ROD_COPPER 20
-#define SV_ROD_IRON 50
-#define SV_ROD_ALUMINIUM 75
#define SV_ROD_SILVER 100
-#define SV_ROD_GOLDEN 125
-#define SV_ROD_MITHRIL 160
-#define SV_ROD_ADMANTITE 200
/* The "sval" codes for TV_SCROLL */
@@ -1401,8 +1259,6 @@
#define SV_SCROLL_TELEPORT 9
#define SV_SCROLL_TELEPORT_LEVEL 10
#define SV_SCROLL_WORD_OF_RECALL 11
-#define SV_SCROLL_IDENTIFY 12
-#define SV_SCROLL_STAR_IDENTIFY 13
#define SV_SCROLL_REMOVE_CURSE 14
#define SV_SCROLL_STAR_REMOVE_CURSE 15
#define SV_SCROLL_ENCHANT_ARMOR 16
@@ -1574,11 +1430,6 @@
#define SV_ROD_MIN_DIRECTION 12
/*
- * Special "sval" limit -- first "large" chest
- */
-#define SV_CHEST_MIN_LARGE 4
-
-/*
* Special "sval" limit -- last "good" magic/prayer book
*/
#define SV_BOOK_MAX_GOOD 49
@@ -1597,7 +1448,6 @@
#define CAVE_VIEW 0x0020 /* view flag */
#define CAVE_TEMP 0x0040 /* temp flag */
#define CAVE_WALL 0x0080 /* wall flag */
-#define CAVE_IDNT 0x0200 /* grid identified (fountains) */
#define CAVE_SPEC 0x0400 /* special mark(quests) */
#define CAVE_FREE 0x0800 /* no random generation on it */
#define CAVE_PLIT 0x2000 /* Player lit grid */
@@ -1882,7 +1732,6 @@
#define GF_DOMINATION 89
#define GF_DISP_GOOD 90
#define GF_RAISE 92
-#define GF_STAR_IDENTIFY 93
#define GF_DESTRUCTION 94
#define GF_STUN_CONF 95
#define GF_STUN_DAM 96
@@ -1949,20 +1798,6 @@
/* High resist */
#define EGO_XTRA_POWER 2
-/*** Object flag values ***/
-
-
-/*
- * Special Object Flags
- */
-#define IDENT_SENSE 0x01 /* Item has been "sensed" */
-#define IDENT_EMPTY 0x04 /* Item charges are known */
-#define IDENT_KNOWN 0x08 /* Item abilities are known */
-#define IDENT_STOREB 0x10 /* Item is storebought !!!! */
-#define IDENT_MENTAL 0x20 /* Item information is known */
-#define IDENT_CURSED 0x40 /* Item is temporarily cursed */
-
-
/*
* Special Monster Flags
@@ -2069,14 +1904,6 @@
/*
- * Hack -- The main "screen"
- */
-#define term_screen (angband_term[0])
-
-
-
-
-/*
* Road flags
*/
#define ROAD_NORTH 1
@@ -2088,7 +1915,6 @@
/*
* Buildings actions
*/
-#define BACT_RESEARCH_ITEM 1
#define BACT_TOWN_HISTORY 2
#define BACT_RACE_LEGENDS 3
#define BACT_KING_LEGENDS 5
@@ -2104,7 +1930,6 @@
#define BACT_ENCHANT_WEAPON 23
#define BACT_ENCHANT_ARMOR 24
#define BACT_RECHARGE 25
-#define BACT_IDENTS 26
#define BACT_HEALING 28
#define BACT_RESTORE 29
#define BACT_ENCHANT_ARROWS 30
@@ -2251,19 +2076,6 @@
#define STORE_LIKED 1
#define STORE_NORMAL 2
-/* Pseudo-id defines */
-#define SENSE_NONE 0
-#define SENSE_CURSED 1
-#define SENSE_AVERAGE 2
-#define SENSE_GOOD_LIGHT 3
-#define SENSE_GOOD_HEAVY 4
-#define SENSE_EXCELLENT 5
-#define SENSE_WORTHLESS 6
-#define SENSE_TERRIBLE 7
-#define SENSE_SPECIAL 8
-#define SENSE_BROKEN 9
-#define SENSE_UNCURSED 10
-
/* Wilderness map related */
#define WILDERNESS_SEE_RADIUS 3 /* The amount of wilderness seen around the player */
diff --git a/src/device_allocation_fwd.hpp b/src/device_allocation_fwd.hpp
index 70e53fca..d90a53c7 100644
--- a/src/device_allocation_fwd.hpp
+++ b/src/device_allocation_fwd.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
typedef struct device_allocation device_allocation;
struct device_allocation;
diff --git a/src/dice.cc b/src/dice.cc
index 187bae68..3b5b05a9 100644
--- a/src/dice.cc
+++ b/src/dice.cc
@@ -3,6 +3,7 @@
#include "z-rand.hpp"
#include <cassert>
+#include <cstring>
void dice_init(dice_type *dice, long base, long num, long sides)
{
@@ -13,47 +14,46 @@ void dice_init(dice_type *dice, long base, long num, long sides)
dice->sides = sides;
}
-bool_ dice_parse(dice_type *dice, cptr s)
+static bool dice_parse(dice_type *dice, const char *s)
{
long base, num, sides;
if (sscanf(s, "%ld+%ldd%ld", &base, &num, &sides) == 3)
{
dice_init(dice, base, num, sides);
- return TRUE;
+ return true;
}
if (sscanf(s, "%ld+d%ld", &base, &sides) == 2)
{
dice_init(dice, base, 1, sides);
- return TRUE;
+ return true;
}
if (sscanf(s, "d%ld", &sides) == 1)
{
dice_init(dice, 0, 1, sides);
- return TRUE;
+ return true;
}
if (sscanf(s, "%ldd%ld", &num, &sides) == 2)
{
dice_init(dice, 0, num, sides);
- return TRUE;
+ return true;
}
if (sscanf(s, "%ld", &base) == 1)
{
dice_init(dice, base, 0, 0);
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
-void dice_parse_checked(dice_type *dice, cptr s)
+void dice_parse_checked(dice_type *dice, const char *s)
{
- bool_ result = dice_parse(dice, s);
- if (!result)
+ if (!dice_parse(dice, s))
{
abort();
}
diff --git a/src/dice_fwd.hpp b/src/dice_fwd.hpp
index 72b3b5ca..6dd0775e 100644
--- a/src/dice_fwd.hpp
+++ b/src/dice_fwd.hpp
@@ -1,12 +1,9 @@
#pragma once
-#include "h-basic.h"
-
typedef struct dice_type dice_type;
struct dice_type;
void dice_init(dice_type *dice, long base, long num, long sides);
-bool_ dice_parse(dice_type *dice, cptr s);
-void dice_parse_checked(dice_type *dice, cptr s);
+void dice_parse_checked(dice_type *dice, const char *s);
long dice_roll(dice_type *dice);
void dice_print(dice_type *dice, char *buf);
diff --git a/src/dungeon.cc b/src/dungeon.cc
index f8671387..a4e4a73b 100644
--- a/src/dungeon.cc
+++ b/src/dungeon.cc
@@ -7,7 +7,6 @@
*/
#include "dungeon.hpp"
-#include "dungeon.h"
#include "birth.hpp"
#include "cave.hpp"
@@ -24,7 +23,6 @@
#include "dungeon_info_type.hpp"
#include "feature_flag.hpp"
#include "feature_type.hpp"
-#include "files.h"
#include "files.hpp"
#include "game.hpp"
#include "generate.hpp"
@@ -34,7 +32,6 @@
#include "hooks.hpp"
#include "init2.hpp"
#include "levels.hpp"
-#include "loadsave.h"
#include "loadsave.hpp"
#include "lua_bind.hpp"
#include "melee1.hpp"
@@ -70,8 +67,6 @@
#include "tables.hpp"
#include "timer_type.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "wild.hpp"
#include "wilderness_map.hpp"
@@ -80,6 +75,7 @@
#include "xtra1.hpp"
#include "xtra2.hpp"
#include "z-rand.hpp"
+#include "z-util.hpp"
#include <boost/filesystem.hpp>
#include <cassert>
@@ -89,525 +85,22 @@
#define AUTO_CURSE_CHANCE 15
#define CHAINSWORD_NOISE 100
-/**
- * Type of a "sense" function
- */
-typedef byte (*sense_function_t)(object_type const *o_ptr);
-
-/*
- * Return a "feeling" (or NULL) about an item. Method 1 (Heavy).
- */
-static byte value_check_aux1(object_type const *o_ptr)
-{
- /* Artifacts */
- if (artifact_p(o_ptr))
- {
- /* Cursed/Broken */
- if (cursed_p(o_ptr)) return (SENSE_TERRIBLE);
-
- /* Normal */
- return (SENSE_SPECIAL);
- }
-
- /* Ego-Items */
- if (ego_item_p(o_ptr))
- {
- /* Cursed/Broken */
- if (cursed_p(o_ptr)) return (SENSE_WORTHLESS);
-
- /* Normal */
- return (SENSE_EXCELLENT);
- }
-
- /* Cursed items */
- if (cursed_p(o_ptr)) return (SENSE_CURSED);
-
- /* Good "armor" bonus */
- if (o_ptr->to_a > 0) return (SENSE_GOOD_HEAVY);
-
- /* Good "weapon" bonus */
- if (o_ptr->to_h + o_ptr->to_d > 0) return (SENSE_GOOD_HEAVY);
-
- /* Default to "average" */
- return (SENSE_AVERAGE);
-}
-
-static byte value_check_aux1_magic(object_type const *o_ptr)
-{
- auto const &k_info = game->edit_data.k_info;
-
- auto k_ptr = &k_info[o_ptr->k_idx];
-
-
- switch (o_ptr->tval)
- {
- /* Scrolls, Potions, Wands, Staves and Rods */
- case TV_SCROLL:
- case TV_POTION:
- case TV_POTION2:
- case TV_WAND:
- case TV_STAFF:
- case TV_ROD:
- case TV_ROD_MAIN:
- {
- /* "Cursed" scrolls/potions have a cost of 0 */
- if (k_ptr->cost == 0) return (SENSE_TERRIBLE);
-
- /* Artifacts */
- if (artifact_p(o_ptr)) return (SENSE_SPECIAL);
-
- /* Scroll of Nothing, Apple Juice, etc. */
- if (k_ptr->cost < 3) return (SENSE_WORTHLESS);
-
- /*
- * Identify, Phase Door, Cure Light Wounds, etc. are
- * just average
- */
- if (k_ptr->cost < 100) return (SENSE_AVERAGE);
-
- /* Enchant Armor, *Identify*, Restore Stat, etc. */
- if (k_ptr->cost < 10000) return (SENSE_GOOD_HEAVY);
-
- /* Acquirement, Deincarnation, Strength, Blood of Life, ... */
- if (k_ptr->cost >= 10000) return (SENSE_EXCELLENT);
-
- break;
- }
-
- /* Food */
- case TV_FOOD:
- {
- /* "Cursed" food */
- if (k_ptr->cost == 0) return (SENSE_TERRIBLE);
-
- /* Artifacts */
- if (artifact_p(o_ptr)) return (SENSE_SPECIAL);
-
- /* Normal food (no magical properties) */
- if (k_ptr->cost <= 10) return (SENSE_AVERAGE);
-
- /* Everything else is good */
- if (k_ptr->cost > 10) return (SENSE_GOOD_HEAVY);
-
- break;
- }
- }
-
- /* No feeling */
- return (SENSE_NONE);
-}
-
-
-/*
- * Return a "feeling" (or NULL) about an item. Method 2 (Light).
- */
-static byte value_check_aux2(object_type const *o_ptr)
-{
- /* Cursed items (all of them) */
- if (cursed_p(o_ptr)) return (SENSE_CURSED);
-
- /* Artifacts -- except cursed/broken ones */
- if (artifact_p(o_ptr)) return (SENSE_GOOD_LIGHT);
-
- /* Ego-Items -- except cursed/broken ones */
- if (ego_item_p(o_ptr)) return (SENSE_GOOD_LIGHT);
-
- /* Good armor bonus */
- if (o_ptr->to_a > 0) return (SENSE_GOOD_LIGHT);
-
- /* Good weapon bonuses */
- if (o_ptr->to_h + o_ptr->to_d > 0) return (SENSE_GOOD_LIGHT);
-
- /* Default to "average" */
- return (SENSE_AVERAGE);
-}
-
-
-static byte value_check_aux2_magic(object_type const *o_ptr)
-{
- auto const &k_info = game->edit_data.k_info;
-
- auto k_ptr = &k_info[o_ptr->k_idx];
-
-
- switch (o_ptr->tval)
- {
- /* Scrolls, Potions, Wands, Staves and Rods */
- case TV_SCROLL:
- case TV_POTION:
- case TV_POTION2:
- case TV_WAND:
- case TV_STAFF:
- case TV_ROD:
- case TV_ROD_MAIN:
- {
- /* "Cursed" scrolls/potions have a cost of 0 */
- if (k_ptr->cost == 0) return (SENSE_CURSED);
-
- /* Artifacts */
- if (artifact_p(o_ptr)) return (SENSE_GOOD_LIGHT);
-
- /* Scroll of Nothing, Apple Juice, etc. */
- if (k_ptr->cost < 3) return (SENSE_AVERAGE);
-
- /*
- * Identify, Phase Door, Cure Light Wounds, etc. are
- * just average
- */
- if (k_ptr->cost < 100) return (SENSE_AVERAGE);
-
- /* Enchant Armor, *Identify*, Restore Stat, etc. */
- if (k_ptr->cost < 10000) return (SENSE_GOOD_LIGHT);
-
- /* Acquirement, Deincarnation, Strength, Blood of Life, ... */
- if (k_ptr->cost >= 10000) return (SENSE_GOOD_LIGHT);
-
- break;
- }
-
- /* Food */
- case TV_FOOD:
- {
- /* "Cursed" food */
- if (k_ptr->cost == 0) return (SENSE_CURSED);
-
- /* Artifacts */
- if (artifact_p(o_ptr)) return (SENSE_GOOD_LIGHT);
-
- /* Normal food (no magical properties) */
- if (k_ptr->cost <= 10) return (SENSE_AVERAGE);
-
- /* Everything else is good */
- if (k_ptr->cost > 10) return (SENSE_GOOD_LIGHT);
-
- break;
- }
- }
-
- /* No feeling */
- return (SENSE_NONE);
-}
-
-
/*
* Can a player be resurrected?
*/
-static bool_ granted_resurrection()
+static bool granted_resurrection()
{
if (praying_to(GOD_ERU))
{
if (p_ptr->grace > 100000)
{
- if (magik(70)) return (TRUE);
- else return (FALSE);
+ return magik(70);
}
}
- return (FALSE);
-}
-
-static sense_function_t select_sense(object_type *o_ptr, sense_function_t combat, sense_function_t magic)
-{
- switch (o_ptr->tval)
- {
- case TV_SHOT:
- case TV_ARROW:
- case TV_BOLT:
- case TV_BOW:
- case TV_DIGGING:
- case TV_HAFTED:
- case TV_POLEARM:
- case TV_SWORD:
- case TV_MSTAFF:
- case TV_AXE:
- case TV_BOOTS:
- case TV_GLOVES:
- case TV_HELM:
- case TV_CROWN:
- case TV_SHIELD:
- case TV_CLOAK:
- case TV_SOFT_ARMOR:
- case TV_HARD_ARMOR:
- case TV_DRAG_ARMOR:
- case TV_BOOMERANG:
- {
- return combat;
- }
-
- case TV_POTION:
- case TV_POTION2:
- case TV_SCROLL:
- case TV_WAND:
- case TV_STAFF:
- case TV_ROD:
- case TV_ROD_MAIN:
- {
- return magic;
- }
-
- /* Dual use? */
- case TV_DAEMON_BOOK:
- {
- return combat;
- }
- }
-
- return nullptr;
+ return false;
}
/*
- * Sense quality of specific list of objects.
- *
- * Combat items (weapons and armour) - Fast, weak if combat skill < 10, strong
- * otherwise.
- *
- * Magic items (scrolls, staffs, wands, potions etc) - Slow, weak if
- * magic skill < 10, strong otherwise.
- *
- * It shouldn't matter a lot to discriminate against magic users, because
- * they learn one form of ID or another, and because most magic items are
- * easy_know.
- */
-void sense_objects(std::vector<int> const &object_idxs)
-{
- /* No sensing when confused */
- if (p_ptr->confused) return;
-
- /*
- * In Angband, the chance of pseudo-id uses two different formulae:
- *
- * (1) Fast. 0 == rand_int(BASE / (plev * plev + 40)
- * (2) Slow. 0 == rand_int(BASE / (plev + 5)
- *
- * Warriors: Fase with BASE == 9000
- * Magi: Slow with BASE == 240000
- * Priests: Fast with BASE == 10000
- * Rogues: Fase with BASE == 20000
- * Rangers: Slow with BASE == 120000
- * Paladins: Fast with BASE == 80000
- *
- * In other words, those who have identify spells are penalised.
- * The problems with Pern/Tome since it externalised player classes
- * is that it uses the same and slow formula for spellcasters and
- * fighters.
- *
- * In the following code, combat item pseudo-ID improves exponentially,
- * (fast with BASE 9000) and magic one linear (slow with base 60000 --
- * twice faster than V rangers).
- *
- * I hope this makes it closer to the original model -- pelpel
- */
-
- /* The combat skill affects weapon/armour pseudo-ID */
- int combat_lev = get_skill(SKILL_COMBAT);
-
- /* The magic skill affects magic item pseudo-ID */
- int magic_lev = get_skill(SKILL_MAGIC);
-
- /* Higher skill levels give the player better sense of items */
- auto feel_combat = (combat_lev > 10) ? value_check_aux1 : value_check_aux2;
- auto feel_magic = (magic_lev > 10) ? value_check_aux1_magic : value_check_aux2_magic;
-
- /*** Sense everything ***/
-
- /* Check everything */
- for (auto i : object_idxs)
- {
- object_type *o_ptr = get_object(i);
-
- /* Skip empty slots */
- if (!o_ptr->k_idx) continue;
-
- /* We know about it already, do not tell us again */
- if (o_ptr->ident & (IDENT_SENSE)) continue;
-
- /* It is fully known, no information needed */
- if (object_known_p(o_ptr)) continue;
-
- /* Select appropriate sensing function, if any */
- sense_function_t sense = select_sense(o_ptr, feel_combat, feel_magic);
-
- /* Skip non-sensed items */
- if (!sense)
- {
- continue;
- }
-
- /* Check for a feeling */
- byte feel = sense(o_ptr);
-
- /* Skip non-feelings */
- if (feel == SENSE_NONE)
- {
- continue;
- }
-
- /* Get an object description */
- char o_name[80];
- object_desc(o_name, o_ptr, FALSE, 0);
-
- /* Messages */
- if (i < 0) {
- // We get a message from the floor handling code, so
- // it would be overkill to have a message here too.
- }
- else if (i >= INVEN_WIELD)
- {
- msg_format("You feel the %s (%c) you are %s %s %s...",
- o_name, index_to_label(i), describe_use(i),
- ((o_ptr->number == 1) ? "is" : "are"), sense_desc[feel]);
- }
- else
- {
- msg_format("You feel the %s (%c) in your pack %s %s...",
- o_name, index_to_label(i),
- ((o_ptr->number == 1) ? "is" : "are"), sense_desc[feel]);
- }
-
- /* We have "felt" it */
- o_ptr->ident |= (IDENT_SENSE);
-
- /* Set sense property */
- o_ptr->sense = feel;
-
- /* Combine / Reorder the pack (later) */
- p_ptr->notice |= (PN_COMBINE | PN_REORDER);
-
- /* Window stuff */
- p_ptr->window |= (PW_INVEN | PW_EQUIP);
- }
-
- /* Squelch ! */
- squeltch_inventory();
-}
-
-void sense_inventory()
-{
- static std::vector<int> idxs;
- // Initialize static vector if necessary
- if (idxs.empty())
- {
- idxs.reserve(INVEN_TOTAL);
- for (int i = 0; i < INVEN_TOTAL; i++)
- {
- idxs.push_back(i);
- }
- }
- sense_objects(idxs);
-}
-
-/*
- * Go to any level (ripped off from wiz_jump)
- */
-static void pattern_teleport()
-{
- /* Ask for level */
- if (get_check("Teleport level? "))
- {
- char ppp[80];
-
- char tmp_val[160];
-
- /* Prompt */
- sprintf(ppp, "Teleport to level (0-%d): ", 99);
-
- /* Default */
- sprintf(tmp_val, "%d", dun_level);
-
- /* Ask for a level */
- if (!get_string(ppp, tmp_val, 10)) return;
-
- /* Extract request */
- command_arg = atoi(tmp_val);
- }
- else if (get_check("Normal teleport? "))
- {
- teleport_player(200);
- return;
- }
- else
- {
- return;
- }
-
- /* Paranoia */
- if (command_arg < 0) command_arg = 0;
-
- /* Paranoia */
- if (command_arg > 99) command_arg = 99;
-
- /* Accept request */
- msg_format("You teleport to dungeon level %d.", command_arg);
-
- autosave_checkpoint();
-
- /* Change level */
- dun_level = command_arg;
-
- /* Leaving */
- p_ptr->leaving = TRUE;
-}
-
-
-/*
- * Returns TRUE if we are on the Straight Road...
- */
-static bool_ pattern_effect()
-{
- if ((cave[p_ptr->py][p_ptr->px].feat < FEAT_PATTERN_START) ||
- (cave[p_ptr->py][p_ptr->px].feat > FEAT_PATTERN_XTRA2)) return (FALSE);
-
- if (cave[p_ptr->py][p_ptr->px].feat == FEAT_PATTERN_END)
- {
- set_poisoned(0);
- set_image(0);
- set_stun(0);
- set_cut(0);
- set_blind(0);
- set_afraid(0);
- do_res_stat(A_STR, TRUE);
- do_res_stat(A_INT, TRUE);
- do_res_stat(A_WIS, TRUE);
- do_res_stat(A_DEX, TRUE);
- do_res_stat(A_CON, TRUE);
- do_res_stat(A_CHR, TRUE);
- restore_level();
- hp_player(1000);
- cave_set_feat(p_ptr->py, p_ptr->px, FEAT_PATTERN_OLD);
- msg_print("This section of the Straight Road looks less powerful.");
- }
-
-
- /*
- * We could make the healing effect of the
- * Pattern center one-time only to avoid various kinds
- * of abuse, like luring the win monster into fighting you
- * in the middle of the pattern...
- */
- else if (cave[p_ptr->py][p_ptr->px].feat == FEAT_PATTERN_OLD)
- {
- /* No effect */
- }
- else if (cave[p_ptr->py][p_ptr->px].feat == FEAT_PATTERN_XTRA1)
- {
- pattern_teleport();
- }
- else if (cave[p_ptr->py][p_ptr->px].feat == FEAT_PATTERN_XTRA2)
- {
- if (!(p_ptr->invuln))
- take_hit(200, "walking the corrupted Straight Road");
- }
-
- else
- {
- if (!(p_ptr->invuln))
- take_hit(damroll(1, 3), "walking the Straight Road");
- }
-
- return (TRUE);
-}
-
-
-/*
* If player has inscribed the object with "!!", let him know when it's
* recharged. -LM-
*/
@@ -630,7 +123,7 @@ static void recharged_notice(object_type *o_ptr)
{
/* Describe (briefly) */
char o_name[80];
- object_desc(o_name, o_ptr, FALSE, 0);
+ object_desc(o_name, o_ptr, false, 0);
/* Notify the player */
if (o_ptr->number > 1)
@@ -780,12 +273,9 @@ static void regen_monsters()
{
auto const &r_info = game->edit_data.r_info;
- int i, frac;
+ auto o_ptr = &p_ptr->inventory[INVEN_CARRY];
- object_type *o_ptr = &p_ptr->inventory[INVEN_CARRY];
-
-
- if (o_ptr->k_idx)
+ if (o_ptr->k_ptr)
{
auto r_ptr = &r_info[o_ptr->pval];
@@ -793,7 +283,7 @@ static void regen_monsters()
if (o_ptr->pval2 < o_ptr->pval3)
{
/* Hack -- Base regeneration */
- frac = o_ptr->pval3 / 100;
+ int frac = o_ptr->pval3 / 100;
/* Hack -- Minimal regeneration rate */
if (!frac) frac = 1;
@@ -814,7 +304,7 @@ static void regen_monsters()
}
/* Regenerate everyone */
- for (i = 1; i < m_max; i++)
+ for (int i = 1; i < m_max; i++)
{
/* Check the i'th monster */
monster_type *m_ptr = &m_list[i];
@@ -829,7 +319,7 @@ static void regen_monsters()
if (m_ptr->hp < m_ptr->maxhp)
{
/* Hack -- Base regeneration */
- frac = m_ptr->maxhp / 100;
+ int frac = m_ptr->maxhp / 100;
/* Hack -- Minimal regeneration rate */
if (!frac) frac = 1;
@@ -946,7 +436,7 @@ static void apply_effect(int y, int x)
/* XXX XXX XXX */
-static bool_ is_recall = FALSE;
+static bool is_recall = false;
/*
@@ -986,7 +476,7 @@ static void process_world_corruptions()
increase_mana(-amt);
if (p_ptr->csp == 0)
{
- p_ptr->corrupt_anti_teleport_stopped = FALSE;
+ p_ptr->corrupt_anti_teleport_stopped = false;
msg_print("You stop controlling your corruption.");
p_ptr->update = p_ptr->update | PU_BONUS;
}
@@ -995,10 +485,7 @@ static void process_world_corruptions()
}
-/*
- * Shim for accessing Lua variable.
- */
-static bool_ grace_delay_trigger()
+static bool grace_delay_trigger()
{
p_ptr->grace_delay++;
@@ -1007,12 +494,12 @@ static bool_ grace_delay_trigger()
/* reset */
p_ptr->grace_delay = 0;
/* triggered */
- return TRUE;
+ return true;
}
else
{
/* not triggered */
- return FALSE;
+ return false;
}
}
@@ -1214,6 +701,292 @@ static void process_world_gods()
}
+/**
+ * Is the light source safe for creatures sensitive to light?
+ */
+static bool is_light_safe(object_type const *o_ptr)
+{
+ // Get the flags of the object; we don't bother with sets since we're only
+ // interested in "innate" flags on the light source itself.
+ object_flags_no_set = true;
+ auto flags = object_flags(o_ptr);
+ object_flags_no_set = false;
+
+ // We only allow really badly cursed items. This is to provide
+ // an "out" in case of severely bad luck, but these lights cannot
+ // be used for any non-trivial length of time.
+ return (flags | TR_TY_CURSE) && (flags | TR_DG_CURSE);
+}
+
+
+/**
+ * Process lasting effects
+ */
+static void process_lasting_effects()
+{
+ auto &lasting_effects = game->lasting_effects;
+
+ for (int j = 0; j < cur_hgt - 1; j++)
+ {
+ for (int i = 0; i < cur_wid - 1; i++)
+ {
+ if (auto ei = cave[j][i].maybe_effect)
+ {
+ effect_type *e_ptr = &lasting_effects[*ei];
+
+ if (e_ptr->time)
+ {
+ /* Apply damage */
+ project(0, 0, j, i, e_ptr->dam, e_ptr->type,
+ PROJECT_KILL | PROJECT_ITEM | PROJECT_HIDE);
+ }
+ else
+ {
+ cave[j][i].maybe_effect = boost::none;
+ }
+
+ if ((e_ptr->flags & EFF_WAVE) && !(e_ptr->flags & EFF_LAST))
+ {
+ if (distance(e_ptr->cy, e_ptr->cx, j, i) < e_ptr->rad - 1)
+ {
+ cave[j][i].maybe_effect = boost::none;
+ }
+ }
+ else if ((e_ptr->flags & EFF_STORM) && !(e_ptr->flags & EFF_LAST))
+ {
+ cave[j][i].maybe_effect = boost::none;
+ }
+
+ lite_spot(j, i);
+ }
+ }
+ }
+
+ // Filter out any expired effects
+ lasting_effects.erase(
+ std::remove_if(
+ std::begin(lasting_effects),
+ std::end(lasting_effects),
+ [](auto effect) { return effect.time == 0; }),
+ std::end(lasting_effects));
+
+ // Reduce & handle effects
+ for (std::size_t i = 0; i < lasting_effects.size(); i++)
+ {
+ effect_type &e = lasting_effects[i];
+
+ // Reduce duration
+ e.time--;
+
+ // Set up the effect in the dungeon.
+ if (e.flags & EFF_WAVE)
+ {
+ // Expand the wave front
+ e.rad++;
+
+ // Check direction
+ if (e.flags & EFF_DIR8)
+ {
+ for (int y = e.cy - e.rad, z = 0; y <= e.cy; y++, z++)
+ {
+ for (int x = e.cx - (e.rad - z); x <= e.cx + (e.rad - z); x++)
+ {
+ if (!in_bounds(y, x))
+ {
+ continue;
+ }
+
+ if (los(e.cy, e.cx, y, x) &&
+ (distance(e.cy, e.cx, y, x) == e.rad))
+ {
+ cave[y][x].maybe_effect = i;
+ }
+ }
+ }
+ }
+ else if (e.flags & EFF_DIR2)
+ {
+ for (int y = e.cy, z = e.rad; y <= e.cy + e.rad; y++, z--)
+ {
+ for (int x = e.cx - (e.rad - z); x <= e.cx + (e.rad - z); x++)
+ {
+ if (!in_bounds(y, x))
+ {
+ continue;
+ }
+
+ if (los(e.cy, e.cx, y, x) &&
+ (distance(e.cy, e.cx, y, x) == e.rad))
+ {
+ cave[y][x].maybe_effect = i;
+ }
+ }
+ }
+ }
+ else if (e.flags & EFF_DIR6)
+ {
+ for (int x = e.cx, z = e.rad; x <= e.cx + e.rad; x++, z--)
+ {
+ for (int y = e.cy - (e.rad - z); y <= e.cy + (e.rad - z); y++)
+ {
+ if (!in_bounds(y, x))
+ {
+ continue;
+ }
+
+ if (los(e.cy, e.cx, y, x) &&
+ (distance(e.cy, e.cx, y, x) == e.rad))
+ {
+ cave[y][x].maybe_effect = i;
+ }
+ }
+ }
+ }
+ else if (e.flags & EFF_DIR4)
+ {
+ for (int x = e.cx - e.rad, z = 0; x <= e.cx; x++, z++)
+ {
+ for (int y = e.cy - (e.rad - z); y <= e.cy + (e.rad - z); y++)
+ {
+ if (!in_bounds(y, x))
+ {
+ continue;
+ }
+
+ if (los(e.cy, e.cx, y, x) &&
+ (distance(e.cy, e.cx, y, x) == e.rad))
+ {
+ cave[y][x].maybe_effect = i;
+ }
+ }
+ }
+ }
+ else if (e.flags & EFF_DIR9)
+ {
+ for (int y = e.cy - e.rad; y <= e.cy; y++)
+ {
+ for (int x = e.cx; x <= e.cx + e.rad; x++)
+ {
+ if (!in_bounds(y, x))
+ {
+ continue;
+ }
+
+ if (los(e.cy, e.cx, y, x) &&
+ (distance(e.cy, e.cx, y, x) == e.rad))
+ {
+ cave[y][x].maybe_effect = i;
+ }
+ }
+ }
+ }
+ else if (e.flags & EFF_DIR1)
+ {
+ for (int y = e.cy; y <= e.cy + e.rad; y++)
+ {
+ for (int x = e.cx - e.rad; x <= e.cx; x++)
+ {
+ if (!in_bounds(y, x))
+ {
+ continue;
+ }
+
+ if (los(e.cy, e.cx, y, x) &&
+ (distance(e.cy, e.cx, y, x) == e.rad))
+ {
+ cave[y][x].maybe_effect = i;
+ }
+ }
+ }
+ }
+ else if (e.flags & EFF_DIR7)
+ {
+ for (int y = e.cy - e.rad; y <= e.cy; y++)
+ {
+ for (int x = e.cx - e.rad; x <= e.cx; x++)
+ {
+ if (!in_bounds(y, x))
+ {
+ continue;
+ }
+
+ if (los(e.cy, e.cx, y, x) &&
+ (distance(e.cy, e.cx, y, x) == e.rad))
+ {
+ cave[y][x].maybe_effect = i;
+ }
+ }
+ }
+ }
+ else if (e.flags & EFF_DIR3)
+ {
+ for (int y = e.cy; y <= e.cy + e.rad; y++)
+ {
+ for (int x = e.cx; x <= e.cx + e.rad; x++)
+ {
+ if (!in_bounds(y, x))
+ {
+ continue;
+ }
+
+ if (los(e.cy, e.cx, y, x) &&
+ (distance(e.cy, e.cx, y, x) == e.rad))
+ {
+ cave[y][x].maybe_effect = i;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (int y = e.cy - e.rad; y <= e.cy + e.rad; y++)
+ {
+ for (int x = e.cx - e.rad; x <= e.cx + e.rad; x++)
+ {
+ if (!in_bounds(y, x))
+ {
+ continue;
+ }
+
+ if (los(e.cy, e.cx, y, x) &&
+ (distance(e.cy, e.cx, y, x) == e.rad))
+ {
+ cave[y][x].maybe_effect = i;
+ }
+ }
+ }
+ }
+ }
+ else if (e.flags & EFF_STORM)
+ {
+ // Center on player
+ e.cy = p_ptr->py;
+ e.cx = p_ptr->px;
+ // Set up the effect
+ for (int y = e.cy - e.rad; y <= e.cy + e.rad; y++)
+ {
+ for (int x = e.cx - e.rad; x <= e.cx + e.rad; x++)
+ {
+ if (!in_bounds(y, x))
+ {
+ continue;
+ }
+
+ if (los(e.cy, e.cx, y, x) &&
+ (distance(e.cy, e.cx, y, x) <= e.rad))
+ {
+ cave[y][x].maybe_effect = i;
+ lite_spot(y, x);
+ }
+ }
+ }
+ }
+ }
+
+ apply_effect(p_ptr->py, p_ptr->px);
+}
+
+
/*
* Handle certain things once every 10 game turns
*
@@ -1226,11 +999,12 @@ static void process_world()
auto const &r_info = game->edit_data.r_info;
auto const &f_info = game->edit_data.f_info;
auto &timers = game->timers;
+ auto const &dungeon_flags = game->dungeon_flags;
- int x, y, i, j;
+ int x, y;
int regen_amount;
- bool_ cave_no_regen = FALSE;
+ bool cave_no_regen = false;
int upkeep_factor = 0;
auto d_ptr = &d_info[dungeon_type];
@@ -1289,7 +1063,7 @@ static void process_world()
/*** Is the wielded monsters still hypnotised ***/
o_ptr = &p_ptr->inventory[INVEN_CARRY];
- if (o_ptr->k_idx)
+ if (o_ptr->k_ptr)
{
auto r_ptr = &r_info[o_ptr->pval];
@@ -1306,10 +1080,10 @@ static void process_world()
{
if ((turn % (static_cast<s32b>(options->autosave_freq) * 10)) == 0)
{
- is_autosave = TRUE;
+ is_autosave = true;
msg_print("Autosaving the game...");
do_cmd_save_game();
- is_autosave = FALSE;
+ is_autosave = false;
}
}
@@ -1322,13 +1096,8 @@ static void process_world()
/* Hack -- Daybreak/Nighfall in town */
if ((turn % ((10L * DAY) / 2)) == 0)
{
- bool_ dawn;
-
- /* Check for dawn */
- dawn = ((turn % (10L * DAY)) == 0);
-
/* Day breaks */
- if (dawn)
+ if (((turn % (10L * DAY)) == 0))
{
/* Message */
msg_print("The sun has risen.");
@@ -1404,7 +1173,7 @@ static void process_world()
/* Make a new monster */
if (!(dungeon_flags & DF_NO_NEW_MONSTER))
{
- alloc_monster(MAX_SIGHT + 5, FALSE);
+ alloc_monster(MAX_SIGHT + 5, false);
}
}
@@ -1432,29 +1201,26 @@ static void process_world()
/* Take damage */
msg_print("The sun's rays scorch your undead flesh!");
take_hit(1, "sunlight");
- cave_no_regen = TRUE;
+ cave_no_regen = true;
drop_from_wild();
}
}
- if ((p_ptr->inventory[INVEN_LITE].tval != 0) &&
- (p_ptr->inventory[INVEN_LITE].sval >= SV_LITE_GALADRIEL) &&
- (p_ptr->inventory[INVEN_LITE].sval <= SV_STONE_LORE) &&
- (p_ptr->inventory[INVEN_LITE].sval != SV_LITE_UNDEATH))
+ if (!is_light_safe(&p_ptr->inventory[INVEN_LITE]))
{
object_type * o_ptr = &p_ptr->inventory[INVEN_LITE];
char o_name [80];
char ouch [80];
/* Get an object description */
- object_desc(o_name, o_ptr, FALSE, 0);
+ object_desc(o_name, o_ptr, false, 0);
msg_format("The %s scorches your undead flesh!", o_name);
- cave_no_regen = TRUE;
+ cave_no_regen = true;
/* Get an object description */
- object_desc(o_name, o_ptr, TRUE, 0);
+ object_desc(o_name, o_ptr, true, 0);
sprintf(ouch, "wielding %s", o_name);
take_hit(1, ouch);
@@ -1472,7 +1238,7 @@ static void process_world()
/* Take damage */
msg_print("You are drowning!");
take_hit(randint(p_ptr->lev), "drowning");
- cave_no_regen = TRUE;
+ cave_no_regen = true;
}
}
@@ -1503,7 +1269,7 @@ static void process_world()
{
int amt = 1 + ((p_ptr->lev) / 5);
- cave_no_regen = TRUE;
+ cave_no_regen = true;
if (amt > p_ptr->chp - 1) amt = p_ptr->chp - 1;
take_hit(amt, " walls ...");
}
@@ -1513,6 +1279,8 @@ static void process_world()
/* Take damage from cuts */
if ((p_ptr->cut) && !(p_ptr->invuln))
{
+ int i;
+
/* Mortal wound or Deep Gash */
if (p_ptr->cut > 200)
{
@@ -1559,7 +1327,7 @@ static void process_world()
}
/* Basic digestion rate based on speed */
- i = extract_energy[speed_use] * 2;
+ int i = extract_energy[speed_use] * 2;
/* Regeneration takes more food */
if (p_ptr->regenerate) i += 30;
@@ -1583,7 +1351,10 @@ static void process_world()
auto const flags = object_flags(o_ptr);
/* Hitpoints multiplier consume a lot of food */
- if (o_ptr->k_idx && (flags & TR_LIFE)) i += o_ptr->pval * 5;
+ if (o_ptr->k_ptr && (flags & TR_LIFE))
+ {
+ i += o_ptr->pval * 5;
+ }
/* Slow digestion takes less food */
if (p_ptr->slow_digest) i -= 10;
@@ -1607,7 +1378,7 @@ static void process_world()
if (p_ptr->food < PY_FOOD_STARVE)
{
/* Calculate damage */
- i = (PY_FOOD_STARVE - p_ptr->food) / 10;
+ int i = (PY_FOOD_STARVE - p_ptr->food) / 10;
/* Take damage */
if (!(p_ptr->invuln)) take_hit(i, "starvation");
@@ -1649,18 +1420,10 @@ static void process_world()
}
}
- /* Are we walking the pattern? */
- if (!p_ptr->wild_mode && pattern_effect())
+ /* Regeneration ability */
+ if (p_ptr->regenerate)
{
- cave_no_regen = TRUE;
- }
- else
- {
- /* Regeneration ability */
- if (p_ptr->regenerate)
- {
- regen_amount = regen_amount * 2;
- }
+ regen_amount = regen_amount * 2;
}
@@ -1777,7 +1540,7 @@ static void process_world()
inc_piety(GOD_YAVANNA, -dec);
}
}
- p_ptr->did_nothing = FALSE;
+ p_ptr->did_nothing = false;
/* Increase regen by tim regen */
if (p_ptr->tim_regen) regen_amount += p_ptr->tim_regen_pow;
@@ -1801,30 +1564,21 @@ static void process_world()
/* Regenerate Hit Points if needed */
if ((p_ptr->chp < p_ptr->mhp) && !cave_no_regen)
{
- if ((cave[p_ptr->py][p_ptr->px].feat < FEAT_PATTERN_END) &&
- (cave[p_ptr->py][p_ptr->px].feat >= FEAT_PATTERN_START))
- {
- /* Hmmm. this should never happen? */
- regenhp(regen_amount / 5);
- }
- else
- {
- regenhp(regen_amount);
- }
+ regenhp(regen_amount);
}
/*** Timeout Various Things ***/
/* Handle temporary stat drains */
- for (i = 0; i < 6; i++)
+ for (int i = 0; i < 6; i++)
{
if (p_ptr->stat_cnt[i] > 0)
{
p_ptr->stat_cnt[i]--;
if (p_ptr->stat_cnt[i] == 0)
{
- do_res_stat(i, FALSE);
+ do_res_stat(i, false);
}
}
}
@@ -1865,7 +1619,7 @@ static void process_world()
/* Dead player */
if (p_ptr->chp < 0)
{
- bool_ old_quick = options->quick_messages;
+ bool old_quick = options->quick_messages;
/* Hack -- Note death */
if (!options->last_words)
@@ -1889,15 +1643,15 @@ static void process_world()
}
/* No longer a winner */
- total_winner = FALSE;
+ total_winner = false;
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
/* Note death */
- death = TRUE;
+ death = true;
- options->quick_messages = FALSE;
+ options->quick_messages = false;
if (get_check("Make a last screenshot? "))
{
do_cmd_html_dump();
@@ -1944,11 +1698,11 @@ static void process_world()
/* Timed breath */
if (p_ptr->tim_water_breath)
{
- set_tim_breath(p_ptr->tim_water_breath - 1, FALSE);
+ set_tim_breath(p_ptr->tim_water_breath - 1, false);
}
if (p_ptr->tim_magic_breath)
{
- set_tim_breath(p_ptr->tim_magic_breath - 1, TRUE);
+ set_tim_breath(p_ptr->tim_magic_breath - 1, true);
}
/* Timed precognition */
@@ -2324,208 +2078,7 @@ static void process_world()
/* handle spell effects */
if (!p_ptr->wild_mode)
{
- /*
- * I noticed significant performance degrade after the introduction
- * of staying spell effects. I believe serious optimisation effort
- * is required before another release.
- *
- * More important is to fix that display weirdness...
- *
- * It seems that the game never expects that monster deaths and
- * terrain feature changes should happen here... Moving these
- * to process_player() [before resting code, with "every 10 game turn"
- * 'if'] may or may not fix the problem... -- pelpel to DG
- */
- for (j = 0; j < cur_hgt - 1; j++)
- {
- for (i = 0; i < cur_wid - 1; i++)
- {
- int e = cave[j][i].effect;
-
- if (e)
- {
- effect_type *e_ptr = &effects[e];
-
- if (e_ptr->time)
- {
- /* Apply damage */
- project(0, 0, j, i, e_ptr->dam, e_ptr->type,
- PROJECT_KILL | PROJECT_ITEM | PROJECT_HIDE);
- }
- else
- {
- cave[j][i].effect = 0;
- }
-
- if ((e_ptr->flags & EFF_WAVE) && !(e_ptr->flags & EFF_LAST))
- {
- if (distance(e_ptr->cy, e_ptr->cx, j, i) < e_ptr->rad - 1)
- cave[j][i].effect = 0;
- }
- else if ((e_ptr->flags & EFF_STORM) && !(e_ptr->flags & EFF_LAST))
- {
- cave[j][i].effect = 0;
- }
-
- lite_spot(j, i);
- }
- }
- }
-
- /* Reduce & handle effects */
- for (i = 0; i < MAX_EFFECTS; i++)
- {
- /* Skip empty slots */
- if (effects[i].time == 0) continue;
-
- /* Reduce duration */
- effects[i].time--;
-
- /* Creates a "wave" effect*/
- if (effects[i].flags & EFF_WAVE)
- {
- effect_type *e_ptr = &effects[i];
- int x, y, z;
-
- e_ptr->rad++;
-
- /* What a frelling ugly line of ifs ... */
- if (effects[i].flags & EFF_DIR8)
- for (y = e_ptr->cy - e_ptr->rad, z = 0; y <= e_ptr->cy; y++, z++)
- {
- for (x = e_ptr->cx - (e_ptr->rad - z); x <= e_ptr->cx + (e_ptr->rad - z); x++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- else if (effects[i].flags & EFF_DIR2)
- for (y = e_ptr->cy, z = e_ptr->rad; y <= e_ptr->cy + e_ptr->rad; y++, z--)
- {
- for (x = e_ptr->cx - (e_ptr->rad - z); x <= e_ptr->cx + (e_ptr->rad - z); x++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- else if (effects[i].flags & EFF_DIR6)
- for (x = e_ptr->cx, z = e_ptr->rad; x <= e_ptr->cx + e_ptr->rad; x++, z--)
- {
- for (y = e_ptr->cy - (e_ptr->rad - z); y <= e_ptr->cy + (e_ptr->rad - z); y++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- else if (effects[i].flags & EFF_DIR4)
- for (x = e_ptr->cx - e_ptr->rad, z = 0; x <= e_ptr->cx; x++, z++)
- {
- for (y = e_ptr->cy - (e_ptr->rad - z); y <= e_ptr->cy + (e_ptr->rad - z); y++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- else if (effects[i].flags & EFF_DIR9)
- for (y = e_ptr->cy - e_ptr->rad; y <= e_ptr->cy; y++)
- {
- for (x = e_ptr->cx; x <= e_ptr->cx + e_ptr->rad; x++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- else if (effects[i].flags & EFF_DIR1)
- for (y = e_ptr->cy; y <= e_ptr->cy + e_ptr->rad; y++)
- {
- for (x = e_ptr->cx - e_ptr->rad; x <= e_ptr->cx; x++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- else if (effects[i].flags & EFF_DIR7)
- for (y = e_ptr->cy - e_ptr->rad; y <= e_ptr->cy; y++)
- {
- for (x = e_ptr->cx - e_ptr->rad; x <= e_ptr->cx; x++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- else if (effects[i].flags & EFF_DIR3)
- for (y = e_ptr->cy; y <= e_ptr->cy + e_ptr->rad; y++)
- {
- for (x = e_ptr->cx; x <= e_ptr->cx + e_ptr->rad; x++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- else
- for (y = e_ptr->cy - e_ptr->rad; y <= e_ptr->cy + e_ptr->rad; y++)
- {
- for (x = e_ptr->cx - e_ptr->rad; x <= e_ptr->cx + e_ptr->rad; x++)
- {
- if (!in_bounds(y, x)) continue;
-
- /* This is *slow* -- pelpel */
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- }
- /* Creates a "storm" effect*/
- else if (effects[i].flags & EFF_STORM)
- {
- effect_type *e_ptr = &effects[i];
- int x, y;
-
- e_ptr->cy = p_ptr->py;
- e_ptr->cx = p_ptr->px;
- for (y = e_ptr->cy - e_ptr->rad; y <= e_ptr->cy + e_ptr->rad; y++)
- {
- for (x = e_ptr->cx - e_ptr->rad; x <= e_ptr->cx + e_ptr->rad; x++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) <= e_ptr->rad))
- {
- cave[y][x].effect = i;
- lite_spot(y, x);
- }
- }
- }
- }
- }
-
- apply_effect(p_ptr->py, p_ptr->px);
+ process_lasting_effects();
}
/* Arg cannot breath? */
@@ -2548,25 +2101,31 @@ static void process_world()
*/
if (((turn % 3000) == 0) && p_ptr->black_breath)
{
- bool_ be_silent = FALSE;
+ bool be_silent = false;
/* check all equipment for the Black Breath flag. */
- for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
+ for (int i = INVEN_WIELD; i < INVEN_TOTAL; i++)
{
o_ptr = &p_ptr->inventory[i];
/* Skip non-objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Extract the item flags */
auto const flags = object_flags(o_ptr);
/* No messages if object has the flag, to avoid annoyance. */
- if (flags & TR_BLACK_BREATH) be_silent = TRUE;
+ if (flags & TR_BLACK_BREATH)
+ {
+ be_silent = true;
+ }
}
- /* If we are allowed to speak, warn and disturb. */
+ /* If we are allowed to speak, warn and disturb. */
if (!be_silent)
{
cmsg_print(TERM_L_DARK, "The Black Breath saps your soul!");
@@ -2731,7 +2290,8 @@ static void process_world()
}
/* Process equipment */
- for (j = 0, i = INVEN_WIELD; i < INVEN_TOTAL; i++)
+ bool changed = false;
+ for (int i = INVEN_WIELD; i < INVEN_TOTAL; i++)
{
/* Get the object */
o_ptr = &p_ptr->inventory[i];
@@ -2751,14 +2311,14 @@ static void process_world()
activate_dg_curse();
/* The object recurse itself ! */
- o_ptr->ident |= IDENT_CURSED;
+ o_ptr->art_flags |= TR_CURSED;
}
/* Auto Curse */
if ((flags & TR_AUTO_CURSE) && (rand_int(AUTO_CURSE_CHANCE) == 0))
{
/* The object recurse itself ! */
- o_ptr->ident |= IDENT_CURSED;
+ o_ptr->art_flags |= TR_CURSED;
}
/*
@@ -2767,7 +2327,7 @@ static void process_world()
*/
if ((flags & TR_TELEPORT) && (rand_int(100) < 1))
{
- if ((o_ptr->ident & IDENT_CURSED) && !p_ptr->anti_tele)
+ if ((o_ptr->art_flags & TR_CURSED) && !p_ptr->anti_tele)
{
disturb();
@@ -2790,7 +2350,10 @@ static void process_world()
/* Skip non-objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Hack: Skip wielded lights that need fuel (already handled above) */
if ((i == INVEN_LITE) && (o_ptr->tval == TV_LITE) && (flags & TR_FUEL_LITE)) continue;
@@ -2805,25 +2368,28 @@ static void process_world()
if (o_ptr->timeout == 0)
{
recharged_notice(o_ptr);
- j++;
+ changed = true;
}
}
}
/* Notice changes */
- if (j)
+ if (changed)
{
- /* Window stuff */
- p_ptr->window |= (PW_EQUIP);
+ p_ptr->window |= PW_EQUIP;
}
/* Recharge rods */
- for (j = 0, i = 0; i < INVEN_TOTAL; i++)
+ changed = false;
+ for (int i = 0; i < INVEN_TOTAL; i++)
{
o_ptr = &p_ptr->inventory[i];
/* Skip non-objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Examine the rod */
auto const flags = object_flags(o_ptr);
@@ -2849,7 +2415,7 @@ static void process_world()
o_ptr->timeout += (flags & TR_CHARGING) ? 2 : 1;
/* Always notice */
- j++;
+ changed = true;
/* Notice changes, provide message if object is inscribed. */
if (o_ptr->timeout >= o_ptr->pval2)
@@ -2868,7 +2434,7 @@ static void process_world()
/* Notice changes */
if (o_ptr->timeout == 0)
{
- j++;
+ changed = true;
recharged_notice(o_ptr);
}
}
@@ -2901,7 +2467,7 @@ static void process_world()
if (o_ptr->pval <= 0)
{
pack_decay(i);
- j++;
+ changed = true;
}
}
}
@@ -2920,7 +2486,7 @@ static void process_world()
int my = p_ptr->py + 1;
get_pos_player(5, &my, &mx);
msg_print("Your egg hatches!");
- place_monster_aux(my, mx, o_ptr->pval2, FALSE, FALSE, MSTATUS_PET);
+ place_monster_aux(my, mx, o_ptr->pval2, false, false, MSTATUS_PET);
monster_type *m_ptr = &m_list[cave[my][mx].m_idx];
auto const r_ptr = m_ptr->race();
@@ -2932,15 +2498,14 @@ static void process_world()
}
inc_stack_size(i, -1);
-
- j++;
+ changed = true;
}
}
}
}
/* Notice changes */
- if (j)
+ if (changed)
{
/* Combine pack */
p_ptr->notice |= (PN_COMBINE);
@@ -2952,13 +2517,16 @@ static void process_world()
/*** Process Objects ***/
/* Process objects */
- for (i = 1; i < o_max; i++)
+ for (int i = 1; i < o_max; i++)
{
/* Access object */
o_ptr = &o_list[i];
/* Skip dead objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Examine the rod */
auto const flags = object_flags(o_ptr);
@@ -3036,7 +2604,7 @@ static void process_world()
my = o_ptr->iy;
get_pos_player(5, &my, &mx);
msg_print("An egg hatches!");
- place_monster_one(my, mx, o_ptr->pval2, 0, FALSE, MSTATUS_ENEMY);
+ place_monster_one(my, mx, o_ptr->pval2, 0, false, MSTATUS_ENEMY);
floor_item_increase(i, -1);
floor_item_describe(i);
floor_item_optimize(i);
@@ -3120,10 +2688,10 @@ static void process_world()
dungeon_type = DUNGEON_WILDERNESS;
dun_level = 0;
- is_recall = TRUE;
+ is_recall = true;
p_ptr->inside_quest = 0;
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
}
else
{
@@ -3139,10 +2707,10 @@ static void process_world()
p_ptr->oldpy = p_ptr->py;
/* Leaving */
- is_recall = TRUE;
+ is_recall = true;
- p_ptr->leaving = TRUE;
- p_ptr->wild_mode = FALSE;
+ p_ptr->leaving = true;
+ p_ptr->wild_mode = false;
}
}
}
@@ -3153,7 +2721,7 @@ static void process_world()
/*
* Verify use of "wizard" mode
*/
-static bool_ enter_wizard_mode()
+static bool enter_wizard_mode()
{
/* Ask first time, but not while loading a dead char with the -w option */
if (!noscore && !(p_ptr->chp < 0))
@@ -3166,7 +2734,7 @@ static bool_ enter_wizard_mode()
/* Verify request */
if (!get_check("Are you sure you want to enter wizard mode? "))
{
- return (FALSE);
+ return false;
}
/* Mark savefile */
@@ -3174,14 +2742,14 @@ static bool_ enter_wizard_mode()
}
/* Success */
- return (TRUE);
+ return true;
}
/*
* Verify use of "debug" commands
*/
-static bool_ enter_debug_mode()
+static bool enter_debug_mode()
{
/* Ask first time */
if (!noscore && !wizard)
@@ -3194,7 +2762,7 @@ static bool_ enter_debug_mode()
/* Verify request */
if (!get_check("Are you sure you want to use debug commands? "))
{
- return (FALSE);
+ return false;
}
/* Mark savefile */
@@ -3202,7 +2770,7 @@ static bool_ enter_debug_mode()
}
/* Success */
- return (TRUE);
+ return true;
}
@@ -3212,14 +2780,15 @@ static bool_ enter_debug_mode()
*
* XXX XXX XXX Make some "blocks"
*/
-static void process_command()
+static void process_command(s16b *command_ptr)
{
auto const &wf_info = game->edit_data.wf_info;
- char error_m[80];
+ assert(command_ptr);
+ auto &command_cmd = *command_ptr;
/* Handle repeating the last command */
- repeat_check();
+ repeat_check(command_ptr);
/* Parse the command */
switch (command_cmd)
@@ -3247,12 +2816,12 @@ static void process_command()
{
if (wizard)
{
- wizard = FALSE;
+ wizard = false;
msg_print("Wizard mode off.");
}
else if (enter_wizard_mode())
{
- wizard = TRUE;
+ wizard = true;
msg_print("Wizard mode on.");
}
@@ -3432,9 +3001,6 @@ static void process_command()
/* Go up staircase */
case '<':
{
- /* Get the light being wielded */
- auto o_ptr = &p_ptr->inventory[INVEN_LITE];
-
/* Cannot move if rooted in place */
if (p_ptr->tim_roots) break;
@@ -3456,10 +3022,7 @@ static void process_command()
msg_print("You can't travel during the day!");
}
else if (p_ptr->sensible_lite &&
- (o_ptr->tval != 0) &&
- (o_ptr->sval >= SV_LITE_GALADRIEL) &&
- (o_ptr->sval <= SV_STONE_LORE) &&
- (o_ptr->sval != SV_LITE_UNDEATH))
+ !is_light_safe(&p_ptr->inventory[INVEN_LITE]))
{
msg_print("Travel with your present light would be unsafe.");
}
@@ -4023,7 +3586,7 @@ static void process_command()
/* Hack -- Save and don't quit */
case KTRL('S'):
{
- is_autosave = FALSE;
+ is_autosave = false;
do_cmd_save_game();
break;
}
@@ -4037,10 +3600,10 @@ static void process_command()
/* Save and quit */
case KTRL('X'):
{
- alive = FALSE;
+ alive = false;
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
break;
}
@@ -4119,6 +3682,8 @@ static void process_command()
/* Would like to have an option disabling this -- pelpel */
if (rand_int(100) < insanity)
{
+ char error_m[80];
+
get_rnd_line("error.txt", error_m);
msg_print(error_m);
}
@@ -4145,7 +3710,7 @@ static void process_command()
static void process_player()
{
auto const &f_info = game->edit_data.f_info;
- auto const &k_info = game->edit_data.k_info;
+ auto const &dungeon_flags = game->dungeon_flags;
int i, j;
@@ -4194,26 +3759,29 @@ static void process_player()
/* Complete resting */
else if (resting == -2)
{
- bool_ stop = TRUE;
+ bool stop = true;
object_type *o_ptr;
/* Get the carried monster */
o_ptr = &p_ptr->inventory[INVEN_CARRY];
/* Stop resting */
- if ((!p_ptr->drain_life) && (p_ptr->chp != p_ptr->mhp)) stop = FALSE;
- if ((!p_ptr->drain_mana) && (p_ptr->csp != p_ptr->msp)) stop = FALSE;
- if (o_ptr->pval2 < o_ptr->pval3) stop = FALSE;
- if (p_ptr->blind || p_ptr->confused) stop = FALSE;
- if (p_ptr->poisoned || p_ptr->afraid) stop = FALSE;
- if (p_ptr->stun || p_ptr->cut) stop = FALSE;
- if (p_ptr->slow || p_ptr->paralyzed) stop = FALSE;
- if (p_ptr->image || p_ptr->word_recall) stop = FALSE;
- if (p_ptr->immov_cntr != 0) stop = FALSE;
+ if ((!p_ptr->drain_life) && (p_ptr->chp != p_ptr->mhp)) stop = false;
+ if ((!p_ptr->drain_mana) && (p_ptr->csp != p_ptr->msp)) stop = false;
+ if (o_ptr->pval2 < o_ptr->pval3) stop = false;
+ if (p_ptr->blind || p_ptr->confused) stop = false;
+ if (p_ptr->poisoned || p_ptr->afraid) stop = false;
+ if (p_ptr->stun || p_ptr->cut) stop = false;
+ if (p_ptr->slow || p_ptr->paralyzed) stop = false;
+ if (p_ptr->image || p_ptr->word_recall) stop = false;
+ if (p_ptr->immov_cntr != 0) stop = false;
for (i = 0; i < 6; i++)
{
- if (p_ptr->stat_cnt[i] > 0) stop = FALSE;
+ if (p_ptr->stat_cnt[i] > 0)
+ {
+ stop = false;
+ }
}
if (stop)
@@ -4267,7 +3835,7 @@ static void process_player()
if (!p_ptr->wild_mode && dun_level == 0)
{
auto &wilderness = game->wilderness;
- wilderness(p_ptr->wilderness_x, p_ptr->wilderness_y).known = TRUE;
+ wilderness(p_ptr->wilderness_x, p_ptr->wilderness_y).known = true;
}
@@ -4278,16 +3846,12 @@ static void process_player()
if (options->fresh_before) Term_fresh();
/* Hack -- Pack Overflow */
- if (p_ptr->inventory[INVEN_PACK].k_idx)
+ if (p_ptr->inventory[INVEN_PACK].k_ptr)
{
int item = INVEN_PACK;
- char o_name[80];
-
- object_type *o_ptr;
-
/* Access the slot to be dropped */
- o_ptr = &p_ptr->inventory[item];
+ auto o_ptr = &p_ptr->inventory[item];
/* Disturbing */
disturb();
@@ -4296,7 +3860,8 @@ static void process_player()
msg_print("Your pack overflows!");
/* Describe */
- object_desc(o_name, o_ptr, TRUE, 3);
+ char o_name[80];
+ object_desc(o_name, o_ptr, true, 3);
/* Message */
msg_format("You drop %s (%c).", o_name, index_to_label(item));
@@ -4345,7 +3910,7 @@ static void process_player()
p_ptr->redraw |= (PR_FRAME);
}
- p_ptr->did_nothing = TRUE;
+ p_ptr->did_nothing = true;
/* Take a turn */
energy_use = 100;
@@ -4363,7 +3928,7 @@ static void process_player()
* instead of using running commands when s/he follows
* Eru and do the opposite for the other deities -- pelpel
*/
- /* p_ptr->did_nothing = TRUE; */
+ /* p_ptr->did_nothing = true; */
}
/* Repeated command */
@@ -4379,15 +3944,15 @@ static void process_player()
redraw_stuff();
/* Hack -- Assume messages were seen */
- msg_flag = FALSE;
+ msg_flag = false;
/* Clear the top line */
prt("", 0, 0);
/* Process the command */
- process_command();
+ process_command(&command_cmd);
- p_ptr->did_nothing = TRUE;
+ p_ptr->did_nothing = true;
}
/* Normal command */
@@ -4397,10 +3962,10 @@ static void process_player()
move_cursor_relative(p_ptr->py, p_ptr->px);
/* Get a command (normal) */
- request_command(FALSE);
+ request_command(false);
/* Process the command */
- process_command();
+ process_command(&command_cmd);
}
@@ -4421,7 +3986,7 @@ static void process_player()
if (!options->avoid_other && shimmer_monsters)
{
/* Clear the flag */
- shimmer_monsters = FALSE;
+ shimmer_monsters = false;
/* Shimmer multi-hued monsters */
for (i = 1; i < m_max; i++)
@@ -4439,7 +4004,7 @@ static void process_player()
if (!(r_ptr->flags & RF_ATTR_MULTI)) continue;
/* Reset the flag */
- shimmer_monsters = TRUE;
+ shimmer_monsters = true;
/* Redraw regardless */
lite_spot(m_ptr->fy, m_ptr->fx);
@@ -4450,23 +4015,22 @@ static void process_player()
if (!options->avoid_other && !options->avoid_shimmer && shimmer_objects)
{
/* Clear the flag */
- shimmer_objects = FALSE;
+ shimmer_objects = false;
/* Shimmer multi-hued objects */
for (i = 1; i < o_max; i++)
{
/* Acquire object -- for speed only base items are allowed to shimmer */
object_type *o_ptr = &o_list[i];
- auto k_ptr = &k_info[o_ptr->k_idx];
/* Skip dead or carried objects */
- if ((!o_ptr->k_idx) || (!o_ptr->ix)) continue;
+ if ((!o_ptr->k_ptr) || (!o_ptr->ix)) continue;
/* Skip non-multi-hued monsters */
- if (!(k_ptr->flags & TR_ATTR_MULTI)) continue;
+ if (!(o_ptr->k_ptr->flags & TR_ATTR_MULTI)) continue;
/* Reset the flag */
- shimmer_objects = TRUE;
+ shimmer_objects = true;
/* Redraw regardless */
lite_spot(o_ptr->iy, o_ptr->ix);
@@ -4512,7 +4076,7 @@ static void process_player()
if (repair_monsters)
{
/* Reset the flag */
- repair_monsters = FALSE;
+ repair_monsters = false;
/* Rotate detection flags */
for (i = 1; i < m_max; i++)
@@ -4542,7 +4106,7 @@ static void process_player()
m_ptr->mflag &= ~(MFLAG_SHOW);
/* Still need repairs */
- repair_monsters = TRUE;
+ repair_monsters = true;
}
/* Remove detection */
@@ -4552,10 +4116,10 @@ static void process_player()
m_ptr->mflag &= ~(MFLAG_MARK);
/* Assume invisible */
- m_ptr->ml = FALSE;
+ m_ptr->ml = false;
/* Update the monster */
- update_mon(i, FALSE);
+ update_mon(i, false);
/* Redraw regardless */
lite_spot(m_ptr->fy, m_ptr->fx);
@@ -4597,12 +4161,13 @@ static void process_player()
static void dungeon()
{
auto const &d_info = game->edit_data.d_info;
+ auto const &dungeon_flags = game->dungeon_flags;
/* Reset various flags */
- hack_mind = FALSE;
+ hack_mind = false;
/* Not leaving */
- p_ptr->leaving = FALSE;
+ p_ptr->leaving = false;
/* Reset the "command" vars */
command_cmd = 0;
@@ -4622,9 +4187,9 @@ static void dungeon()
/* Check visual effects */
- shimmer_monsters = TRUE;
- shimmer_objects = TRUE;
- repair_monsters = TRUE;
+ shimmer_monsters = true;
+ shimmer_objects = true;
+ repair_monsters = true;
/* Disturb */
@@ -4645,21 +4210,21 @@ static void dungeon()
/* No stairs down from Quest */
if (is_quest(dun_level) && !p_ptr->astral)
{
- create_down_stair = FALSE;
- create_down_shaft = FALSE;
+ create_down_stair = false;
+ create_down_shaft = false;
}
/* Paranoia -- no stairs from town or wilderness */
- if (!dun_level) create_down_stair = create_up_stair = FALSE;
- if (!dun_level) create_down_shaft = create_up_shaft = FALSE;
+ if (!dun_level) create_down_stair = create_up_stair = false;
+ if (!dun_level) create_down_shaft = create_up_shaft = false;
/* Option -- no connected stairs */
- if (!options->dungeon_stair) create_down_stair = create_up_stair = FALSE;
- if (!options->dungeon_stair) create_down_shaft = create_up_shaft = FALSE;
+ if (!options->dungeon_stair) create_down_stair = create_up_stair = false;
+ if (!options->dungeon_stair) create_down_shaft = create_up_shaft = false;
/* no connecting stairs on special levels */
- if (!(dungeon_flags & DF_NO_STAIR)) create_down_stair = create_up_stair = FALSE;
- if (!(dungeon_flags & DF_NO_STAIR)) create_down_shaft = create_up_shaft = FALSE;
+ if (!(dungeon_flags & DF_NO_STAIR)) create_down_stair = create_up_stair = false;
+ if (!(dungeon_flags & DF_NO_STAIR)) create_down_shaft = create_up_shaft = false;
/* Make a stairway. */
if ((create_up_stair || create_down_stair ||
@@ -4692,8 +4257,8 @@ static void dungeon()
}
/* Cancel the stair request */
- create_down_stair = create_up_stair = FALSE;
- create_down_shaft = create_up_shaft = FALSE;
+ create_down_stair = create_up_stair = false;
+ create_down_shaft = create_up_shaft = false;
}
/* Hack - Assume invalid panel */
@@ -4710,7 +4275,7 @@ static void dungeon()
/* Enter "xtra" mode */
- character_xtra = TRUE;
+ character_xtra = true;
/* Window stuff */
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
@@ -4752,7 +4317,7 @@ static void dungeon()
redraw_stuff();
/* Leave "xtra" mode */
- character_xtra = FALSE;
+ character_xtra = false;
/* Update stuff */
p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS | PU_POWERS | PU_BODY);
@@ -4791,7 +4356,7 @@ static void dungeon()
/* Reset the object generation level */
object_level = dun_level;
- hack_mind = TRUE;
+ hack_mind = true;
/* Mega Hack, if needed wipe all stairs */
if (dungeon_type == DUNGEON_DEATH)
@@ -4826,7 +4391,7 @@ static void dungeon()
}
/* Main loop */
- while (TRUE)
+ while (true)
{
/* Hack -- Compact the monster list occasionally */
if (m_cnt + 32 > max_m_idx) compact_monsters(64);
@@ -4905,7 +4470,10 @@ static void dungeon()
/* Make it pulsate and live !!!! */
if ((dungeon_flags & DF_EVOLVE) && dun_level)
{
- if (!(turn % 10)) evolve_level(TRUE);
+ if (!(turn % 10))
+ {
+ evolve_level(true);
+ }
}
/* Notice stuff */
@@ -4963,7 +4531,7 @@ static void dungeon()
dungeon_type = DUNGEON_WILDERNESS;
}
- is_recall = FALSE;
+ is_recall = false;
}
@@ -4974,27 +4542,16 @@ static void dungeon()
*/
static void load_all_pref_files()
{
- char buf[1024];
-
std::string const &player_name = game->player_name;
- /* Access the "race" pref file */
- sprintf(buf, "%s.prf", rp_ptr->title.c_str());
-
- /* Process that file */
- process_pref_file(buf);
+ /* Process the "race" pref file */
+ process_pref_file(name_file_pref(rp_ptr->title));
- /* Access the "class" pref file */
- sprintf(buf, "%s.prf", spp_ptr->title);
+ /* Process the "class" pref file */
+ process_pref_file(name_file_pref(spp_ptr->title));
- /* Process that file */
- process_pref_file(buf);
-
- /* Access the "character" pref file */
- sprintf(buf, "%s.prf", player_name.c_str());
-
- /* Process that file */
- process_pref_file(buf);
+ /* Process the "character" pref file */
+ process_pref_file(name_file_pref(player_name));
/* Load automatizer settings. Character-specific automatizer
* file gets priority over the "template" file. We do not try
@@ -5015,46 +4572,48 @@ static void load_all_pref_files()
/*
* Actually play a game
*/
-void play_game()
+void play_game(program_args const &args)
{
auto const &d_info = game->edit_data.d_info;
int i, tmp_dun;
- bool_ cheat_death = FALSE;
+ bool cheat_death = false;
/* Initialize player */
p_ptr = new player_type();
/* Hack -- Character is "icky" */
- character_icky = TRUE;
+ character_icky = true;
/* Make sure main term is active */
Term_activate(angband_term[0]);
/* Initialise the resize hooks for all the terminals */
- angband_term[0]->resize_hook = resize_map;
+ term_set_resize_hook(angband_term[0], resize_map);
for (i = 1; i < ANGBAND_TERM_MAX; i++)
{
if (angband_term[i])
{
- /* Add redraw hook */
- angband_term[i]->resize_hook = resize_window;
+ term_set_resize_hook(angband_term[i], resize_window);
}
}
/* Hack -- turn off the cursor */
- Term_set_cursor(0);
+ Term_hide_cursor();
/* Character list */
- bool_ new_game = FALSE;
- if (!no_begin_screen) new_game = begin_screen();
- no_begin_screen = FALSE;
+ bool new_game = false;
+ if (!no_begin_screen)
+ {
+ new_game = begin_screen();
+ }
+ no_begin_screen = false;
/* Attempt to load */
- if (!load_player())
+ if (!load_player(args))
{
/* Oops */
quit("broken savefile");
@@ -5064,17 +4623,17 @@ void play_game()
if (!character_loaded)
{
/* Make new player */
- new_game = TRUE;
+ new_game = true;
/* The dungeon is not ready */
- character_dungeon = FALSE;
+ character_dungeon = false;
}
/* Process old character */
if (!new_game)
{
/* Process the player name */
- process_player_name(FALSE);
+ set_player_base(game->player_name);
}
/* Force "complex" RNG */
@@ -5087,7 +4646,7 @@ void play_game()
modules[game_module_idx].intro();
/* The dungeon is not ready */
- character_dungeon = FALSE;
+ character_dungeon = false;
/* Set the seed for flavors */
seed_flavor() = seed_t::system();
@@ -5119,10 +4678,13 @@ void play_game()
Term_fresh();
/* Be sure to not bother the player */
- calc_powers_silent = TRUE;
+ calc_powers_silent = true;
/* Hack -- Enter wizard mode */
- if (arg_wizard && enter_wizard_mode()) wizard = TRUE;
+ if (args.wizard && enter_wizard_mode())
+ {
+ wizard = true;
+ }
/* Flavor the objects */
flavor_init();
@@ -5140,14 +4702,17 @@ void play_game()
window_stuff();
/* load user file */
- process_pref_file("user.prf");
+ process_pref_file(name_file_pref("user"));
/* Load the "pref" files */
load_all_pref_files();
/* Set or clear "rogue_like_commands" if requested */
- if (arg_force_original) options->rogue_like_commands = FALSE;
- if (arg_force_roguelike) options->rogue_like_commands = TRUE;
+ if (auto it = args.force_key_set)
+ {
+ assert((*it == 'r') || (*it == 'o'));
+ options->rogue_like_commands = (*it == 'r');
+ }
/* Initialize vault info */
if (init_v_info()) quit("Cannot initialize vaults");
@@ -5158,7 +4723,7 @@ void play_game()
init_hooks_module();
/* React to changes */
- Term_xtra(TERM_XTRA_REACT, 0);
+ Term_xtra_react();
/* Mega hack, prevent lots of bugs */
if ((p_ptr->px == 0) || (p_ptr->py == 0))
@@ -5180,21 +4745,21 @@ void play_game()
process_hooks_new(HOOK_GAME_START, NULL, NULL);
/* Character is now "complete" */
- character_generated = TRUE;
+ character_generated = true;
/* Hack -- Character is no longer "icky" */
- character_icky = FALSE;
+ character_icky = false;
/* Start game */
- alive = TRUE;
+ alive = true;
/* Hack -- Enforce "delayed death" */
- if (p_ptr->chp < 0) death = TRUE;
+ if (p_ptr->chp < 0) death = true;
/* Process */
- while (TRUE)
+ while (true)
{
/* Save the level */
old_dun_level = dun_level;
@@ -5203,7 +4768,7 @@ void play_game()
/* We reached surface ? good, lets go down again !! */
if (p_ptr->astral && !dun_level)
{
- p_ptr->astral = FALSE;
+ p_ptr->astral = false;
cmsg_print(TERM_L_GREEN,
"Well done ! You reached the town ! "
"You can now go down again.");
@@ -5290,18 +4855,18 @@ void play_game()
/* Accidental Death */
if (alive && death)
{
- cheat_death = FALSE;
+ cheat_death = false;
/* Can we die ? please let us die ! */
if (process_hooks_new(HOOK_DIE, NULL, NULL))
{
- cheat_death = TRUE;
+ cheat_death = true;
}
/* Deus ex machina */
else if (granted_resurrection())
{
- cheat_death = TRUE;
+ cheat_death = true;
p_ptr->grace = -200000;
cmsg_format(TERM_L_GREEN,
"The power of %s raises you back from the grave!",
@@ -5312,7 +4877,7 @@ void play_game()
/* Blood of life */
else if (p_ptr->allow_one_death > 0)
{
- cheat_death = TRUE;
+ cheat_death = true;
/* Lose one extra life */
p_ptr->allow_one_death--;
@@ -5325,7 +4890,7 @@ void play_game()
/* Cheat death option */
else if ((wizard || options->cheat_live) && !get_check("Die? "))
{
- cheat_death = TRUE;
+ cheat_death = true;
/* Mark savefile */
noscore |= 0x0001;
@@ -5364,7 +4929,7 @@ void play_game()
set_cut(0);
/* accounting for a new ailment. -LM- */
- p_ptr->black_breath = FALSE;
+ p_ptr->black_breath = false;
/* Hack -- don't go to undead form */
p_ptr->necro_extra &= ~CLASS_UNDEAD;
@@ -5387,7 +4952,7 @@ void play_game()
game->died_from = "Cheating death";
/* Do not die */
- death = FALSE;
+ death = false;
/* New depth -KMW- */
/* dun_level = 0; */
@@ -5395,7 +4960,7 @@ void play_game()
p_ptr->inside_quest = 0;
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
}
}
@@ -5406,7 +4971,7 @@ void play_game()
}
/* Mega hack */
- if (dun_level) p_ptr->wild_mode = FALSE;
+ if (dun_level) p_ptr->wild_mode = false;
/* Make a new level */
process_hooks_new(HOOK_NEW_LEVEL, NULL, NULL);
diff --git a/src/dungeon.h b/src/dungeon.h
deleted file mode 100644
index b5a81a59..00000000
--- a/src/dungeon.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-// C linkage required for these functions since main-* code uses them.
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void play_game();
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/src/dungeon.hpp b/src/dungeon.hpp
index e14f4a12..263c1f10 100644
--- a/src/dungeon.hpp
+++ b/src/dungeon.hpp
@@ -1,6 +1,5 @@
#pragma once
-#include <vector>
+#include "program_args.hpp"
-void sense_inventory();
-void sense_objects(std::vector<int> const &object_idxs);
+void play_game(program_args const &);
diff --git a/src/dungeon_flag_list.hpp b/src/dungeon_flag_list.hpp
index 8fdefc95..d152634e 100644
--- a/src/dungeon_flag_list.hpp
+++ b/src/dungeon_flag_list.hpp
@@ -44,7 +44,6 @@ DF(2, 4, ASK_LEAVE)
DF(2, 5, NO_STAIR)
DF(2, 6, SPECIAL)
DF(2, 7, NO_NEW_MONSTER)
-DF(2, 8, DESC)
DF(2, 9, NO_GENO)
DF(2, 10, NO_BREATH)
DF(2, 11, WATER_BREATH)
@@ -52,4 +51,3 @@ DF(2, 12, ELVEN)
DF(2, 13, DWARVEN)
DF(2, 14, NO_EASY_MOVE)
DF(2, 15, NO_RECALL_OUT)
-DF(2, 16, DESC_ALWAYS)
diff --git a/src/dungeon_info_type.hpp b/src/dungeon_info_type.hpp
index 2f8fefde..afee2c52 100644
--- a/src/dungeon_info_type.hpp
+++ b/src/dungeon_info_type.hpp
@@ -1,12 +1,14 @@
#pragma once
-#include "h-basic.h"
-#include "rule_type.hpp"
-#include "obj_theme.hpp"
#include "dungeon_flag_set.hpp"
+#include "h-basic.hpp"
+#include "level_data.hpp"
+#include "obj_theme.hpp"
+#include "rule_type.hpp"
#include <array>
#include <string>
+#include <unordered_map>
/**
* Maximum number of towns per dungeon
@@ -41,7 +43,7 @@ struct dungeon_info_type
s16b mindepth = 0; /* Minimal depth */
s16b maxdepth = 0; /* Maximal depth */
- bool_ principal = 0; /* If it's a part of the main dungeon */
+ bool principal = 0; /* If it's a part of the main dungeon */
byte min_plev = 0; /* Minimal plev needed to enter -- it's an anti-cheating mesure */
int min_m_alloc_level = 0; /* Minimal number of monsters per level */
@@ -71,6 +73,8 @@ struct dungeon_info_type
int d_frequency[4] = { 0 }; /* Frequency of damage (1 is the minimum) */
int d_type[4] = { 0 }; /* Type of damage */
+ std::unordered_map<int, level_data> level_data_by_depth { };
+
s16b t_idx[TOWN_DUNGEON] = { 0 }; /* The towns */
s16b t_level[TOWN_DUNGEON] = { 0 }; /* The towns levels */
s16b t_num = 0; /* Number of towns */
diff --git a/src/effect_type.hpp b/src/effect_type.hpp
index 8cd638c6..f74ba2ab 100644
--- a/src/effect_type.hpp
+++ b/src/effect_type.hpp
@@ -1,17 +1,17 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* Lasting spell effects. (Clouds, etc.)
*/
struct effect_type
{
- s16b time; /* For how long */
- s16b dam; /* How much damage */
- s16b type; /* Of which type */
- s16b cy; /* Center of the cast*/
- s16b cx; /* Center of the cast*/
- s16b rad; /* Radius -- if needed */
- u32b flags; /* Flags */
+ s16b time = 0; /* For how long */
+ s16b dam = 0; /* How much damage */
+ s16b type = 0; /* Of which type */
+ s16b cy = 0; /* Center of the cast*/
+ s16b cx = 0; /* Center of the cast*/
+ s16b rad = 0; /* Radius -- if needed */
+ u32b flags = 0; /* Flags */
};
diff --git a/src/ego_item_type.hpp b/src/ego_item_type.hpp
index 2082c083..76794426 100644
--- a/src/ego_item_type.hpp
+++ b/src/ego_item_type.hpp
@@ -1,10 +1,12 @@
#pragma once
#include "ego_flag_set.hpp"
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_flag_set.hpp"
#include <array>
+#include <boost/optional.hpp>
+#include <string>
/*
* Size of flag rarity tables
@@ -16,9 +18,9 @@ constexpr int FLAG_RARITY_MAX = 6;
*/
struct ego_item_type
{
- const char *name = nullptr; /* Name */
+ std::string name; /* Name */
- bool_ before = FALSE; /* Before or after the object name ? */
+ bool before = false; /* Before or after the object name ? */
byte tval[10] = { 0 };
byte min_sval[10] = { 0 };
@@ -50,7 +52,7 @@ struct ego_item_type
object_flag_set need_flags;
object_flag_set forbid_flags;
- s16b power = -1; /* Power granted, if any */
+ boost::optional<int> power; /* Power granted, if any */
public:
ego_item_type()
diff --git a/src/fate.hpp b/src/fate.hpp
index 906bc99d..948adb51 100644
--- a/src/fate.hpp
+++ b/src/fate.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* Fate descritpor.
@@ -17,6 +17,6 @@ struct fate
s16b r_idx; /* Monster to find */
s16b count; /* Number of things */
s16b time; /* Turn before */
- bool_ know; /* Has it been predicted? */
- bool_ icky; /* Hackish runtime-only flag */
+ bool know; /* Has it been predicted? */
+ bool icky; /* Hackish runtime-only flag */
};
diff --git a/src/feature_type.hpp b/src/feature_type.hpp
index e818f17a..9634b99c 100644
--- a/src/feature_type.hpp
+++ b/src/feature_type.hpp
@@ -1,15 +1,17 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "feature_flag_set.hpp"
+#include <string>
+
/**
* Terrain feature descriptor.
*/
struct feature_type
{
- char *name = nullptr; /* Name */
+ std::string name; /* Name */
const char *text = nullptr; /* Text. May point to shared read-only memory, DO NOT FREE! */
const char *tunnel = nullptr; /* Text for tunneling. May point to shared read-only memory, DO NOT FREE! */
diff --git a/src/files.cc b/src/files.cc
index 6b3de0f0..42de6999 100644
--- a/src/files.cc
+++ b/src/files.cc
@@ -7,7 +7,6 @@
*/
#include "files.hpp"
-#include "files.h"
#include "cave.hpp"
#include "cave_type.hpp"
@@ -21,7 +20,6 @@
#include "hooks.hpp"
#include "init1.hpp"
#include "levels.hpp"
-#include "loadsave.h"
#include "loadsave.hpp"
#include "mimic.hpp"
#include "monoid.hpp"
@@ -51,23 +49,67 @@
#include "tables.hpp"
#include "town_type.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "wilderness_map.hpp"
#include "wilderness_type_info.hpp"
#include "xtra1.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
+#include "z-util.hpp"
#include <boost/algorithm/string.hpp>
-#include <boost/filesystem.hpp>
#include <iostream>
+#include <fcntl.h>
#include <fmt/format.h>
#include <fstream>
#include <limits>
#include <memory>
#include <unordered_set>
+using boost::algorithm::equals;
+using boost::algorithm::trim_right;
+using boost::algorithm::starts_with;
+
+namespace fs = boost::filesystem;
+
+std::string name_file_note(std::string_view sv)
+{
+ std::string buf;
+ buf.reserve(sv.size() + 4);
+ buf += sv;
+ buf += ".nte";
+ return buf;
+}
+
+std::string name_file_pref(std::string_view sv)
+{
+ std::string buf;
+ buf.reserve(sv.size() + 4);
+ buf += sv;
+ buf += ".prf";
+ return buf;
+}
+
+std::string name_file_save()
+{
+ return name_file_save(game->player_base);
+}
+
+std::string name_file_save(std::string_view sv)
+{
+ char buf[1024];
+ std::string s(sv);
+ path_build(buf, sizeof(buf), ANGBAND_DIR_SAVE, s.c_str());
+
+ return buf;
+}
+
+boost::filesystem::path name_file_dungeon_save(std::string const &ext)
+{
+ fs::path p(name_file_save());
+ return p.replace_extension(ext);
+}
+
/*
* Extract the first few "tokens" from a buffer
*
@@ -244,7 +286,7 @@ errr process_pref_file_aux(char *buf)
if (buf[0] == '%')
{
/* Attempt to Process the given file */
- return (process_pref_file(buf + 2));
+ return process_pref_file(buf + 2);
}
@@ -316,7 +358,7 @@ errr process_pref_file_aux(char *buf)
if (tokenize(buf + 4, 3, zz, ':', '/') == 3)
{
player_race_mod *rmp_ptr;
- i = (huge)strtol(zz[0], NULL, 0);
+ i = strtol(zz[0], NULL, 0);
n1 = strtol(zz[1], NULL, 0);
n2 = strtol(zz[2], NULL, 0);
if (i >= static_cast<int>(race_mod_info.size())) return (1);
@@ -341,12 +383,12 @@ errr process_pref_file_aux(char *buf)
n1 = strtol(zz[1], NULL, 0);
n2 = strtol(zz[2], NULL, 0);
- if (i >= k_info.size())
+ if (!k_info.count(i))
{
return (1);
}
- auto k_ptr = &k_info[i];
+ auto k_ptr = k_info.at(i);
if (n1)
{
@@ -427,18 +469,18 @@ errr process_pref_file_aux(char *buf)
n1 = strtol(zz[1], NULL, 0);
n2 = strtol(zz[2], NULL, 0);
- for (auto &k_ref: k_info)
+ for (auto &k_entry: k_info)
{
- auto k_ptr = &k_ref;
+ auto k_ptr = k_entry.second;
if (k_ptr->tval == j)
{
if (n1)
{
- k_ref.d_attr = n1;
+ k_ptr->d_attr = n1;
}
if (n2)
{
- k_ref.d_char = n2;
+ k_ptr->d_char = n2;
}
}
}
@@ -624,9 +666,9 @@ errr process_pref_file_aux(char *buf)
{
for (auto const &option: options->standard_options)
{
- if (option.o_var && streq(option.o_text, buf + 2))
+ if (option.o_var && equals(option.o_text, buf + 2))
{
- *option.o_var = FALSE;
+ *option.o_var = false;
return 0;
}
}
@@ -637,9 +679,9 @@ errr process_pref_file_aux(char *buf)
{
for (auto const &option: options->standard_options)
{
- if (option.o_var && streq(option.o_text, buf + 2))
+ if (option.o_var && equals(option.o_text, buf + 2))
{
- *option.o_var = TRUE;
+ *option.o_var = true;
return 0;
}
}
@@ -704,9 +746,9 @@ errr process_pref_file_aux(char *buf)
* Output:
* result
*/
-static cptr process_pref_file_expr(char **sp, char *fp)
+static const char *process_pref_file_expr(char **sp, char *fp)
{
- cptr v;
+ const char *v;
char *b;
char *s;
@@ -747,72 +789,40 @@ static cptr process_pref_file_expr(char **sp, char *fp)
}
/* Function: IOR */
- else if (streq(t, "IOR"))
+ else if (equals(t, "IOR"))
{
v = "0";
while (*s && (f != b2))
{
t = process_pref_file_expr(&s, &f);
- if (*t && !streq(t, "0")) v = "1";
+ if (*t && !equals(t, "0")) v = "1";
}
}
/* Function: AND */
- else if (streq(t, "AND"))
+ else if (equals(t, "AND"))
{
v = "1";
while (*s && (f != b2))
{
t = process_pref_file_expr(&s, &f);
- if (*t && streq(t, "0")) v = "0";
+ if (*t && equals(t, "0")) v = "0";
}
}
/* Function: NOT */
- else if (streq(t, "NOT"))
+ else if (equals(t, "NOT"))
{
v = "1";
while (*s && (f != b2))
{
t = process_pref_file_expr(&s, &f);
- if (*t && !streq(t, "0")) v = "0";
+ if (*t && !equals(t, "0")) v = "0";
}
}
/* Function: EQU */
- else if (streq(t, "EQU"))
- {
- v = "1";
- if (*s && (f != b2))
- {
- t = process_pref_file_expr(&s, &f);
- }
- while (*s && (f != b2))
- {
- p = t;
- t = process_pref_file_expr(&s, &f);
- if (*t && !streq(p, t)) v = "0";
- }
- }
-
- /* Function: LEQ */
- else if (streq(t, "LEQ"))
- {
- v = "1";
- if (*s && (f != b2))
- {
- t = process_pref_file_expr(&s, &f);
- }
- while (*s && (f != b2))
- {
- p = t;
- t = process_pref_file_expr(&s, &f);
- if (*t && (strcmp(p, t) > 0)) v = "0";
- }
- }
-
- /* Function: GEQ */
- else if (streq(t, "GEQ"))
+ else if (equals(t, "EQU"))
{
v = "1";
if (*s && (f != b2))
@@ -823,48 +833,12 @@ static cptr process_pref_file_expr(char **sp, char *fp)
{
p = t;
t = process_pref_file_expr(&s, &f);
- if (*t && (strcmp(p, t) < 0)) v = "0";
- }
- }
-
- /* Function: LEQN */
- else if (streq(t, "LEQN"))
- {
- int n = 0;
- v = "1";
- if (*s && (f != b2))
- {
- t = process_pref_file_expr(&s, &f);
- n = atoi(t);
- }
- while (*s && (f != b2))
- {
- p = t;
- t = process_pref_file_expr(&s, &f);
- if (*t && (atoi(t) < n)) v = "0";
- }
- }
-
- /* Function: GEQN */
- else if (streq(t, "GEQN"))
- {
- int n = 0;
- v = "1";
- if (*s && (f != b2))
- {
- t = process_pref_file_expr(&s, &f);
- n = atoi(t);
- }
- while (*s && (f != b2))
- {
- p = t;
- t = process_pref_file_expr(&s, &f);
- if (*t && (atoi(t) > n)) v = "0";
+ if (*t && !equals(p, t)) v = "0";
}
}
/* Function SKILL */
- else if (streq(t, "SKILL"))
+ else if (equals(t, "SKILL"))
{
static char skill_val[4*sizeof(int) + 1];
s16b skill = -1;
@@ -910,34 +884,10 @@ static cptr process_pref_file_expr(char **sp, char *fp)
if (*b == '$')
{
/* System */
- if (streq(b + 1, "SYS"))
+ if (equals(b + 1, "SYS"))
{
v = ANGBAND_SYS;
}
-
- /* Race */
- else if (streq(b + 1, "RACE"))
- {
- v = rp_ptr->title.c_str(); // The string SHOULD be stable enough for this
- }
-
- /* Race */
- else if (streq(b + 1, "RACEMOD"))
- {
- v = rmp_ptr->title.c_str(); // The string SHOULD be stable enough for this
- }
-
- /* Class */
- else if (streq(b + 1, "CLASS"))
- {
- v = spp_ptr->title;
- }
-
- /* Player */
- else if (streq(b + 1, "PLAYER"))
- {
- v = game->player_base.c_str(); // The string SHOULD be stable enough for this
- }
}
/* Constant */
@@ -960,6 +910,7 @@ static cptr process_pref_file_expr(char **sp, char *fp)
+
/*
* Process the "user pref file" with the given name
*
@@ -968,7 +919,7 @@ static cptr process_pref_file_expr(char **sp, char *fp)
* We also accept the special "?" and "%" directives, which
* allow conditional evaluation and filename inclusion.
*/
-errr process_pref_file(cptr name)
+errr process_pref_file(std::string const &name)
{
FILE *fp;
@@ -978,10 +929,10 @@ errr process_pref_file(cptr name)
errr err = 0;
- bool_ bypass = FALSE;
+ bool bypass = false;
/* Build the filename -- Allow users to override system pref files */
- path_build(buf, 1024, ANGBAND_DIR_USER, name);
+ path_build(buf, 1024, ANGBAND_DIR_USER, name.c_str());
/* Open the file */
fp = my_fopen(buf, "r");
@@ -990,7 +941,7 @@ errr process_pref_file(cptr name)
if (!fp)
{
/* Build the pathname, this time using the system pref directory */
- path_build(buf, 1024, ANGBAND_DIR_PREF, name);
+ path_build(buf, 1024, ANGBAND_DIR_PREF, name.c_str());
/* Open the file */
fp = my_fopen(buf, "r");
@@ -1021,7 +972,7 @@ errr process_pref_file(cptr name)
if ((buf[0] == '?') && (buf[1] == ':'))
{
char f;
- cptr v;
+ const char *v;
char *s;
/* Start */
@@ -1031,7 +982,7 @@ errr process_pref_file(cptr name)
v = process_pref_file_expr(&s, &f);
/* Set flag */
- bypass = (streq(v, "0") ? TRUE : FALSE);
+ bypass = (equals(v, "0") ? true : false);
/* Continue */
continue;
@@ -1064,7 +1015,7 @@ errr process_pref_file(cptr name)
if (err)
{
/* Useful error message */
- msg_format("Error %d in line %d of file '%s'.", err, num, name);
+ msg_format("Error %d in line %d of file '%s'.", err, num, name.c_str());
msg_format("Parsing '%s'", buf);
}
@@ -1082,7 +1033,7 @@ errr process_pref_file(cptr name)
* Print long number with header at given row, column
* Use the color for the number, not the header
*/
-static void prt_lnum(cptr header, s32b num, int row, int col, byte color)
+static void prt_lnum(const char *header, s32b num, int row, int col, byte color)
{
int len = strlen(header);
char out_val[32];
@@ -1096,8 +1047,8 @@ static void prt_lnum(cptr header, s32b num, int row, int col, byte color)
/*
* Print number with header at given row, column
*/
-static void prt_num(cptr header, int num, int row, int col, byte color,
- cptr space)
+static void prt_num(const char *header, int num, int row, int col, byte color,
+ const char *space)
{
int len = strlen(header);
char out_val[32];
@@ -1112,7 +1063,7 @@ static void prt_num(cptr header, int num, int row, int col, byte color,
/*
* Print str with header at given row, column
*/
-static void prt_str(cptr header, cptr str, int row, int col, byte color)
+static void prt_str(const char *header, const char *str, int row, int col, byte color)
{
int len = strlen(header);
char out_val[32];
@@ -1132,35 +1083,30 @@ static void prt_str(cptr header, cptr str, int row, int col, byte color)
*/
static void display_player_middle()
{
- int show_tohit = p_ptr->dis_to_h;
- int show_todam = p_ptr->dis_to_d;
-
- object_type *o_ptr = &p_ptr->inventory[INVEN_WIELD];
char num[7];
byte color;
int speed;
- /* Hack -- add in weapon info if known */
- if (object_known_p(o_ptr)) show_tohit = p_ptr->dis_to_h + p_ptr->to_h_melee + o_ptr->to_h;
- else show_tohit = p_ptr->dis_to_h + p_ptr->to_h_melee;
- if (object_known_p(o_ptr)) show_todam = p_ptr->dis_to_d + p_ptr->to_d_melee + o_ptr->to_d;
- else show_todam = p_ptr->dis_to_d + p_ptr->to_d_melee;
-
- /* Dump the bonuses to hit/dam */
- prt_num("+ To Melee Hit ", show_tohit, 9, 1, TERM_L_BLUE, " ");
- prt_num("+ To Melee Damage", show_todam, 10, 1, TERM_L_BLUE, " ");
+ /* Dump the melee bonuses to hit/dam */
+ {
+ auto const o_ptr = &p_ptr->inventory[INVEN_WIELD];
+ int show_tohit = p_ptr->dis_to_h + p_ptr->to_h_melee + o_ptr->to_h;
+ int show_todam = p_ptr->dis_to_d + p_ptr->to_d_melee + o_ptr->to_d;
- o_ptr = &p_ptr->inventory[INVEN_BOW];
+ prt_num("+ To Melee Hit ", show_tohit, 9, 1, TERM_L_BLUE, " ");
+ prt_num("+ To Melee Damage", show_todam, 10, 1, TERM_L_BLUE, " ");
+ }
- /* Hack -- add in weapon info if known */
- if (object_known_p(o_ptr)) show_tohit = p_ptr->dis_to_h + p_ptr->to_h_ranged + o_ptr->to_h;
- else show_tohit = p_ptr->dis_to_h + p_ptr->to_h_ranged;
- if (object_known_p(o_ptr)) show_todam = p_ptr->to_d_ranged + o_ptr->to_d;
- else show_todam = p_ptr->to_d_ranged;
+ /* Dump the ranged bonuses to hit/dam */
+ {
+ auto const o_ptr = &p_ptr->inventory[INVEN_BOW];
+ int show_tohit = p_ptr->dis_to_h + p_ptr->to_h_ranged + o_ptr->to_h;
+ int show_todam = p_ptr->to_d_ranged + o_ptr->to_d;
- prt_num("+ To Ranged Hit ", show_tohit, 11, 1, TERM_L_BLUE, " ");
- prt_num("+ To Ranged Damage", show_todam, 12, 1, TERM_L_BLUE, " ");
+ prt_num("+ To Ranged Hit ", show_tohit, 11, 1, TERM_L_BLUE, " ");
+ prt_num("+ To Ranged Damage", show_todam, 12, 1, TERM_L_BLUE, " ");
+ }
/* Dump the total armor class */
prt_str(" AC ", format("%d+%d", p_ptr->ac, p_ptr->dis_to_a), 13, 1, TERM_L_BLUE);
@@ -1310,7 +1256,7 @@ static byte likert_color = TERM_WHITE;
/*
* Returns a "rating" of x depending on y
*/
-static cptr likert(int x, int y)
+static const char *likert(int x, int y)
{
static char dummy[20] = "";
@@ -1399,7 +1345,7 @@ static void display_player_various()
int tmp, tmp2, damdice, damsides, dambonus, blows;
int xthn, xthb;
int xdev, xsav, xstl;
- cptr desc;
+ const char *desc;
int i;
object_type *o_ptr;
@@ -1518,7 +1464,7 @@ static void display_player_various()
/* Access the first weapon */
o_ptr = &p_ptr->inventory[INVEN_WIELD];
- if (object_known_p(o_ptr)) dambonus += o_ptr->to_d;
+ dambonus += o_ptr->to_d;
damdice = o_ptr->dd;
damsides = o_ptr->ds;
@@ -1568,18 +1514,29 @@ static object_flag_set wield_monster_flags()
/* Get the carried monster */
auto o_ptr = &p_ptr->inventory[INVEN_CARRY];
- if (o_ptr->k_idx)
+ if (o_ptr->k_ptr)
{
auto r_ptr = &r_info[o_ptr->pval];
if (r_ptr->flags & RF_INVISIBLE)
+ {
flags |= TR_INVIS;
+ }
+
if (r_ptr->flags & RF_REFLECTING)
+ {
flags |= TR_REFLECT;
+ }
+
if (r_ptr->flags & RF_CAN_FLY)
+ {
flags |= TR_FEATHER;
+ }
+
if (r_ptr->flags & RF_AQUATIC)
+ {
flags |= TR_WATER_BREATH;
+ }
}
return flags;
@@ -1672,14 +1629,12 @@ object_flag_set player_flags()
{
f |= TR_RES_NETHER;
- if ((p_ptr->grace > 10000) &&
- (p_ptr->praying == TRUE))
+ if (p_ptr->praying && (p_ptr->grace > 10000))
{
f |= TR_NO_TELE;
}
- if ((p_ptr->grace > 20000) &&
- (p_ptr->praying == TRUE))
+ if (p_ptr->praying && (p_ptr->grace > 20000))
{
f |= TR_IM_NETHER;
}
@@ -1689,14 +1644,12 @@ object_flag_set player_flags()
{
f |= TR_WATER_BREATH;
- if ((p_ptr->grace > 1000) &&
- (p_ptr->praying == TRUE))
+ if (p_ptr->praying && (p_ptr->grace > 1000))
{
f |= TR_RES_POIS;
}
- if ((p_ptr->grace > 15000) &&
- (p_ptr->praying == TRUE))
+ if (p_ptr->praying && (p_ptr->grace > 15000))
{
f |= TR_MAGIC_BREATH;
}
@@ -2392,8 +2345,8 @@ std::string describe_player_location()
*/
int dx = pwx - lwx;
int dy = pwy - lwy;
- cptr ns = (dy > 0 ? "south" : "north");
- cptr ew = (dx > 0 ? "east" : "west");
+ const char *ns = (dy > 0 ? "south" : "north");
+ const char *ew = (dx > 0 ? "east" : "west");
dx = (dx < 0 ? -dx : dx);
dy = (dy < 0 ? -dy : dy);
@@ -2410,7 +2363,7 @@ std::string describe_player_location()
}
/* Strip trailing whitespace */
- boost::trim_right(desc);
+ trim_right(desc);
return desc;
}
@@ -2420,20 +2373,20 @@ std::string describe_player_location()
*
* Figure out if a row on the grid is empty
*/
-static bool_ file_character_print_grid_check_row(const char *buf)
+static bool file_character_print_grid_check_row(const char *buf)
{
- if (strstr(buf + 12, "+")) return TRUE;
- if (strstr(buf + 12, "*")) return TRUE;
- if (strstr(buf + 12, "1")) return TRUE;
- if (strstr(buf + 12, "2")) return TRUE;
- if (strstr(buf + 12, "3")) return TRUE;
- if (strstr(buf + 12, "4")) return TRUE;
- if (strstr(buf + 12, "5")) return TRUE;
- if (strstr(buf + 12, "6")) return TRUE;
- if (strstr(buf + 12, "7")) return TRUE;
- if (strstr(buf + 12, "8")) return TRUE;
- if (strstr(buf + 12, "9")) return TRUE;
- return FALSE;
+ if (strstr(buf + 12, "+")) return true;
+ if (strstr(buf + 12, "*")) return true;
+ if (strstr(buf + 12, "1")) return true;
+ if (strstr(buf + 12, "2")) return true;
+ if (strstr(buf + 12, "3")) return true;
+ if (strstr(buf + 12, "4")) return true;
+ if (strstr(buf + 12, "5")) return true;
+ if (strstr(buf + 12, "6")) return true;
+ if (strstr(buf + 12, "7")) return true;
+ if (strstr(buf + 12, "8")) return true;
+ if (strstr(buf + 12, "9")) return true;
+ return false;
}
/*
@@ -2441,9 +2394,9 @@ static bool_ file_character_print_grid_check_row(const char *buf)
*
* Prints the big ugly grid
*/
-static void file_character_print_grid(FILE *fff, bool_ show_gaps, bool_ show_legend)
+static void file_character_print_grid(FILE *fff, bool show_gaps, bool show_legend)
{
- static cptr blank_line = " ";
+ static const char *blank_line = " ";
static char buf[1024];
byte a;
char c;
@@ -2454,12 +2407,12 @@ static void file_character_print_grid(FILE *fff, bool_ show_gaps, bool_ show_leg
{
for (x = 0; x < 40; x++)
{
- (Term_what(x, y, &a, &c));
+ Term_what(x, y, &a, &c);
buf[x] = c;
}
buf[x] = '\0';
- if (strcmp(buf, blank_line) &&
+ if (!equals(buf, blank_line) &&
(y == 3 || show_gaps || file_character_print_grid_check_row(buf)))
fprintf (fff, " %s\n", buf);
}
@@ -2467,12 +2420,12 @@ static void file_character_print_grid(FILE *fff, bool_ show_gaps, bool_ show_leg
{
for (x = 40; x < 80; x++)
{
- (Term_what(x, y, &a, &c));
+ Term_what(x, y, &a, &c);
buf[x - 40] = c;
}
buf[x] = '\0';
- if (strcmp(buf, blank_line) &&
+ if (!equals(buf, blank_line) &&
(show_gaps || file_character_print_grid_check_row(buf)))
fprintf (fff, " %s\n", buf);
}
@@ -2483,18 +2436,14 @@ static void file_character_print_grid(FILE *fff, bool_ show_gaps, bool_ show_leg
*
* Outputs one item (for Inventory, Equipment, Home, and Mathom-house)
*/
-void file_character_print_item(FILE *fff, char label, object_type *obj, bool_ full)
+static void file_character_print_item(FILE *fff, char label, object_type *obj)
{
static char o_name[80];
- static cptr paren = ")";
- object_desc(o_name, obj, TRUE, 3);
- fprintf(fff, "%c%s %s\n", label, paren, o_name);
+ static const char *paren = ")";
- if ((artifact_p(obj) || ego_item_p(obj) || obj->tval == TV_RING || obj->tval == TV_AMULET || full) &&
- (obj->ident & IDENT_MENTAL))
- {
- object_out_desc(obj, fff, TRUE, TRUE);
- }
+ object_desc(o_name, obj, true, 3);
+ fprintf(fff, "%c%s %s\n", label, paren, o_name);
+ object_out_desc(obj, fff, true, true);
}
/*
@@ -2502,7 +2451,7 @@ void file_character_print_item(FILE *fff, char label, object_type *obj, bool_ fu
*
* Prints out one "store" (for Home and Mathom-house)
*/
-static void file_character_print_store(FILE *fff, wilderness_type_info const *place, std::size_t store, bool_ full)
+static void file_character_print_store(FILE *fff, wilderness_type_info const *place, std::size_t store)
{
auto const &st_info = game->edit_data.st_info;
@@ -2517,7 +2466,7 @@ static void file_character_print_store(FILE *fff, wilderness_type_info const *pl
/* Dump all available items */
for (std::size_t i = 0; i < st_ptr->stock.size(); i++)
{
- file_character_print_item(fff, I2A(i%24), &st_ptr->stock[i], full);
+ file_character_print_item(fff, I2A(i%24), &st_ptr->stock[i]);
}
/* Add an empty line */
@@ -2532,7 +2481,7 @@ static void file_character_print_store(FILE *fff, wilderness_type_info const *pl
* was not already there. XXX This is an ugly workaround for the double Gondolin
* problem.
*/
-static bool_ file_character_check_stores(std::unordered_set<store_type *> *seen_stores, wilderness_type_info const *place, int store)
+static bool file_character_check_stores(std::unordered_set<store_type *> *seen_stores, wilderness_type_info const *place, int store)
{
town_type *town = &town_info[place->entrance];
store_type *st_ptr = &town->store[store];
@@ -2540,12 +2489,12 @@ static bool_ file_character_check_stores(std::unordered_set<store_type *> *seen_
// Already seen store?
if (seen_stores->find(st_ptr) != seen_stores->end())
{
- return FALSE;
+ return false;
}
// Add
seen_stores->insert(st_ptr);
- return TRUE;
+ return true;
}
/*
@@ -2554,7 +2503,7 @@ static bool_ file_character_check_stores(std::unordered_set<store_type *> *seen_
* XXX XXX XXX Allow the "full" flag to dump additional info,
* and trigger its usage from various places in the code.
*/
-errr file_character(cptr name, bool_ full)
+errr file_character(const char *name)
{
auto const &d_info = game->edit_data.d_info;
auto const &wf_info = game->edit_data.wf_info;
@@ -2617,7 +2566,7 @@ errr file_character(cptr name, bool_ full)
for (x = 0; x < 79; x++)
{
/* Get the attr/char */
- (Term_what(x, y, &a, &c));
+ Term_what(x, y, &a, &c);
/* Dump it */
buf[x] = c;
@@ -2640,7 +2589,7 @@ errr file_character(cptr name, bool_ full)
for (x = 0; x < 79; x++)
{
/* Get the attr/char */
- (Term_what(x, y, &a, &c));
+ Term_what(x, y, &a, &c);
/* Dump it */
buf[x] = c;
@@ -2705,7 +2654,7 @@ errr file_character(cptr name, bool_ full)
{
char desc[80];
- cptr mimic;
+ const char *mimic;
monster_race_desc(desc, p_ptr->body_monster, 0);
fprintf(fff, "\n Your body %s %s.", (death ? "was" : "is"), desc);
@@ -2733,7 +2682,7 @@ errr file_character(cptr name, bool_ full)
if (r_ptr->flags & RF_UNIQUE)
{
- bool_ dead = (r_ptr->max_num == 0);
+ bool dead = (r_ptr->max_num == 0);
if (dead)
{
Total++;
@@ -2772,19 +2721,19 @@ errr file_character(cptr name, bool_ full)
/* adds and slays */
display_player(1);
- file_character_print_grid(fff, FALSE, TRUE);
+ file_character_print_grid(fff, false, true);
/* sustains and resistances */
display_player(2);
- file_character_print_grid(fff, TRUE, FALSE);
+ file_character_print_grid(fff, true, false);
/* stuff */
display_player(3);
- file_character_print_grid(fff, FALSE, FALSE);
+ file_character_print_grid(fff, false, false);
/* a little bit of stuff */
display_player(4);
- file_character_print_grid(fff, FALSE, FALSE);
+ file_character_print_grid(fff, false, false);
/* Dump corruptions */
fprintf(fff, "\n%s\n", dump_corruptions(false, true).c_str());
@@ -2827,7 +2776,7 @@ errr file_character(cptr name, bool_ full)
{
if (!p_ptr->body_parts[i - INVEN_WIELD]) continue;
- file_character_print_item(fff, index_to_label(i), &p_ptr->inventory[i], full);
+ file_character_print_item(fff, index_to_label(i), &p_ptr->inventory[i]);
}
fprintf(fff, "\n\n");
}
@@ -2836,7 +2785,7 @@ errr file_character(cptr name, bool_ full)
fprintf(fff, " [Character Inventory]\n\n");
for (i = 0; i < INVEN_PACK; i++)
{
- file_character_print_item(fff, index_to_label(i), &p_ptr->inventory[i], full);
+ file_character_print_item(fff, index_to_label(i), &p_ptr->inventory[i]);
}
fprintf(fff, "\n\n");
@@ -2848,7 +2797,7 @@ errr file_character(cptr name, bool_ full)
if (wf_ref.feat == FEAT_TOWN &&
file_character_check_stores(&seen_stores, &wf_ref, 7))
{
- file_character_print_store(fff, &wf_ref, 7, full);
+ file_character_print_store(fff, &wf_ref, 7);
}
}
}
@@ -2861,7 +2810,7 @@ errr file_character(cptr name, bool_ full)
if (wf_ref.feat == FEAT_TOWN &&
file_character_check_stores(&seen_stores, &wf_ref, 57))
{
- file_character_print_store(fff, &wf_ref, 57, full);
+ file_character_print_store(fff, &wf_ref, 57);
}
}
}
@@ -2884,7 +2833,7 @@ errr file_character(cptr name, bool_ full)
/*
* Recursive file perusal.
*
- * Return FALSE on "ESCAPE", otherwise TRUE.
+ * Return false on "ESCAPE", otherwise true.
*
* Process various special text in the input file, including
* the "menu" structures used by the "help file" system.
@@ -2923,7 +2872,7 @@ struct hyperlink
typedef struct hyperlink hyperlink_type;
-static bool_ show_file_aux(cptr name, cptr what, int line)
+static bool show_file_aux(const char *name, const char *what, int line)
{
int i, k, x;
@@ -2942,13 +2891,13 @@ static bool_ show_file_aux(cptr name, cptr what, int line)
byte color = TERM_WHITE;
/* This screen has sub-screens */
- bool_ menu = FALSE;
+ bool menu = false;
/* Current help file */
FILE *fff = NULL;
/* Find this string (if any) */
- cptr find = NULL;
+ const char *find = NULL;
/* Pointer to general buffer in the above */
char *buf;
@@ -3031,32 +2980,32 @@ static bool_ show_file_aux(cptr name, cptr what, int line)
msg_print(NULL);
/* Oops */
- return (TRUE);
+ return true;
}
/* Pre-Parse the file */
- while (TRUE)
+ while (true)
{
/* Read a line or stop */
if (my_fgets(fff, h_ptr->rbuf, 1024)) break;
/* Get a color */
- if (prefix(h_ptr->rbuf, "#####"))
+ if (starts_with(h_ptr->rbuf, "#####"))
{
buf = &h_ptr->rbuf[6];
}
else buf = h_ptr->rbuf;
/* Get the link colors */
- if (prefix(buf, "|||||"))
+ if (starts_with(buf, "|||||"))
{
link_color = color_char_to_attr(buf[5]);
link_color_sel = color_char_to_attr(buf[6]);
}
/* Tag ? */
- if (prefix(buf, "~~~~~"))
+ if (starts_with(buf, "~~~~~"))
{
if (line < 0)
{
@@ -3080,7 +3029,7 @@ static bool_ show_file_aux(cptr name, cptr what, int line)
while (buf[x])
{
/* Hyperlink ? */
- if (prefix(buf + x, "*****"))
+ if (starts_with(buf + x, "*****"))
{
int xx = x + 5, stmp, xdeb = x + 5, z;
char tmp[20];
@@ -3134,7 +3083,7 @@ static bool_ show_file_aux(cptr name, cptr what, int line)
/* Display the file */
- while (TRUE)
+ while (true)
{
/* Clear screen */
Term_clear();
@@ -3157,7 +3106,7 @@ static bool_ show_file_aux(cptr name, cptr what, int line)
/* Oops */
if (!fff)
{
- return (FALSE);
+ return false;
}
/* File has been restarted */
@@ -3184,7 +3133,7 @@ static bool_ show_file_aux(cptr name, cptr what, int line)
if (my_fgets(fff, h_ptr->rbuf, 1024)) break;
/* Get a color */
- if (prefix(h_ptr->rbuf, "#####"))
+ if (starts_with(h_ptr->rbuf, "#####"))
{
color = color_char_to_attr(h_ptr->rbuf[5]);
buf = &h_ptr->rbuf[6];
@@ -3195,10 +3144,10 @@ static bool_ show_file_aux(cptr name, cptr what, int line)
next++;
/* Skip link colors */
- if (prefix(buf, "|||||")) continue;
+ if (starts_with(buf, "|||||")) continue;
/* Skip tags */
- if (prefix(buf, "~~~~~"))
+ if (starts_with(buf, "~~~~~"))
{
i++;
continue;
@@ -3228,13 +3177,13 @@ static bool_ show_file_aux(cptr name, cptr what, int line)
/* Dump the line */
print_x = 0;
- if (!prefix(buf, "&&&&&"))
+ if (!starts_with(buf, "&&&&&"))
{
x = 0;
while (buf[x])
{
/* Hyperlink ? */
- if (prefix(buf + x, "*****"))
+ if (starts_with(buf + x, "*****"))
{
int xx = x + 5;
@@ -3263,7 +3212,7 @@ static bool_ show_file_aux(cptr name, cptr what, int line)
x = xx;
}
/* Color ? */
- else if (prefix(buf + x, "[[[[["))
+ else if (starts_with(buf + x, "[[[[["))
{
int xx = x + 6;
@@ -3280,7 +3229,7 @@ static bool_ show_file_aux(cptr name, cptr what, int line)
x = xx;
}
/* Remove HTML ? */
- else if (prefix(buf + x, "{{{{{"))
+ else if (starts_with(buf + x, "{{{{{"))
{
int xx = x + 6;
@@ -3316,7 +3265,7 @@ static bool_ show_file_aux(cptr name, cptr what, int line)
/* Hilite "h_ptr->shower" */
if (h_ptr->shower[0])
{
- cptr str = buf;
+ const char *str = buf;
/* Display matches */
while ((str = strstr(str, h_ptr->shower)) != NULL)
@@ -3498,16 +3447,16 @@ static bool_ show_file_aux(cptr name, cptr what, int line)
my_fclose(fff);
/* Escape */
- if (k == ESCAPE) return (FALSE);
+ if (k == ESCAPE) return false;
/* Normal return */
- return (TRUE);
+ return true;
}
void show_string(const char *lines, const char *title, int line)
{
// Temporary file
- auto const file_name = boost::filesystem::unique_path().string();
+ auto const file_name = fs::unique_path().string();
// Open a new file
std::ofstream ofs(file_name);
@@ -3522,19 +3471,13 @@ void show_string(const char *lines, const char *title, int line)
fd_kill(file_name.c_str());
}
-void show_file(cptr name, cptr what, int line)
+void show_file(const char *name, const char *what, int line)
{
show_file_aux(name, what, line);
}
static void cmovie_clean_line(int y, char *abuf, char *cbuf)
{
- const byte *ap = Term->scr->a[y];
- const char *cp = Term->scr->c[y];
-
- byte a;
- char c;
-
int x;
int wid, hgt;
int screen_wid, screen_hgt;
@@ -3558,18 +3501,30 @@ static void cmovie_clean_line(int y, char *abuf, char *cbuf)
((y - ROW_MAP) < screen_hgt))
{
/* Retrieve default attr/char */
+ byte a;
+ char c;
map_info_default(y + panel_row_prt, x + panel_col_prt, &a, &c);
abuf[x] = conv_color[a & 0xf];
- if (c == '\0') cbuf[x] = ' ';
- else cbuf[x] = c;
+ if (c == '\0')
+ {
+ cbuf[x] = ' ';
+ }
+ else
+ {
+ cbuf[x] = c;
+ }
}
else
{
- abuf[x] = conv_color[ap[x] & 0xf];
- cbuf[x] = cp[x];
+ byte a;
+ char c;
+ Term_what(x, y, &a, &c);
+
+ abuf[x] = conv_color[a & 0xf];
+ cbuf[x] = c;
}
}
@@ -3579,7 +3534,7 @@ static void cmovie_clean_line(int y, char *abuf, char *cbuf)
}
/* Take an help file screenshot(yes yes I know..) */
-void help_file_screenshot(cptr name)
+void help_file_screenshot(const char *name)
{
int y, x;
int wid, hgt;
@@ -3632,7 +3587,7 @@ void help_file_screenshot(cptr name)
}
/* Take an html screenshot */
-void html_screenshot(cptr name)
+void html_screenshot(const char *name)
{
int y, x;
int wid, hgt;
@@ -3733,31 +3688,26 @@ void do_cmd_help()
-void process_player_base()
-{
- path_build(savefile, 1024, ANGBAND_DIR_SAVE, game->player_base.c_str());
-}
-
-void process_player_name(bool_ sf)
+std::string process_player_name(std::string const &name)
{
/* Cannot be too long */
- if (game->player_base.size() > 15)
+ if (name.size() > 15)
{
- quit_fmt("The name '%s' is too long!", game->player_base.c_str());
+ quit_fmt("The name '%s' is too long!", name.c_str());
}
/* Cannot contain control characters */
- for (auto c : game->player_base)
+ for (auto c : name)
{
if (iscntrl(c))
{
- quit_fmt("The name '%s' contains control chars!", game->player_base.c_str());
+ quit_fmt("The name '%s' contains control chars!", name.c_str());
}
}
/* Extract "useful" letters */
std::string buf;
- for (auto c : game->player_base)
+ for (auto c : name)
{
/* Accept some letters */
if (isalpha(c) || isdigit(c))
@@ -3772,20 +3722,22 @@ void process_player_name(bool_ sf)
}
}
- /* Terminate */
- game->player_base = buf;
-
/* Require a "base" name */
- if (game->player_base.empty())
+ if (buf.empty())
{
- game->player_base = "PLAYER";
+ buf = "PLAYER";
}
- /* Change the savefile name */
- if (sf)
- {
- process_player_base();
- }
+ /* Terminate */
+ return buf;
+}
+
+
+
+
+void set_player_base(std::string const &name)
+{
+ game->player_base = process_player_name(name);
}
@@ -3801,8 +3753,6 @@ void process_player_name(bool_ sf)
*/
void get_name()
{
- char tmp[32];
-
/* Clear last line */
clear_from(22);
@@ -3810,28 +3760,27 @@ void get_name()
prt("[Enter your player's name above, or hit ESCAPE]", 23, 2);
/* Ask until happy */
- while (1)
+ while (true)
{
/* Go to the "name" field */
- move_cursor(2, 9);
+ Term_gotoxy(9, 2);
/* Save the player name */
- strcpy(tmp, game->player_name.c_str());
+ auto tmp = game->player_name;
/* Get an input, ignore "Escape" */
- if (askfor_aux(tmp, 31))
+ if (askfor_aux(&tmp, 31))
{
game->player_name = tmp;
+ set_player_base(tmp);
}
- /* Process the player name */
- process_player_name(FALSE);
-
/* All done */
break;
}
/* Pad the name (to clear junk) */
+ char tmp[32];
sprintf(tmp, "%-31.31s", game->player_name.c_str());
/* Re-Draw the name (in light blue) */
@@ -3878,13 +3827,13 @@ void do_cmd_suicide()
}
/* Stop playing */
- alive = FALSE;
+ alive = false;
/* Kill the player */
- death = TRUE;
+ death = true;
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
/* Cause of death */
game->died_from = "Quitting";
@@ -3896,7 +3845,7 @@ void do_cmd_suicide()
* when the game is loaded again
* Alternatively forget_view() and update_view() can be used
*/
-void remove_cave_view(bool_ remove)
+void remove_cave_view(bool remove)
{
int i;
cave_type *c_ptr;
@@ -3925,7 +3874,7 @@ void remove_cave_view(bool_ remove)
*/
void do_cmd_save_game()
{
- remove_cave_view(TRUE);
+ remove_cave_view(true);
/* Save the current level if in a persistent level */
save_dungeon();
@@ -3964,7 +3913,7 @@ void do_cmd_save_game()
prt("Saving game... failed!", 0, 0);
}
- remove_cave_view(FALSE);
+ remove_cave_view(false);
/* Refresh */
Term_fresh();
@@ -3980,10 +3929,10 @@ void autosave_checkpoint()
{
if (options->autosave_l)
{
- is_autosave = TRUE;
+ is_autosave = true;
msg_print("Autosaving the game...");
do_cmd_save_game();
- is_autosave = FALSE;
+ is_autosave = false;
}
}
@@ -3994,7 +3943,6 @@ static long total_points()
{
auto const &d_info = game->edit_data.d_info;
auto const &r_info = game->edit_data.r_info;
- auto const &k_info = game->edit_data.k_info;
s16b max_dl = 0;
long temp, Total = 0;
@@ -4043,37 +3991,13 @@ static long total_points()
/* Death of a companion is BAD */
temp /= comp_death;
- /* The known objects increase the score */
- for (std::size_t k = 1; k < k_info.size(); k++)
- {
- auto k_ptr = &k_info[k];
-
- /* Hack -- skip artifacts */
- if (k_ptr->flags & TR_INSTA_ART) continue;
-
- /* List known flavored objects */
- if (k_ptr->flavor && k_ptr->aware)
- {
- object_type *i_ptr;
- object_type object_type_body;
-
- /* Get local object */
- i_ptr = &object_type_body;
-
- /* Create fake object */
- object_prep(i_ptr, k);
-
- temp += object_value_real(i_ptr);
- }
- }
-
for (auto const &r_ref: r_info)
{
auto r_ptr = &r_ref;
if (r_ptr->flags & RF_UNIQUE)
{
- bool_ dead = (r_ptr->max_num == 0);
+ bool dead = (r_ptr->max_num == 0);
if (dead)
{
@@ -4166,36 +4090,6 @@ static void print_tomb()
*/
static void show_info()
{
- /* Hack -- Know everything in the inven/equip */
- for (auto &o_ref: p_ptr->inventory)
- {
- auto o_ptr = &o_ref;
-
- /* Skip non-objects */
- if (!o_ptr->k_idx) continue;
-
- /* Aware and Known */
- object_aware(o_ptr);
- object_known(o_ptr);
- }
-
- /* Hack -- Know everything in the home */
- for (int i = 1; i < max_towns; i++)
- {
- auto st_ptr = &town_info[i].store[7];
- for (auto &o_ref: st_ptr->stock)
- {
- auto o_ptr = &o_ref;
-
- /* Skip non-objects */
- if (!o_ptr->k_idx) continue;
-
- /* Aware and Known */
- object_aware(o_ptr);
- object_known(o_ptr);
- }
- }
-
/* Hack -- Recalculate bonuses */
p_ptr->update |= (PU_BONUS);
@@ -4214,7 +4108,7 @@ static void show_info()
prt("Then, hit RETURN to see the character, or ESC to abort.", 22, 0);
/* Dump character records as requested */
- while (TRUE)
+ while (true)
{
char out_val[160];
@@ -4231,15 +4125,13 @@ static void show_info()
if (!out_val[0]) break;
/* Save screen */
- character_icky = TRUE;
- Term_save();
+ screen_save_no_flush();
/* Dump a character file */
- file_character(out_val, TRUE);
+ file_character(out_val);
/* Load screen */
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
}
@@ -4302,7 +4194,7 @@ static void show_info()
prt(tmp_val, j + 2, 4);
/* Display object description */
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
c_put_str(tval_to_attr[o_ptr->tval], o_name, j + 2, 7);
}
@@ -4385,7 +4277,9 @@ static void display_scores_aux(int highscore_fd, int from, int to, int note, hig
{
int pcs, pr, ps, pc, clev, mlev, cdun, mdun;
- cptr gold, when, aged;
+ const char *gold;
+ const char *when;
+ const char *aged;
int in_quest;
@@ -4946,7 +4840,7 @@ out:
}
-void predict_score_gui(bool_ *initialized_p, bool_ *game_in_progress_p)
+void predict_score_gui(bool *initialized_p, bool *game_in_progress_p)
{
char buf[1024];
int highscore_fd;
@@ -4974,7 +4868,7 @@ void predict_score_gui(bool_ *initialized_p, bool_ *game_in_progress_p)
}
/* Mega-Hack - prevent various functions XXX XXX XXX */
- *initialized_p = FALSE;
+ *initialized_p = false;
/* Save screen */
screen_save();
@@ -5001,7 +4895,7 @@ void predict_score_gui(bool_ *initialized_p, bool_ *game_in_progress_p)
Term_fresh();
/* Mega-Hack - We are ready again */
- *initialized_p = TRUE;
+ *initialized_p = true;
}
@@ -5073,19 +4967,12 @@ void wipe_saved()
for (auto l = d_ptr->mindepth; l <= d_ptr->maxdepth; l++)
{
- char buf[10];
-
dun_level = l;
dungeon_type = d;
- if (get_dungeon_save(buf))
+ if (auto ext = get_dungeon_save_extension())
{
- auto tmp = fmt::format("{}.{}", game->player_base, buf);
-
- char name[1024];
- path_build(name, 1024, ANGBAND_DIR_SAVE, tmp.c_str());
-
/* Remove the dungeon save file */
- fd_kill(name);
+ fd_kill(name_file_dungeon_save(*ext).c_str());
}
}
}
@@ -5113,7 +5000,7 @@ void close_game()
/* Hack -- Character is now "icky" */
- character_icky = TRUE;
+ character_icky = true;
/* Handle death */
@@ -5166,7 +5053,7 @@ void close_game()
/* Still alive */
else
{
- is_autosave = FALSE;
+ is_autosave = false;
/* Save the game */
do_cmd_save_game();
@@ -5263,7 +5150,7 @@ errr get_rnd_line(const char *file_name, char *output)
*
* Caution: 'linbuf' should be at least 80 byte long.
*/
-char *get_line(const char* fname, cptr fdir, char *linbuf, int line)
+char *get_line(const char* fname, const char *fdir, char *linbuf, int line)
{
FILE* fp;
int i;
@@ -5343,7 +5230,7 @@ errr get_xtra_line(const char *file_name, monster_type *m_ptr, char *output)
mnum = m_ptr->r_idx;
/* Find matching N: line */
- while (1)
+ while (true)
{
int n;
@@ -5365,7 +5252,7 @@ errr get_xtra_line(const char *file_name, monster_type *m_ptr, char *output)
}
/* Retrieve number of normal messages */
- while (1)
+ while (true)
{
/* Read next line */
if (my_fgets(fp, buf, 90) != 0)
diff --git a/src/files.h b/src/files.h
deleted file mode 100644
index 78521f4c..00000000
--- a/src/files.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include "h-basic.h"
-
-// C linkage required for these functions since main-* code uses them.
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void do_cmd_save_game();
-void predict_score_gui(bool_ *initialized, bool_ *game_in_progress);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/src/files.hpp b/src/files.hpp
index f431eb69..e3e8154a 100644
--- a/src/files.hpp
+++ b/src/files.hpp
@@ -1,33 +1,45 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "monster_type_fwd.hpp"
#include "object_flag_set.hpp"
+#include <boost/filesystem.hpp>
#include <string>
+#include <string_view>
#include <vector>
-void html_screenshot(cptr name);
-void help_file_screenshot(cptr name);
+std::string name_file_note(std::string_view);
+std::string name_file_pref(std::string_view);
+std::string name_file_save();
+std::string name_file_save(std::string_view);
+
+boost::filesystem::path name_file_dungeon_save(std::string const &ext);
+
+void html_screenshot(const char *name);
+void help_file_screenshot(const char *name);
object_flag_set player_flags();
void wipe_saved();
s16b tokenize(char *buf, s16b num, char **tokens, char delim1, char delim2);
void display_player(int mode);
std::string describe_player_location();
-errr file_character(cptr name, bool_ full);
+errr file_character(const char *name);
errr process_pref_file_aux(char *buf);
-errr process_pref_file(cptr name);
+errr process_pref_file(std::string const &name);
void show_string(const char *lines, const char *title, int line = 0);
-void show_file(cptr name, cptr what, int line = 0);
+void show_file(const char *name, const char *what, int line = 0);
void do_cmd_help();
-void process_player_base();
void get_name();
void do_cmd_suicide();
void autosave_checkpoint();
void close_game();
errr get_rnd_line(const char * file_name, char * output);
-char *get_line(const char* fname, cptr fdir, char *linbuf, int line);
+char *get_line(const char* fname, const char *fdir, char *linbuf, int line);
void race_legends();
void show_highclass(int building);
errr get_xtra_line(const char * file_name, monster_type *m_ptr, char * output);
-void process_player_name(bool_ sf);
+std::string process_player_name(std::string const &);
+void set_player_base(std::string const &name);
+
+void do_cmd_save_game();
+void predict_score_gui(bool *initialized, bool *game_in_progress);
diff --git a/src/flag_set.hpp b/src/flag_set.hpp
index 7960de42..570166b6 100644
--- a/src/flag_set.hpp
+++ b/src/flag_set.hpp
@@ -23,9 +23,6 @@ public:
constexpr flag_set()
: m_data { 0 }
{
- // It is *extremely* important that there are absolutely
- // NO dependencies on any global objects in here; lest we
- // fall into SIOF territory; see DECLARE_FLAG_ZERO_IMPL
}
// This method is a workaround for a a segmentation fault
@@ -187,15 +184,3 @@ public:
*/
#define DECLARE_FLAG(type, name, tier, index) \
PP_GLOBAL_CONSTEXPR_CONST(type, name, DECLARE_FLAG_MAKE_INIT(type, tier, index))
-
-/**
- * Macro for declaring a zero'ed "flag" variable.
- */
-#define DECLARE_FLAG_ZERO_INTF(type, name) \
- extern type name
-
-/**
- * Macro for declaring the implementation of a zero'ed "flag" variable.
- */
-#define DECLARE_FLAG_ZERO_IMPL(type, name) \
- type name { };
diff --git a/src/flags_group.hpp b/src/flags_group.hpp
index 84809e37..f523271c 100644
--- a/src/flags_group.hpp
+++ b/src/flags_group.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_flag_set.hpp"
/**
diff --git a/src/format_ext.cc b/src/format_ext.cc
new file mode 100644
index 00000000..0eef9148
--- /dev/null
+++ b/src/format_ext.cc
@@ -0,0 +1,24 @@
+#include "format_ext.hpp"
+
+#include "util.hpp"
+
+void singular_prefix::write(fmt::Writer &w) const
+{
+ assert(!m_s.empty());
+
+ if (is_a_vowel(m_s[0]))
+ {
+ w.write("an ");
+ }
+ else
+ {
+ w.write("a ");
+ }
+
+ w.write(m_s);
+}
+
+void format_arg(fmt::BasicFormatter<char> &formatter, const char *&format_str, const singular_prefix &sp)
+{
+ sp.write(formatter.writer());
+}
diff --git a/src/format_ext.hpp b/src/format_ext.hpp
new file mode 100644
index 00000000..e0084e2f
--- /dev/null
+++ b/src/format_ext.hpp
@@ -0,0 +1,33 @@
+#include <utility>
+
+#pragma once
+
+#include <fmt/format.h>
+#include <string>
+
+struct singular_prefix {
+
+private:
+ std::string m_s;
+
+ friend void format_arg(fmt::BasicFormatter<char> &formatter, const char *&format_str, const singular_prefix &sp);
+
+public:
+ explicit singular_prefix(std::string s)
+ : m_s(std::move(s))
+ {
+ }
+
+ explicit singular_prefix(std::string &&s)
+ : m_s(std::move(s))
+ {
+ }
+
+ void write(fmt::Writer &w) const;
+
+};
+
+//
+// Formatting support for fmtlib
+//
+void format_arg(fmt::BasicFormatter<char> &formatter, const char *&format_str, const singular_prefix &sp);
diff --git a/src/frontend.cc b/src/frontend.cc
new file mode 100644
index 00000000..2194ff21
--- /dev/null
+++ b/src/frontend.cc
@@ -0,0 +1 @@
+#include "frontend.hpp"
diff --git a/src/frontend.hpp b/src/frontend.hpp
new file mode 100644
index 00000000..b0861906
--- /dev/null
+++ b/src/frontend.hpp
@@ -0,0 +1,107 @@
+#pragma once
+
+#include "frontend_fwd.hpp"
+
+#include <string_view>
+
+#include "h-basic.hpp"
+
+/**
+ * User interface operations supported by the front end.
+ */
+class Frontend {
+
+public:
+ /**
+ * Result polling/waiting for an event.
+ */
+ enum class event_result_t {
+ SUCCESS,
+ FAILURE,
+ };
+
+ /**
+ * Initialize the underlying user interface element.
+ */
+ virtual void init() = 0;
+
+ /**
+ * Destroy the underlying user interface element.
+ */
+ virtual void nuke() = 0;
+
+ /**
+ * Poll or wait for event and process it.
+ */
+ virtual void process_event(bool wait) = 0;
+
+ /**
+ * Does this user interface draw its own cursor?
+ *
+ * The return value is assumed to be constant over the
+ * lifetime of the user interface.
+ */
+ virtual bool soft_cursor() const = 0;
+
+ /**
+ * Does this user interface have an "icky" lower right corner,
+ * i.e. does it _not_ support putting the cursor in that corner?
+ *
+ * The return value is assumed to be constant over the
+ * lifetime of the user interface.
+ */
+ virtual bool icky_corner() const = 0;
+
+ /**
+ * Flush any pending events.
+ */
+ virtual void flush_events() = 0;
+
+ /**
+ * Process any pending events.
+ */
+ virtual void process_queued_events() = 0;
+
+ /**
+ * Clear contents of the user interface.
+ */
+ virtual void clear() = 0;
+
+ /**
+ * Flush pending output.
+ */
+ virtual void flush_output() = 0;
+
+ /**
+ * Make a noise, e.g. a system beep or similar.
+ */
+ virtual void noise() = 0;
+
+ /**
+ * React to changes generated by the game, e.g. window
+ * size, or colors.
+ */
+ virtual void react() = 0;
+
+ /**
+ * Rename the main window.
+ */
+ virtual void rename_main_window(std::string_view) = 0;
+
+ /**
+ * Draw the cursor at position x, y.
+ */
+ virtual void draw_cursor(int x, int y) = 0;
+
+ /**
+ * Draw the given text string s at position x, y
+ * using attributes a.
+ */
+ virtual void draw_text(int x, int y, int n, byte a, const char *s) = 0;
+
+ /**
+ * Destroy.
+ */
+ virtual ~Frontend() = default;
+
+};
diff --git a/src/frontend_fwd.hpp b/src/frontend_fwd.hpp
new file mode 100644
index 00000000..925cfa5e
--- /dev/null
+++ b/src/frontend_fwd.hpp
@@ -0,0 +1,3 @@
+ #pragma once
+
+class Frontend;
diff --git a/src/game.cc b/src/game.cc
index 284c9ccc..220c18cf 100644
--- a/src/game.cc
+++ b/src/game.cc
@@ -1,3 +1,759 @@
#include "game.hpp"
+#include <stats.hpp>
+
Game *game;
+
+/**
+ * Default constructor
+ */
+Game::Game()
+{
+ // Initialize the available player powers
+ powers = std::unordered_map<int, std::shared_ptr<power_type>> {
+ {
+ PWR_SPIT_ACID,
+ std::make_shared<power_type>(
+ "spit acid",
+ "You can spit acid.",
+ "You gain the ability to spit acid.",
+ "You lose the ability to spit acid.",
+ power_activation {
+ 9, 9, A_DEX, 15
+ }
+ ),
+ },
+ {
+ PWR_BR_FIRE,
+ std::make_shared<power_type>(
+ "fire breath",
+ "You can breath fire.",
+ "You gain the ability to breathe fire.",
+ "You lose the ability to breathe fire.",
+ power_activation {
+ 20, 10, A_CON, 18
+ }
+ ),
+ },
+ {
+ PWR_HYPN_GAZE,
+ std::make_shared<power_type>(
+ "hypnotic gaze",
+ "Your gaze is hypnotic.",
+ "Your eyes look mesmerising...",
+ "Your eyes look uninteresting.",
+ power_activation {
+ 12, 12, A_CHR, 18
+ }
+ ),
+ },
+ {
+ PWR_TELEKINES,
+ std::make_shared<power_type>(
+ "telekinesis",
+ "You are telekinetic.",
+ "You gain the ability to move objects telekinetically.",
+ "You lose the ability to move objects telekinetically.",
+ power_activation {
+ 9, 9, A_WIS, 14
+ }
+ ),
+ },
+ {
+ PWR_VTELEPORT,
+ std::make_shared<power_type>(
+ "teleport",
+ "You can teleport at will.",
+ "You gain the power of teleportation at will.",
+ "You lose the power of teleportation at will.",
+ power_activation {
+ 7, 7, A_WIS, 15
+ }
+ ),
+ },
+ {
+ PWR_MIND_BLST,
+ std::make_shared<power_type>(
+ "mind blast",
+ "You can mind blast your enemies.",
+ "You gain the power of Mind Blast.",
+ "You lose the power of Mind Blast.",
+ power_activation {
+ 5, 3, A_WIS, 15
+ }
+ ),
+ },
+ {
+ PWR_RADIATION,
+ std::make_shared<power_type>(
+ "emit radiation",
+ "You can emit hard radiation at will.",
+ "You start emitting hard radiation.",
+ "You stop emitting hard radiation.",
+ power_activation {
+ 15, 15, A_CON, 14
+ }
+ ),
+ },
+ {
+ PWR_VAMPIRISM,
+ std::make_shared<power_type>(
+ "vampiric drain",
+ "You can drain life from a foe.",
+ "You become vampiric.",
+ "You are no longer vampiric.",
+ power_activation {
+ 4, 5, A_CON, 9
+ }
+ ),
+ },
+ {
+ PWR_SMELL_MET,
+ std::make_shared<power_type>(
+ "smell metal",
+ "You can smell nearby precious metal.",
+ "You smell a metallic odour.",
+ "You no longer smell a metallic odour.",
+ power_activation {
+ 3, 2, A_INT, 12
+ }
+ ),
+ },
+ {
+ PWR_SMELL_MON,
+ std::make_shared<power_type>(
+ "smell monsters",
+ "You can smell nearby monsters.",
+ "You smell filthy monsters.",
+ "You no longer smell filthy monsters.",
+ power_activation {
+ 5, 4, A_INT, 15
+ }
+ ),
+ },
+ {
+ PWR_BLINK,
+ std::make_shared<power_type>(
+ "blink",
+ "You can teleport yourself short distances.",
+ "You gain the power of minor teleportation.",
+ "You lose the power of minor teleportation.",
+ power_activation {
+ 3, 3, A_WIS, 12
+ }
+ ),
+ },
+ {
+ PWR_EAT_ROCK,
+ std::make_shared<power_type>(
+ "eat rock",
+ "You can consume solid rock.",
+ "The walls look delicious.",
+ "The walls look unappetising.",
+ power_activation {
+ 8, 12, A_CON, 18
+ }
+ ),
+ },
+ {
+ PWR_SWAP_POS,
+ std::make_shared<power_type>(
+ "swap position",
+ "You can switch locations with another being.",
+ "You feel like walking a mile in someone else's shoes.",
+ "You feel like staying in your own shoes.",
+ power_activation {
+ 15, 12, A_DEX, 16
+ }
+ ),
+ },
+ {
+ PWR_SHRIEK,
+ std::make_shared<power_type>(
+ "shriek",
+ "You can emit a horrible shriek.",
+ "Your vocal cords get much tougher.",
+ "Your vocal cords get much weaker.",
+ power_activation {
+ 4, 4, A_CON, 6
+ }
+ ),
+ },
+ {
+ PWR_ILLUMINE,
+ std::make_shared<power_type>(
+ "illuminate",
+ "You can emit bright light.",
+ "You can light up rooms with your presence.",
+ "You can no longer light up rooms with your presence.",
+ power_activation {
+ 3, 2, A_INT, 10
+ }
+ ),
+ },
+ {
+ PWR_BERSERK,
+ std::make_shared<power_type>(
+ "berserk",
+ "You can drive yourself into a berserk frenzy.",
+ "You feel a controlled rage.",
+ "You no longer feel a controlled rage.",
+ power_activation {
+ 8, 8, A_STR, 14
+ }
+ ),
+ },
+ {
+ PWR_POLYMORPH,
+ std::make_shared<power_type>(
+ "polymorph",
+ "You can polymorph yourself at will.",
+ "Your body seems mutable.",
+ "Your body seems stable.",
+ power_activation {
+ 18, 20, A_CON, 18
+ }
+ ),
+ },
+ {
+ PWR_MIDAS_TCH,
+ std::make_shared<power_type>(
+ "Midas touch",
+ "You can turn ordinary items to gold.",
+ "You gain the Midas touch.",
+ "You lose the Midas touch.",
+ power_activation {
+ 10, 5, A_INT, 12
+ }
+ ),
+ },
+ {
+ PWR_GROW_MOLD,
+ std::make_shared<power_type>(
+ "grow mold",
+ "You can cause mold to grow near you.",
+ "You feel a sudden affinity for mold.",
+ "You feel a sudden dislike for mold.",
+ power_activation {
+ 1, 6, A_CON, 14
+ }
+ ),
+ },
+ {
+ PWR_RESIST,
+ std::make_shared<power_type>(
+ "resist elements",
+ "You can harden yourself to the ravages of the elements.",
+ "You feel like you can protect yourself.",
+ "You feel like you might be vulnerable.",
+ power_activation {
+ 10, 12, A_CON, 12
+ }
+ ),
+ },
+ {
+ PWR_EARTHQUAKE,
+ std::make_shared<power_type>(
+ "earthquake",
+ "You can bring down the dungeon around your ears.",
+ "You gain the ability to wreck the dungeon.",
+ "You lose the ability to wreck the dungeon.",
+ power_activation {
+ 12, 12, A_STR, 16
+ }
+ ),
+ },
+ {
+ PWR_EAT_MAGIC,
+ std::make_shared<power_type>(
+ "eat magic",
+ "You can consume magic energy for your own use.",
+ "Your magic items look delicious.",
+ "Your magic items no longer look delicious.",
+ power_activation {
+ 17, 1, A_WIS, 15
+ }
+ ),
+ },
+ {
+ PWR_WEIGH_MAG,
+ std::make_shared<power_type>(
+ "weigh magic",
+ "You can feel the strength of the magics affecting you.",
+ "You feel you can better understand the magic around you.",
+ "You no longer sense magic.",
+ power_activation {
+ 6, 6, A_INT, 10
+ }
+ ),
+ },
+ {
+ PWR_STERILITY,
+ std::make_shared<power_type>(
+ "sterilise",
+ "You can cause mass impotence.",
+ "You can give everything around you a headache.",
+ "You hear a massed sigh of relief.",
+ power_activation {
+ 20, 40, A_CHR, 18
+ }
+ ),
+ },
+ {
+ PWR_PANIC_HIT,
+ std::make_shared<power_type>(
+ "panic hit",
+ "You can run for your life after hitting something.",
+ "You suddenly understand how thieves feel.",
+ "You no longer feel jumpy.",
+ power_activation {
+ 10, 12, A_DEX, 14
+ }
+ ),
+ },
+ {
+ PWR_DAZZLE,
+ std::make_shared<power_type>(
+ "dazzle",
+ "You can emit confusing, blinding radiation.",
+ "You gain the ability to emit dazzling lights.",
+ "You lose the ability to emit dazzling lights.",
+ power_activation {
+ 7, 15, A_CHR, 8
+ }
+ ),
+ },
+ {
+ PWR_DARKRAY,
+ std::make_shared<power_type>(
+ "spear of darkness",
+ "You can create a spear of darkness.",
+ "An illusory spear of darkness appears in your hand.",
+ "The spear of darkness disappear.",
+ power_activation {
+ 7, 10, A_WIS, 9
+ }
+ ),
+ },
+ {
+ PWR_RECALL,
+ std::make_shared<power_type>(
+ "recall",
+ "You can travel between towns and the depths.",
+ "You feel briefly homesick, but it passes.",
+ "You feel briefly homesick.",
+ power_activation {
+ 17, 50, A_INT, 16
+ }
+ ),
+ },
+ {
+ PWR_BANISH,
+ std::make_shared<power_type>(
+ "banish evil",
+ "You can send evil creatures directly to the Nether Realm.",
+ "You feel a holy wrath fill you.",
+ "You no longer feel a holy wrath.",
+ power_activation {
+ 25, 25, A_WIS, 18
+ }
+ ),
+ },
+ {
+ PWR_COLD_TOUCH,
+ std::make_shared<power_type>(
+ "cold touch",
+ "You can freeze things with a touch.",
+ "Your hands get very cold.",
+ "Your hands warm up.",
+ power_activation {
+ 2, 2, A_CON, 11
+ }
+ ),
+ },
+ {
+ PWR_LAUNCHER,
+ std::make_shared<power_type>(
+ "throw object",
+ "You can hurl objects with great force.",
+ "Your throwing arm feels much stronger.",
+ "Your throwing arm feels much weaker.",
+ power_activation {
+ 1, 10, A_STR, 6
+ }
+ ),
+ },
+ {
+ PWR_PASSWALL,
+ std::make_shared<power_type>(
+ "find secret passages",
+ "You can use secret passages.",
+ "You suddenly notice lots of hidden ways.",
+ "You no longer can use hidden ways.",
+ power_activation {
+ 15, 15, A_DEX, 12
+ }
+ ),
+ },
+ {
+ PWR_DETECT_TD,
+ std::make_shared<power_type>(
+ "detect doors and traps",
+ "You can detect hidden doors and traps.",
+ "You develop an affinity for traps.",
+ "You no longer can detect hidden doors and traps.",
+ power_activation {
+ 5, 3, A_WIS, 10
+ }
+ ),
+ },
+ {
+ PWR_COOK_FOOD,
+ std::make_shared<power_type>(
+ "create food",
+ "You can create food.",
+ "Your cooking skills greatly improve.",
+ "Your cooking skills return to a normal level.",
+ power_activation {
+ 15, 10, A_INT, 10
+ }
+ ),
+ },
+ {
+ PWR_UNFEAR,
+ std::make_shared<power_type>(
+ "remove fear",
+ "You can embolden yourself.",
+ "You feel your fears lessening.",
+ "You feel your fears growing again.",
+ power_activation {
+ 3, 5, A_WIS, 8
+ }
+ ),
+ },
+ {
+ PWR_EXPL_RUNE,
+ std::make_shared<power_type>(
+ "set explosive rune",
+ "You can set explosive runes.",
+ "You suddenly understand how explosive runes work.",
+ "You suddenly forget how explosive runes work.",
+ power_activation {
+ 25, 35, A_INT, 15
+ }
+ ),
+ },
+ {
+ PWR_STM,
+ std::make_shared<power_type>(
+ "stone to mud",
+ "You can destroy walls.",
+ "You can destroy walls.",
+ "You cannot destroy walls anymore.",
+ power_activation {
+ 20, 10, A_STR, 12
+ }
+ ),
+ },
+ {
+ PWR_POIS_DART,
+ std::make_shared<power_type>(
+ "poison dart",
+ "You can throw poisoned darts.",
+ "You get an infinite supply of poisoned darts.",
+ "You lose your infinite supply of poisoned darts.",
+ power_activation {
+ 12, 8, A_DEX, 14
+ }
+ ),
+ },
+ {
+ PWR_MAGIC_MISSILE,
+ std::make_shared<power_type>(
+ "magic missile",
+ "You can cast magic missiles.",
+ "You suddenly understand the basics of magic.",
+ "You forget the basics of magic.",
+ power_activation {
+ 2, 2, A_INT, 9
+ }
+ ),
+ },
+ {
+ PWR_GROW_TREE,
+ std::make_shared<power_type>(
+ "grow trees",
+ "You can grow trees.",
+ "You feel an affinity for trees.",
+ "You no longer feel an affinity for trees.",
+ power_activation {
+ 2, 6, A_CHR, 3
+ }
+ ),
+ },
+ {
+ PWR_BR_COLD,
+ std::make_shared<power_type>(
+ "cold breath",
+ "You can breath cold.",
+ "You gain the ability to breathe cold.",
+ "You lose the ability to breathe cold.",
+ power_activation {
+ 20, 10, A_CON, 18
+ }
+ ),
+ },
+ {
+ PWR_BR_CHAOS,
+ std::make_shared<power_type>(
+ "chaos breath",
+ "You can breath chaos.",
+ "You gain the ability to breathe chaos.",
+ "You lose the ability to breathe chaos.",
+ power_activation {
+ 20, 10, A_CON, 18
+ }
+ ),
+ },
+ {
+ PWR_BR_ELEM,
+ std::make_shared<power_type>(
+ "elemental breath",
+ "You can breath the elements.",
+ "You gain the ability to breathe the elements.",
+ "You lose the ability to breathe the elements.",
+ power_activation {
+ 20, 10, A_CON, 18
+ }
+ ),
+ },
+ {
+ PWR_WRECK_WORLD,
+ std::make_shared<power_type>(
+ "change the world",
+ "You can wreck the world around you.",
+ "You gain the ability to wreck the world.",
+ "You lose the ability to wreck the world.",
+ power_activation {
+ 1, 30, A_CHR, 6
+ }
+ ),
+ },
+ {
+ PWR_SCARE,
+ std::make_shared<power_type>(
+ "scare monster",
+ "You can scare monsters.",
+ "You gain the ability to scare monsters.",
+ "You lose the ability to scare monsters.",
+ power_activation {
+ 4, 3, A_INT, 3
+ }
+ ),
+ },
+ {
+ PWR_REST_LIFE,
+ std::make_shared<power_type>(
+ "restore life",
+ "You can restore lost life forces.",
+ "You gain the ability to restore your life force.",
+ "You lose the ability to restore your life force.",
+ power_activation {
+ 30, 30, A_WIS, 18
+ }
+ ),
+ },
+ {
+ PWR_SUMMON_MONSTER,
+ std::make_shared<power_type>(
+ "summon monsters",
+ "You can call upon monsters.",
+ "You gain the ability to call upon monsters.",
+ "You lose the ability to call upon monsters.",
+ power_activation {
+ 0, 0, 0, 0
+ }
+ ),
+ },
+ {
+ PWR_NECRO,
+ std::make_shared<power_type>(
+ "necromantic powers",
+ "You can use the foul necromantic magic.",
+ "You gain the ability to use the foul necromantic magic.",
+ "You lose the ability to use the foul necromantic magic.",
+ power_activation {
+ 0, 0, 0, 0
+ }
+ ),
+ },
+ {
+ PWR_ROHAN,
+ std::make_shared<power_type>(
+ "Rohan Knight's Powers",
+ "You can use rohir powers.",
+ "You gain the ability to use rohir powers.",
+ "You lose the ability to use rohir powers.",
+ power_activation {
+ 0, 0, 0, 0
+ }
+ ),
+ },
+ {
+ PWR_THUNDER,
+ std::make_shared<power_type>(
+ "Thunderlord's Powers",
+ "You can use thunderlords powers.",
+ "You gain the ability to use thunderlords powers.",
+ "You lose the ability to use thunderlords powers.",
+ power_activation {
+ 0, 0, 0, 0
+ }
+ ),
+ },
+ {
+ PWR_DEATHMOLD,
+ std::make_shared<power_type>(
+ "Death Mold's Powers",
+ "You can use the foul deathmold magic.",
+ "You gain the ability to use the foul deathmold magic.",
+ "You lose the ability to use the foul deathmold magic.",
+ power_activation {
+ 0, 0, 0, 0
+ }
+ ),
+ },
+ {
+ PWR_HYPNO,
+ std::make_shared<power_type>(
+ "Hypnotise Pet",
+ "You can mystify pets.",
+ "You gain the ability to mystify pets.",
+ "You lose the ability to mystify pets.",
+ power_activation {
+ 0, 0, 0, 0
+ }
+ ),
+ },
+ {
+ PWR_UNHYPNO,
+ std::make_shared<power_type>(
+ "Awaken Hypnotised Pet",
+ "You can wake up a pet.",
+ "You gain the ability to wake up a pet.",
+ "You lose the ability to wake up a pet.",
+ power_activation {
+ 0, 0, 0, 0
+ }
+ ),
+ },
+ {
+ PWR_INCARNATE,
+ std::make_shared<power_type>(
+ "Incarnate",
+ "You can incarnate into a body.",
+ "You feel the need to get a body.",
+ "You no longer feel the need for a new body.",
+ power_activation {
+ 0, 0, 0, 0
+ }
+ ),
+ },
+ {
+ PWR_MAGIC_MAP,
+ std::make_shared<power_type>(
+ "magic map",
+ "You can sense what is beyond walls.",
+ "You feel you can sense what is beyond walls.",
+ "You no longer can sense what is beyond walls.",
+ power_activation {
+ 7, 10, A_WIS, 15
+ }
+ ),
+ },
+ {
+ PWR_COMPANION,
+ std::make_shared<power_type>(
+ "turn pet into companion",
+ "You can turn a pet into a companion.",
+ "You suddenly gain authority over your pets.",
+ "You can no longer convert pets into companions.",
+ power_activation {
+ 2, 10, A_CHR, 10
+ }
+ ),
+ },
+ {
+ PWR_BEAR,
+ std::make_shared<power_type>(
+ "turn into a bear",
+ "You can turn into a bear.",
+ "You suddenly gain beorning powers.",
+ "You can no longer shapeshift into a bear.",
+ power_activation {
+ 2, 5, A_CON, 5
+ }
+ ),
+ },
+ {
+ PWR_DODGE,
+ std::make_shared<power_type>(
+ "sense dodge success",
+ "You can sense your dodging success chance.",
+ "You suddenly can sense your dodging success chance.",
+ "You can no longer sense your dodging success chance.",
+ power_activation {
+ 0, 0, 0, 0
+ }
+ ),
+ },
+ {
+ PWR_BALROG,
+ std::make_shared<power_type>(
+ "turn into a Balrog",
+ "You can turn into a Balrog at will.",
+ "You feel the fire of Udun burning in you.",
+ "You no longer feel the fire of Udun in you.",
+ power_activation {
+ 35, 80, A_WIS, 25
+ }
+ ),
+ },
+ {
+ POWER_INVISIBILITY,
+ std::make_shared<power_type>(
+ "invisibility",
+ "You are able melt into the shadows to become invisible.",
+ "You suddenly become able to melt into the shadows.",
+ "You lose your shadow-melting ability.",
+ power_activation {
+ 30, 10, A_DEX, 20
+ }
+ ),
+ },
+ {
+ POWER_WEB,
+ std::make_shared<power_type>(
+ "web",
+ "You are able throw a thick and very resistant spider web.",
+ "You suddenly become able to weave webs.",
+ "You lose your web-weaving capability.",
+ power_activation {
+ 25, 30, A_DEX, 20
+ }
+ ),
+ },
+ {
+ POWER_COR_SPACE_TIME,
+ std::make_shared<power_type>(
+ "control space/time continuum",
+ "You are able to control the space/time continuum.",
+ "You become able to control the space/time continuum.",
+ "You are no more able to control the space/time continuum.",
+ power_activation {
+ 1, 10, A_WIS, 10
+ }
+ ),
+ },
+ };
+}
diff --git a/src/game.hpp b/src/game.hpp
index 4f84f52c..93b18e50 100644
--- a/src/game.hpp
+++ b/src/game.hpp
@@ -4,18 +4,22 @@
#include "alloc.hpp"
#include "birther.hpp"
+#include "effect_type.hpp"
#include "game_edit_data.hpp"
#include "grid.hpp"
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "level_marker.hpp"
#include "messages.hpp"
#include "player_defs.hpp"
+#include "powers.hpp"
+#include "power_type.hpp"
#include "random_artifact.hpp"
#include "skill_type.hpp"
#include "timer_type_fwd.hpp"
#include "wilderness_map.hpp"
#include <boost/multi_array.hpp>
+#include <unordered_map>
/**
* All structures for the game itself.
@@ -65,6 +69,14 @@ struct Game {
std::array<s16b, PY_MAX_LEVEL> player_hp { };
/**
+ * Powers
+ */
+ std::unordered_map<
+ int,
+ std::shared_ptr<power_type>>
+ powers;
+
+ /**
* Message buffer.
*/
Messages messages { 2048 };
@@ -85,13 +97,33 @@ struct Game {
std::vector<timer_type *> timers;
/**
+ * Level generators
+ */
+ std::unordered_map<std::string, std::function<bool()>> level_generators;
+
+ /**
* Level markers for 'special' levels.
*/
boost::multi_array<level_marker, 2> level_markers { };
/**
+ * Dungeon flags.
+ */
+ dungeon_flag_set dungeon_flags { };
+
+ /**
+ * Lasting effects.
+ */
+ std::vector<effect_type> lasting_effects { };
+
+ /**
* Generate a special level feeling?
*/
bool generate_special_feeling = false;
+ /**
+ * Construct a default instance.
+ */
+ explicit Game();
+
};
diff --git a/src/game_edit_data.cc b/src/game_edit_data.cc
new file mode 100644
index 00000000..1195dd14
--- /dev/null
+++ b/src/game_edit_data.cc
@@ -0,0 +1,18 @@
+#include "game_edit_data.hpp"
+
+#include <algorithm>
+
+std::vector<int> const GameEditData::k_info_keys() const
+{
+ std::vector<int> keys;
+
+ std::transform(std::begin(k_info),
+ std::end(k_info),
+ std::back_inserter(keys),
+ [] (auto e) { return e.first; });
+
+ std::sort(std::begin(keys),
+ std::end(keys));
+
+ return keys;
+};
diff --git a/src/game_edit_data.hpp b/src/game_edit_data.hpp
index a4727d90..3b8f2cd4 100644
--- a/src/game_edit_data.hpp
+++ b/src/game_edit_data.hpp
@@ -21,6 +21,8 @@
#include "vault_type.hpp"
#include "wilderness_type_info.hpp"
+#include <memory>
+#include <unordered_map>
#include <vector>
/**
@@ -66,9 +68,14 @@ struct GameEditData {
std::vector<set_type> set_info;
/**
- * Object kinds
+ * Object kinds.
*/
- std::vector<object_kind> k_info;
+ std::unordered_map<int, std::shared_ptr<object_kind>> k_info;
+
+ /**
+ * Get a sorted vector of all the keys of k_info.
+ */
+ std::vector<int> const k_info_keys() const;
/**
* Building actions.
diff --git a/src/gen_evol.cc b/src/gen_evol.cc
index 7dca5b9a..dc1ac4f5 100644
--- a/src/gen_evol.cc
+++ b/src/gen_evol.cc
@@ -22,35 +22,31 @@
/*
* Generate a game of life level :) and make it evolve
*/
-void evolve_level(bool_ noise)
+void evolve_level(bool noise)
{
auto const &f_info = game->edit_data.f_info;
- int i, j;
-
- int cw = 0, cf = 0;
-
-
/* Add a bit of noise */
if (noise)
{
- for (i = 1; i < cur_wid - 1; i++)
+ int cw = 0;
+ int cf = 0;
+
+ for (int i = 1; i < cur_wid - 1; i++)
{
- for (j = 1; j < cur_hgt - 1; j++)
+ for (int j = 1; j < cur_hgt - 1; j++)
{
if (f_info[cave[j][i].feat].flags & FF_WALL) cw++;
if (f_info[cave[j][i].feat].flags & FF_FLOOR) cf++;
}
}
- for (i = 1; i < cur_wid - 1; i++)
+ for (int i = 1; i < cur_wid - 1; i++)
{
- for (j = 1; j < cur_hgt - 1; j++)
+ for (int j = 1; j < cur_hgt - 1; j++)
{
- cave_type *c_ptr;
-
/* Access the grid */
- c_ptr = &cave[j][i];
+ auto c_ptr = &cave[j][i];
/* Permanent features should stay */
if (f_info[c_ptr->feat].flags & FF_PERMANENT) continue;
@@ -76,9 +72,9 @@ void evolve_level(bool_ noise)
}
}
- for (i = 1; i < cur_wid - 1; i++)
+ for (int i = 1; i < cur_wid - 1; i++)
{
- for (j = 1; j < cur_hgt - 1; j++)
+ for (int j = 1; j < cur_hgt - 1; j++)
{
int x, y, c;
cave_type *c_ptr;
@@ -138,7 +134,7 @@ void evolve_level(bool_ noise)
}
-bool_ level_generate_life()
+bool level_generate_life()
{
int i, j;
@@ -152,13 +148,15 @@ bool_ level_generate_life()
}
}
- evolve_level(FALSE);
- evolve_level(FALSE);
- evolve_level(FALSE);
+ evolve_level(false);
+ evolve_level(false);
+ evolve_level(false);
/* Determine the character location */
if (!new_player_spot(get_branch()))
- return FALSE;
+ {
+ return false;
+ }
- return TRUE;
+ return true;
}
diff --git a/src/gen_evol.hpp b/src/gen_evol.hpp
index 6e5087c8..9a820f3b 100644
--- a/src/gen_evol.hpp
+++ b/src/gen_evol.hpp
@@ -1,6 +1,4 @@
#pragma once
-#include "h-basic.h"
-
-bool_ level_generate_life();
-void evolve_level(bool_ noise);
+bool level_generate_life();
+void evolve_level(bool noise);
diff --git a/src/gen_maze.cc b/src/gen_maze.cc
index 22722e0a..c5260a9a 100644
--- a/src/gen_maze.cc
+++ b/src/gen_maze.cc
@@ -143,7 +143,7 @@ static void dig(maze_row *maze, int y, int x, int d)
}
-bool_ level_generate_maze()
+bool level_generate_maze()
{
int i, j, d;
int y, dy = 0;
@@ -288,7 +288,9 @@ bool_ level_generate_maze()
/* Determine the character location */
if (!new_player_spot(get_branch()))
- return FALSE;
+ {
+ return false;
+ }
- return TRUE;
+ return true;
}
diff --git a/src/gen_maze.hpp b/src/gen_maze.hpp
index bc03b575..fea3defb 100644
--- a/src/gen_maze.hpp
+++ b/src/gen_maze.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
-bool_ level_generate_maze();
+bool level_generate_maze();
diff --git a/src/generate.cc b/src/generate.cc
index ba485faf..7fc94217 100644
--- a/src/generate.cc
+++ b/src/generate.cc
@@ -17,6 +17,7 @@
#include "feature_type.hpp"
#include "game.hpp"
#include "hook_build_room1_in.hpp"
+#include "hook_quest_gen_in.hpp"
#include "hooks.hpp"
#include "init1.hpp"
#include "levels.hpp"
@@ -41,11 +42,15 @@
#include "wild.hpp"
#include "wilderness_map.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
+#include <boost/algorithm/string/predicate.hpp>
#include <cassert>
#include <memory>
#include <vector>
+using boost::algorithm::equals;
+
#define SAFE_MAX_ATTEMPTS 5000
/*
@@ -293,53 +298,17 @@ struct dun_data
int col_rooms;
/* Array of which blocks are used */
- bool_ room_map[MAX_ROOMS_ROW][MAX_ROOMS_COL];
+ bool room_map[MAX_ROOMS_ROW][MAX_ROOMS_COL];
/* Hack -- there is a pit/nest on this level */
- bool_ crowded;
+ bool crowded;
};
/*
- * Level generator type
- */
-
-typedef struct level_generator_type level_generator_type;
-struct level_generator_type
-{
- cptr name;
- bool_ (*generator)();
-
- struct level_generator_type *next;
-};
-
-static level_generator_type *level_generators = NULL;
-
-/*
- * Add a new generator
- */
-void add_level_generator(cptr name, bool_ (*generator)())
-{
- assert(name != nullptr);
-
- level_generator_type *g = new level_generator_type;
-
- g->name = strdup(name);
- g->generator = generator;
-
- g->next = level_generators;
- level_generators = g;
-}
-
-
-/*
* Dungeon generation data -- see "cave_gen()"
*/
static dun_data *dun;
-/*
- * ???
- */
-static int template_race;
@@ -407,6 +376,7 @@ static void rand_dir(int *rdir, int *cdir)
*/
static void place_up_stairs(int y, int x)
{
+ auto const &dungeon_flags = game->dungeon_flags;
cave_type *c_ptr = &cave[y][x];
/* Create up stairs */
@@ -429,6 +399,7 @@ static void place_up_stairs(int y, int x)
static void place_down_stairs(int y, int x)
{
auto const &d_info = game->edit_data.d_info;
+ auto const &dungeon_flags = game->dungeon_flags;
cave_type *c_ptr = &cave[y][x];
@@ -454,7 +425,7 @@ static void place_down_stairs(int y, int x)
* Helper function for place_new_way. Determine if y, x is one of
* floor features of the current dungeon
*/
-static bool_ is_safe_floor(int y, int x)
+static bool is_safe_floor(int y, int x)
{
auto const &d_info = game->edit_data.d_info;
@@ -462,12 +433,12 @@ static bool_ is_safe_floor(int y, int x)
byte feat = cave[y][x].feat;
/* One of the legal floor types */
- if (feat == d_ptr->floor1) return (TRUE);
- if (feat == d_ptr->floor2) return (TRUE);
- if (feat == d_ptr->floor3) return (TRUE);
+ if (feat == d_ptr->floor1) return true;
+ if (feat == d_ptr->floor2) return true;
+ if (feat == d_ptr->floor3) return true;
/* Assume non-floor */
- return (FALSE);
+ return false;
}
@@ -482,13 +453,13 @@ void place_new_way(int *y, int *x)
int x0, x1, x2;
int y0, y1, y2;
cave_type *c_ptr;
- bool_ ok;
+ bool ok;
int i, way_n;
byte way_x[MAX_WID], way_y[MAX_WID];
/* Find valid location XXX XXX XXX */
- while (TRUE)
+ while (true)
{
/* A way on vertical edge */
if (rand_int(cur_hgt + cur_wid) < cur_hgt)
@@ -599,17 +570,17 @@ void place_new_way(int *y, int *x)
way_n = 0;
/* Assume bad location */
- ok = FALSE;
+ ok = false;
/* Check if it connects to current dungeon */
while (in_bounds(yy, xx))
{
/* Check grids ahead */
- if (is_safe_floor(yy + y0, xx + x0)) ok = TRUE;
+ if (is_safe_floor(yy + y0, xx + x0)) ok = true;
/* Check side grids */
- if (is_safe_floor(yy + y1, xx + x1)) ok = TRUE;
- if (is_safe_floor(yy + y2, xx + x2)) ok = TRUE;
+ if (is_safe_floor(yy + y1, xx + x1)) ok = true;
+ if (is_safe_floor(yy + y2, xx + x2)) ok = true;
/* Connected */
if (ok) break;
@@ -621,7 +592,7 @@ void place_new_way(int *y, int *x)
if (c_ptr->feat == FEAT_PERM_OUTER)
{
/* Comment this out if you find any problems... */
- ok = TRUE;
+ ok = true;
break;
}
@@ -677,7 +648,7 @@ void place_new_way(int *y, int *x)
way_n++;
}
- ok = TRUE;
+ ok = true;
break;
}
@@ -710,8 +681,10 @@ void place_new_way(int *y, int *x)
/*
* Returns random co-ordinates for player/monster/object
*/
-bool_ new_player_spot(int branch)
+bool new_player_spot(int branch)
{
+ auto const &dungeon_flags = game->dungeon_flags;
+
int y, x;
int max_attempts = 5000;
@@ -741,7 +714,7 @@ bool_ new_player_spot(int branch)
}
/* Should be -1, actually if we failed... */
- if (max_attempts < 1) return (FALSE);
+ if (max_attempts < 1) return false;
/* Save the new player grid */
@@ -770,7 +743,7 @@ bool_ new_player_spot(int branch)
}
}
- return (TRUE);
+ return true;
}
@@ -830,9 +803,9 @@ static void place_fountain(int y, int x)
int maxsval = 0;
/* List of usable svals */
- for (auto const &k_ref: k_info)
+ for (auto const &k_entry: k_info)
{
- auto k_ptr = &k_ref;
+ auto const &k_ptr = k_entry.second;
if (((k_ptr->tval == TV_POTION) || (k_ptr->tval == TV_POTION2)) &&
(k_ptr->level <= dun_level) && (k_ptr->flags & TR_FOUNTAIN))
@@ -875,7 +848,7 @@ static void place_between(int y, int x)
cave_type *c_ptr = &cave[y][x], *c1_ptr;
int gx, gy;
- while (TRUE)
+ while (true)
{
/* Location */
gy = rand_int(cur_hgt);
@@ -1001,6 +974,7 @@ static void place_random_door(int y, int x)
static void alloc_stairs(int feat, int num, int walls, int branch)
{
auto const &d_info = game->edit_data.d_info;
+ auto const &dungeon_flags = game->dungeon_flags;
int y, x, i, j, cnt;
@@ -1103,7 +1077,7 @@ static void alloc_object(int set, int typ, int num)
/* Pick a "legal" spot */
while (dummy < SAFE_MAX_ATTEMPTS)
{
- bool_ room;
+ bool room;
dummy++;
@@ -1115,7 +1089,7 @@ static void alloc_object(int set, int typ, int num)
if (!cave_naked_bold(y, x)) continue;
/* Check for "room" */
- room = (cave[y][x].info & (CAVE_ROOM)) ? TRUE : FALSE;
+ room = (cave[y][x].info & (CAVE_ROOM)) ? true : false;
/* Require corridor? */
if ((set == ALLOC_SET_CORR) && room) continue;
@@ -1155,7 +1129,7 @@ static void alloc_object(int set, int typ, int num)
case ALLOC_TYP_OBJECT:
{
- place_object(y, x, FALSE, FALSE, OBJ_FOUND_FLOOR);
+ place_object(y, x, false, false, OBJ_FOUND_FLOOR);
break;
}
@@ -1413,7 +1387,7 @@ static void build_streamer(int feat, int chance)
int d = DUN_STR_RNG;
/* Pick a nearby grid */
- while (1)
+ while (true)
{
ty = rand_spread(y, d);
tx = rand_spread(x, d);
@@ -1492,7 +1466,7 @@ static void build_streamer2(int feat, int killwall)
/* Place streamer into dungeon */
if (poolchance > 2)
{
- while (TRUE)
+ while (true)
{
/* One grid per density */
for (i = 0; i < (DUN_STR_DWLW + 1); i++)
@@ -1500,7 +1474,7 @@ static void build_streamer2(int feat, int killwall)
int d = DUN_STR_WLW;
/* Pick a nearby grid */
- while (1)
+ while (true)
{
ty = rand_spread(y, d);
tx = rand_spread(x, d);
@@ -1689,17 +1663,17 @@ static void destroy_level()
/*
* Function that sees if a square is a floor (Includes range checking)
*/
-static bool_ get_is_floor(int x, int y)
+static bool get_is_floor(int x, int y)
{
auto const &f_info = game->edit_data.f_info;
/* Out of bounds */
- if (!in_bounds(y, x)) return (FALSE);
+ if (!in_bounds(y, x)) return false;
/* Do the real check: */
- if (f_info[cave[y][x].feat].flags & FF_FLOOR) return (TRUE);
+ if (f_info[cave[y][x].feat].flags & FF_FLOOR) return true;
- return (FALSE);
+ return false;
}
@@ -1708,8 +1682,10 @@ static bool_ get_is_floor(int x, int y)
*/
static void check_room_boundary(int x1, int y1, int x2, int y2)
{
+ auto const &dungeon_flags = game->dungeon_flags;
+
int count, x, y;
- bool_ old_is_floor, new_is_floor;
+ bool old_is_floor, new_is_floor;
/* Avoid doing this in irrelevant places -- pelpel */
if (!(dungeon_flags & DF_CAVERN)) return;
@@ -1826,7 +1802,7 @@ static void vault_objects(int y, int x, int num)
/* Place an item */
if (rand_int(100) < 75)
{
- place_object(j, k, FALSE, FALSE, OBJ_FOUND_FLOOR);
+ place_object(j, k, false, false, OBJ_FOUND_FLOOR);
}
/* Place gold */
@@ -1865,7 +1841,7 @@ static void vault_monsters(int y1, int x1, int num)
/* Place the monster (allow groups) */
monster_level = dun_level + 2;
- place_monster(y, x, TRUE, TRUE);
+ place_monster(y, x, true, true);
monster_level = dun_level;
}
}
@@ -1881,7 +1857,7 @@ static void vault_monsters(int y1, int x1, int num)
* cx, cy are the returned center of the allocated room in coordinates for
* cave.feat and cave.info etc.
*/
-bool_ room_alloc(int width, int height, bool_ crowded, int by0, int bx0, int *cx, int *cy)
+bool room_alloc(int width, int height, bool crowded, int by0, int bx0, int *cx, int *cy)
{
int temp, eby, ebx, by, bx;
@@ -1892,7 +1868,7 @@ bool_ room_alloc(int width, int height, bool_ crowded, int by0, int bx0, int *cx
for (ebx = bx0 + temp; bx0 > 0 && ebx > dun->col_rooms; bx0--, ebx--);
- if (ebx > dun->col_rooms) return (FALSE);
+ if (ebx > dun->col_rooms) return false;
/* Total number along height */
temp = ((height - 1) / BLOCK_HGT) + 1;
@@ -1900,14 +1876,14 @@ bool_ room_alloc(int width, int height, bool_ crowded, int by0, int bx0, int *cx
for (eby = by0 + temp; by0 > 0 && eby > dun->row_rooms; by0--, eby--);
/* Never run off the screen */
- if (eby > dun->row_rooms) return (FALSE);
+ if (eby > dun->row_rooms) return false;
/* Verify open space */
for (by = by0; by < eby; by++)
{
for (bx = bx0; bx < ebx; bx++)
{
- if (dun->room_map[by][bx]) return (FALSE);
+ if (dun->room_map[by][bx]) return false;
}
}
@@ -1933,12 +1909,12 @@ bool_ room_alloc(int width, int height, bool_ crowded, int by0, int bx0, int *cx
{
for (bx = bx0; bx < ebx; bx++)
{
- dun->room_map[by][bx] = TRUE;
+ dun->room_map[by][bx] = true;
}
}
/* Count "crowded" rooms */
- if (crowded) dun->crowded = TRUE;
+ if (crowded) dun->crowded = true;
/*
* Hack -- See if room will cut off a cavern.
@@ -1949,7 +1925,7 @@ bool_ room_alloc(int width, int height, bool_ crowded, int by0, int bx0, int *cx
*cx + width / 2 + 1, *cy + height / 2 + 1);
/* Success */
- return (TRUE);
+ return true;
}
/*
@@ -1986,7 +1962,7 @@ static void build_type1(int by0, int bx0)
ysize = y1 + y2;
/* Try to allocate space for room. If fails, exit */
- if (!room_alloc(xsize + 2, ysize + 2, FALSE, by0, bx0, &xval, &yval)) return;
+ if (!room_alloc(xsize + 2, ysize + 2, false, by0, bx0, &xval, &yval)) return;
/* Get corner values */
y1 = yval - ysize / 2;
@@ -2051,7 +2027,7 @@ static void build_type2(int by0, int bx0)
int y1b, x1b, y2b, x2b;
/* Try to allocate space for room. If fails, exit */
- if (!room_alloc(25, 11, FALSE, by0, bx0, &xval, &yval)) return;
+ if (!room_alloc(25, 11, false, by0, bx0, &xval, &yval)) return;
/* Determine extents of the first room */
y1a = yval - randint(4);
@@ -2115,7 +2091,7 @@ static void build_type3(int by0, int bx0)
int yval, xval;
/* Try to allocate space for room. If fails, exit */
- if (!room_alloc(25, 11, FALSE, by0, bx0, &xval, &yval)) return;
+ if (!room_alloc(25, 11, false, by0, bx0, &xval, &yval)) return;
/* For now, always 3x3 */
wx = wy = 1;
@@ -2206,7 +2182,7 @@ static void build_type3(int by0, int bx0)
}
/* Place a treasure in the vault */
- place_object(yval, xval, FALSE, FALSE, OBJ_FOUND_FLOOR);
+ place_object(yval, xval, false, false, OBJ_FOUND_FLOOR);
/* Let's guard the treasure well */
vault_monsters(yval, xval, rand_int(2) + 3);
@@ -2284,7 +2260,7 @@ static void build_type4(int by0, int bx0)
int y2, x2, tmp, yval, xval;
/* Try to allocate space for room. If fails, exit */
- if (!room_alloc(25, 11, FALSE, by0, bx0, &xval, &yval)) return;
+ if (!room_alloc(25, 11, false, by0, bx0, &xval, &yval)) return;
/* Large room */
y1 = yval - 4;
@@ -2392,7 +2368,7 @@ static void build_type4(int by0, int bx0)
/* Object (80%) */
if (rand_int(100) < 80)
{
- place_object(yval, xval, FALSE, FALSE, OBJ_FOUND_FLOOR);
+ place_object(yval, xval, false, false, OBJ_FOUND_FLOOR);
}
/* Stairs (20%) */
@@ -2473,8 +2449,8 @@ static void build_type4(int by0, int bx0)
vault_monsters(yval, xval + 2, randint(2));
/* Objects */
- if (rand_int(3) == 0) place_object(yval, xval - 2, FALSE, FALSE, OBJ_FOUND_FLOOR);
- if (rand_int(3) == 0) place_object(yval, xval + 2, FALSE, FALSE, OBJ_FOUND_FLOOR);
+ if (rand_int(3) == 0) place_object(yval, xval - 2, false, false, OBJ_FOUND_FLOOR);
+ if (rand_int(3) == 0) place_object(yval, xval + 2, false, false, OBJ_FOUND_FLOOR);
}
break;
@@ -2585,234 +2561,145 @@ static void build_type4(int by0, int bx0)
*/
-/*
- * Helper function for "monster nest (jelly)"
- */
-static bool_ vault_aux_jelly(int r_idx)
+static bool vault_aux_jelly(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
/* Decline unique monsters */
- if (r_ptr->flags & RF_UNIQUE) return (FALSE);
+ if (r_ptr->flags & RF_UNIQUE) return false;
/* Also decline evil jellies (like death molds and shoggoths) */
- if (r_ptr->flags & RF_EVIL) return (FALSE);
+ if (r_ptr->flags & RF_EVIL) return false;
/* Require icky thing, jelly, mold, or mushroom */
- if (!strchr("ijm,", r_ptr->d_char)) return (FALSE);
+ if (!strchr("ijm,", r_ptr->d_char)) return false;
/* Okay */
- return (TRUE);
+ return true;
}
-
-/*
- * Helper function for "monster nest (animal)"
- */
-static bool_ vault_aux_animal(int r_idx)
+static bool vault_aux_animal(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
/* Decline unique monsters */
- if (r_ptr->flags & RF_UNIQUE) return (FALSE);
+ if (r_ptr->flags & RF_UNIQUE) return false;
/* Require "animal" flag */
- if (!(r_ptr->flags & RF_ANIMAL)) return (FALSE);
+ if (!(r_ptr->flags & RF_ANIMAL)) return false;
/* Okay */
- return (TRUE);
+ return true;
}
-
-/*
- * Helper function for "monster nest (undead)"
- */
-static bool_ vault_aux_undead(int r_idx)
+static bool vault_aux_undead(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
/* Decline unique monsters */
- if (r_ptr->flags & RF_UNIQUE) return (FALSE);
+ if (r_ptr->flags & RF_UNIQUE) return false;
/* Require Undead */
- if (!(r_ptr->flags & RF_UNDEAD)) return (FALSE);
+ if (!(r_ptr->flags & RF_UNDEAD)) return false;
/* Okay */
- return (TRUE);
+ return true;
}
-
-/*
- * Helper function for "monster nest (chapel)"
- */
-static bool_ vault_aux_chapel(int r_idx)
+static bool vault_aux_chapel(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
/* Decline unique monsters */
- if (r_ptr->flags & RF_UNIQUE) return (FALSE);
+ if (r_ptr->flags & RF_UNIQUE) return false;
/* Require "priest" or Angel */
if (!((r_ptr->d_char == 'A') || strstr(r_ptr->name, "riest")))
{
- return (FALSE);
+ return false;
}
/* Okay */
- return (TRUE);
+ return true;
}
-
-/*
- * Helper function for "monster nest (kennel)"
- */
-static bool_ vault_aux_kennel(int r_idx)
+static bool vault_aux_kennel(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
/* Decline unique monsters */
- if (r_ptr->flags & RF_UNIQUE) return (FALSE);
+ if (r_ptr->flags & RF_UNIQUE) return false;
/* Require a Zephyr Hound or a dog */
return ((r_ptr->d_char == 'Z') || (r_ptr->d_char == 'C'));
-
}
-
-/*
- * Helper function for "monster nest (treasure)"
- */
-static bool_ vault_aux_treasure(int r_idx)
+static bool vault_aux_treasure(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
/* Decline unique monsters */
- if (r_ptr->flags & RF_UNIQUE) return (FALSE);
+ if (r_ptr->flags & RF_UNIQUE) return false;
/* Require "priest" or Angel */
if (!((r_ptr->d_char == '!') || (r_ptr->d_char == '|') ||
- (r_ptr->d_char == '$') || (r_ptr->d_char == '?') ||
- (r_ptr->d_char == '=')))
+ (r_ptr->d_char == '$') || (r_ptr->d_char == '?') ||
+ (r_ptr->d_char == '=')))
{
- return (FALSE);
+ return false;
}
/* Okay */
- return (TRUE);
+ return true;
}
+static monster_race const *template_race = nullptr;
-/*
- * Helper function for "monster nest (clone)"
- */
-static bool_ vault_aux_clone(int r_idx)
+static bool vault_aux_clone(monster_race const *r_ptr)
{
- return (r_idx == template_race);
+ return (r_ptr == template_race);
}
-
-/*
- * Helper function for "monster nest (symbol clone)"
- */
-static bool_ vault_aux_symbol(int r_idx)
+static bool vault_aux_symbol(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- return ((r_info[r_idx].d_char == (r_info[template_race].d_char))
- && !(r_info[r_idx].flags & RF_UNIQUE));
+ return ((r_ptr->d_char == (template_race->d_char))
+ && !(r_ptr->flags & RF_UNIQUE));
}
-
-/*
- * Helper function for "monster pit (orc)"
- */
-static bool_ vault_aux_orc(int r_idx)
+static bool vault_aux_orc(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
/* Decline unique monsters */
- if (r_ptr->flags & RF_UNIQUE) return (FALSE);
+ if (r_ptr->flags & RF_UNIQUE) return false;
/* Hack -- Require "o" monsters */
- if (!strchr("o", r_ptr->d_char)) return (FALSE);
+ if (!strchr("o", r_ptr->d_char)) return false;
/* Okay */
- return (TRUE);
+ return true;
}
-
-
-/*
- * Helper function for "monster pit (troll)"
- */
-static bool_ vault_aux_troll(int r_idx)
+static bool vault_aux_troll(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
/* Decline unique monsters */
- if (r_ptr->flags & RF_UNIQUE) return (FALSE);
+ if (r_ptr->flags & RF_UNIQUE) return false;
/* Hack -- Require "T" monsters */
- if (!strchr("T", r_ptr->d_char)) return (FALSE);
+ if (!strchr("T", r_ptr->d_char)) return false;
/* Okay */
- return (TRUE);
+ return true;
}
-
-/*
- * Helper function for "monster pit (giant)"
- */
-static bool_ vault_aux_giant(int r_idx)
+static bool vault_aux_giant(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
/* Decline unique monsters */
- if (r_ptr->flags & RF_UNIQUE) return (FALSE);
+ if (r_ptr->flags & RF_UNIQUE) return false;
/* Hack -- Require "P" monsters */
- if (!strchr("P", r_ptr->d_char)) return (FALSE);
+ if (!strchr("P", r_ptr->d_char)) return false;
/* Okay */
- return (TRUE);
+ return true;
}
-
-/*
- * Helper function for "monster pit (demon)"
- */
-static bool_ vault_aux_demon(int r_idx)
+static bool vault_aux_demon(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
/* Decline unique monsters */
- if (r_ptr->flags & RF_UNIQUE) return (FALSE);
+ if (r_ptr->flags & RF_UNIQUE) return false;
/* Hack -- Require "U" monsters */
- if (!strchr("U", r_ptr->d_char)) return (FALSE);
+ if (!strchr("U", r_ptr->d_char)) return false;
/* Okay */
- return (TRUE);
+ return true;
}
@@ -2826,7 +2713,7 @@ static bool_ vault_aux_demon(int r_idx)
* races, to allow the nest creation to fail instead of having "holes".
*
* Note the use of the "get_mon_num_prep()" function, and the special
- * "get_mon_num_hook()" restriction function, to prepare the "monster
+ * "get_monster_hook()" restriction function, to prepare the "monster
* allocation table" in such a way as to optimize the selection of
* "appropriate" non-unique monsters for the nest.
*
@@ -2846,13 +2733,13 @@ static void build_type5(int by0, int bx0)
int y, x, y1, x1, y2, x2, xval, yval;
int tmp, i;
- cptr name;
- bool_ empty = FALSE;
- bool_ (*old_get_mon_num_hook)(int r_idx);
+ const char *name;
+ bool empty = false;
+ bool (*old_get_monster_hook)(monster_race const *);
s16b what[64];
/* Try to allocate space for room. If fails, exit */
- if (!room_alloc(25, 11, TRUE, by0, bx0, &xval, &yval)) return;
+ if (!room_alloc(25, 11, true, by0, bx0, &xval, &yval)) return;
/* Large room */
y1 = yval - 4;
@@ -2902,20 +2789,20 @@ static void build_type5(int by0, int bx0)
/* Hack -- Choose a nest type */
tmp = randint(dun_level);
- old_get_mon_num_hook = get_mon_num_hook;
+ old_get_monster_hook = get_monster_hook;
if ((tmp < 25) && (rand_int(2) != 0))
{
- while (1)
+ while (true)
{
- template_race = rand_int(r_info.size());
+ template_race = &*uniform_element(r_info);
/* Reject uniques */
- if (r_info[template_race].flags & RF_UNIQUE) continue;
+ if (template_race->flags & RF_UNIQUE) continue;
/* Reject OoD monsters in a loose fashion */
- if (((r_info[template_race].level) + randint(5)) >
- (dun_level + randint(5))) continue;
+ if ((template_race->level + randint(5)) >
+ (dun_level + randint(5))) continue;
/* Don't like 'break's like this, but this cannot be made better */
break;
@@ -2924,12 +2811,12 @@ static void build_type5(int by0, int bx0)
if ((dun_level >= (25 + randint(15))) && (rand_int(2) != 0))
{
name = "symbol clone";
- get_mon_num_hook = vault_aux_symbol;
+ get_monster_hook = vault_aux_symbol;
}
else
{
name = "clone";
- get_mon_num_hook = vault_aux_clone;
+ get_monster_hook = vault_aux_clone;
}
}
else if (tmp < 25)
@@ -2939,13 +2826,13 @@ static void build_type5(int by0, int bx0)
name = "jelly";
/* Restrict to jelly */
- get_mon_num_hook = vault_aux_jelly;
+ get_monster_hook = vault_aux_jelly;
}
else if (tmp < 50)
{
name = "treasure";
- get_mon_num_hook = vault_aux_treasure;
+ get_monster_hook = vault_aux_treasure;
}
/* Monster nest (animal) */
@@ -2954,7 +2841,7 @@ static void build_type5(int by0, int bx0)
if (rand_int(3) == 0)
{
name = "kennel";
- get_mon_num_hook = vault_aux_kennel;
+ get_monster_hook = vault_aux_kennel;
}
else
{
@@ -2962,7 +2849,7 @@ static void build_type5(int by0, int bx0)
name = "animal";
/* Restrict to animal */
- get_mon_num_hook = vault_aux_animal;
+ get_monster_hook = vault_aux_animal;
}
}
@@ -2972,7 +2859,7 @@ static void build_type5(int by0, int bx0)
if (rand_int(3) == 0)
{
name = "chapel";
- get_mon_num_hook = vault_aux_chapel;
+ get_monster_hook = vault_aux_chapel;
}
else
{
@@ -2980,7 +2867,7 @@ static void build_type5(int by0, int bx0)
name = "undead";
/* Restrict to undead */
- get_mon_num_hook = vault_aux_undead;
+ get_monster_hook = vault_aux_undead;
}
}
@@ -2994,11 +2881,11 @@ static void build_type5(int by0, int bx0)
what[i] = get_mon_num(dun_level + 10);
/* Notice failure */
- if (!what[i]) empty = TRUE;
+ if (!what[i]) empty = true;
}
/* Remove restriction */
- get_mon_num_hook = old_get_mon_num_hook;
+ get_monster_hook = old_get_monster_hook;
/* Prepare allocation table */
get_mon_num_prep();
@@ -3019,7 +2906,7 @@ static void build_type5(int by0, int bx0)
/* (Sometimes) Cause a "special feeling" (for "Monster Nests") */
if ((dun_level <= 40) && (randint(dun_level * dun_level + 50) < 300))
{
- good_item_flag = TRUE;
+ good_item_flag = true;
}
/* Place some monsters */
@@ -3030,7 +2917,7 @@ static void build_type5(int by0, int bx0)
int r_idx = what[rand_int(64)];
/* Place that "random" monster (no groups) */
- place_monster_aux(y, x, r_idx, FALSE, FALSE, MSTATUS_ENEMY);
+ place_monster_aux(y, x, r_idx, false, false, MSTATUS_ENEMY);
}
}
}
@@ -3071,7 +2958,7 @@ static void build_type5(int by0, int bx0)
* be present in many of the dragon pits, if they have the proper breath.
*
* Note the use of the "get_mon_num_prep()" function, and the special
- * "get_mon_num_hook()" restriction function, to prepare the "monster
+ * "get_monster_hook()" restriction function, to prepare the "monster
* allocation table" in such a way as to optimize the selection of
* "appropriate" non-unique monsters for the pit.
*
@@ -3086,12 +2973,12 @@ static void build_type6(int by0, int bx0)
int tmp, what[16];
int i, j, y, x, y1, x1, y2, x2, xval, yval;
- bool_ empty = FALSE;
- cptr name;
- bool_ (*old_get_mon_num_hook)(int r_idx);
+ bool empty = false;
+ const char *name;
+ bool (*old_get_monster_hook)(monster_race const *);
/* Try to allocate space for room. If fails, exit */
- if (!room_alloc(25, 11, TRUE, by0, bx0, &xval, &yval)) return;
+ if (!room_alloc(25, 11, true, by0, bx0, &xval, &yval)) return;
/* Large room */
y1 = yval - 4;
@@ -3141,7 +3028,7 @@ static void build_type6(int by0, int bx0)
/* Choose a pit type */
tmp = randint(dun_level);
- old_get_mon_num_hook = get_mon_num_hook;
+ old_get_monster_hook = get_monster_hook;
/* Orc pit */
if (tmp < 20)
@@ -3150,7 +3037,7 @@ static void build_type6(int by0, int bx0)
name = "orc";
/* Restrict monster selection */
- get_mon_num_hook = vault_aux_orc;
+ get_monster_hook = vault_aux_orc;
}
/* Troll pit */
@@ -3160,7 +3047,7 @@ static void build_type6(int by0, int bx0)
name = "troll";
/* Restrict monster selection */
- get_mon_num_hook = vault_aux_troll;
+ get_monster_hook = vault_aux_troll;
}
/* Giant pit */
@@ -3170,7 +3057,7 @@ static void build_type6(int by0, int bx0)
name = "giant";
/* Restrict monster selection */
- get_mon_num_hook = vault_aux_giant;
+ get_monster_hook = vault_aux_giant;
}
else if (tmp < 70)
@@ -3182,19 +3069,19 @@ static void build_type6(int by0, int bx0)
do
{
- template_race = rand_int(r_info.size() - 1);
+ template_race = &*uniform_element(r_info);
}
- while ((r_info[template_race].flags & RF_UNIQUE)
- || (((r_info[template_race].level) + randint(5)) >
- (dun_level + randint(5))));
+ while ((template_race->flags & RF_UNIQUE)
+ || (((template_race->level) + randint(5)) >
+ (dun_level + randint(5))));
/* Restrict selection */
- get_mon_num_hook = vault_aux_symbol;
+ get_monster_hook = vault_aux_symbol;
}
else
{
name = "ordered chapel";
- get_mon_num_hook = vault_aux_chapel;
+ get_monster_hook = vault_aux_chapel;
}
}
@@ -3202,7 +3089,7 @@ static void build_type6(int by0, int bx0)
/* Dragon pit */
else if (tmp < 80)
{
- /* Hack - get_mon_num_hook needs a plain function */
+ /* Hack - get_monster_hook needs a plain function */
static monster_spell_flag_set mask;
/* Pick dragon type */
@@ -3252,22 +3139,18 @@ static void build_type6(int by0, int bx0)
}
/* Restrict monster selection */
- get_mon_num_hook = [](int r_idx) -> bool_ {
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
+ get_monster_hook = [](monster_race const *r_ptr) -> bool {
/* Decline unique monsters */
- if (r_ptr->flags & RF_UNIQUE) return (FALSE);
+ if (r_ptr->flags & RF_UNIQUE) return false;
/* Hack -- Require "d" or "D" monsters */
- if (!strchr("Dd", r_ptr->d_char)) return (FALSE);
+ if (!strchr("Dd", r_ptr->d_char)) return false;
/* Hack -- Require correct "breath attack" */
- if ((r_ptr->spells & mask) != mask) return (FALSE);
+ if ((r_ptr->spells & mask) != mask) return false;
/* Okay */
- return (TRUE);
+ return true;
};
}
@@ -3278,7 +3161,7 @@ static void build_type6(int by0, int bx0)
name = "demon";
/* Restrict monster selection */
- get_mon_num_hook = vault_aux_demon;
+ get_monster_hook = vault_aux_demon;
}
/* Prepare allocation table */
@@ -3291,11 +3174,11 @@ static void build_type6(int by0, int bx0)
what[i] = get_mon_num(dun_level + 10);
/* Notice failure */
- if (!what[i]) empty = TRUE;
+ if (!what[i]) empty = true;
}
/* Remove restriction */
- get_mon_num_hook = old_get_mon_num_hook;
+ get_monster_hook = old_get_monster_hook;
/* Prepare allocation table */
get_mon_num_prep();
@@ -3356,57 +3239,57 @@ static void build_type6(int by0, int bx0)
/* (Sometimes) Cause a "special feeling" (for "Monster Pits") */
if ((dun_level <= 40) && (randint(dun_level * dun_level + 50) < 300))
{
- good_item_flag = TRUE;
+ good_item_flag = true;
}
/* Top and bottom rows */
for (x = xval - 9; x <= xval + 9; x++)
{
- place_monster_aux(yval - 2, x, what[0], FALSE, FALSE, MSTATUS_ENEMY);
- place_monster_aux(yval + 2, x, what[0], FALSE, FALSE, MSTATUS_ENEMY);
+ place_monster_aux(yval - 2, x, what[0], false, false, MSTATUS_ENEMY);
+ place_monster_aux(yval + 2, x, what[0], false, false, MSTATUS_ENEMY);
}
/* Middle columns */
for (y = yval - 1; y <= yval + 1; y++)
{
- place_monster_aux(y, xval - 9, what[0], FALSE, FALSE, MSTATUS_ENEMY);
- place_monster_aux(y, xval + 9, what[0], FALSE, FALSE, MSTATUS_ENEMY);
+ place_monster_aux(y, xval - 9, what[0], false, false, MSTATUS_ENEMY);
+ place_monster_aux(y, xval + 9, what[0], false, false, MSTATUS_ENEMY);
- place_monster_aux(y, xval - 8, what[1], FALSE, FALSE, MSTATUS_ENEMY);
- place_monster_aux(y, xval + 8, what[1], FALSE, FALSE, MSTATUS_ENEMY);
+ place_monster_aux(y, xval - 8, what[1], false, false, MSTATUS_ENEMY);
+ place_monster_aux(y, xval + 8, what[1], false, false, MSTATUS_ENEMY);
- place_monster_aux(y, xval - 7, what[1], FALSE, FALSE, MSTATUS_ENEMY);
- place_monster_aux(y, xval + 7, what[1], FALSE, FALSE, MSTATUS_ENEMY);
+ place_monster_aux(y, xval - 7, what[1], false, false, MSTATUS_ENEMY);
+ place_monster_aux(y, xval + 7, what[1], false, false, MSTATUS_ENEMY);
- place_monster_aux(y, xval - 6, what[2], FALSE, FALSE, MSTATUS_ENEMY);
- place_monster_aux(y, xval + 6, what[2], FALSE, FALSE, MSTATUS_ENEMY);
+ place_monster_aux(y, xval - 6, what[2], false, false, MSTATUS_ENEMY);
+ place_monster_aux(y, xval + 6, what[2], false, false, MSTATUS_ENEMY);
- place_monster_aux(y, xval - 5, what[2], FALSE, FALSE, MSTATUS_ENEMY);
- place_monster_aux(y, xval + 5, what[2], FALSE, FALSE, MSTATUS_ENEMY);
+ place_monster_aux(y, xval - 5, what[2], false, false, MSTATUS_ENEMY);
+ place_monster_aux(y, xval + 5, what[2], false, false, MSTATUS_ENEMY);
- place_monster_aux(y, xval - 4, what[3], FALSE, FALSE, MSTATUS_ENEMY);
- place_monster_aux(y, xval + 4, what[3], FALSE, FALSE, MSTATUS_ENEMY);
+ place_monster_aux(y, xval - 4, what[3], false, false, MSTATUS_ENEMY);
+ place_monster_aux(y, xval + 4, what[3], false, false, MSTATUS_ENEMY);
- place_monster_aux(y, xval - 3, what[3], FALSE, FALSE, MSTATUS_ENEMY);
- place_monster_aux(y, xval + 3, what[3], FALSE, FALSE, MSTATUS_ENEMY);
+ place_monster_aux(y, xval - 3, what[3], false, false, MSTATUS_ENEMY);
+ place_monster_aux(y, xval + 3, what[3], false, false, MSTATUS_ENEMY);
- place_monster_aux(y, xval - 2, what[4], FALSE, FALSE, MSTATUS_ENEMY);
- place_monster_aux(y, xval + 2, what[4], FALSE, FALSE, MSTATUS_ENEMY);
+ place_monster_aux(y, xval - 2, what[4], false, false, MSTATUS_ENEMY);
+ place_monster_aux(y, xval + 2, what[4], false, false, MSTATUS_ENEMY);
}
/* Above/Below the center monster */
for (x = xval - 1; x <= xval + 1; x++)
{
- place_monster_aux(yval + 1, x, what[5], FALSE, FALSE, MSTATUS_ENEMY);
- place_monster_aux(yval - 1, x, what[5], FALSE, FALSE, MSTATUS_ENEMY);
+ place_monster_aux(yval + 1, x, what[5], false, false, MSTATUS_ENEMY);
+ place_monster_aux(yval - 1, x, what[5], false, false, MSTATUS_ENEMY);
}
/* Next to the center monster */
- place_monster_aux(yval, xval + 1, what[6], FALSE, FALSE, MSTATUS_ENEMY);
- place_monster_aux(yval, xval - 1, what[6], FALSE, FALSE, MSTATUS_ENEMY);
+ place_monster_aux(yval, xval + 1, what[6], false, false, MSTATUS_ENEMY);
+ place_monster_aux(yval, xval - 1, what[6], false, false, MSTATUS_ENEMY);
/* Center monster */
- place_monster_aux(yval, xval, what[7], FALSE, FALSE, MSTATUS_ENEMY);
+ place_monster_aux(yval, xval, what[7], false, false, MSTATUS_ENEMY);
}
/*
@@ -3476,7 +3359,7 @@ static void build_vault(int yval, int xval, int ymax, int xmax, std::string cons
{
if (rand_int(100) < 75)
{
- place_object(y, x, FALSE, FALSE, OBJ_FOUND_VAULT);
+ place_object(y, x, false, false, OBJ_FOUND_VAULT);
}
else
{
@@ -3543,7 +3426,7 @@ static void build_vault(int yval, int xval, int ymax, int xmax, std::string cons
case '&':
{
monster_level = dun_level + 5;
- place_monster(y, x, TRUE, TRUE);
+ place_monster(y, x, true, true);
monster_level = dun_level;
break;
}
@@ -3552,7 +3435,7 @@ static void build_vault(int yval, int xval, int ymax, int xmax, std::string cons
case '@':
{
monster_level = dun_level + 11;
- place_monster(y, x, TRUE, TRUE);
+ place_monster(y, x, true, true);
monster_level = dun_level;
break;
}
@@ -3561,10 +3444,10 @@ static void build_vault(int yval, int xval, int ymax, int xmax, std::string cons
case '9':
{
monster_level = dun_level + 9;
- place_monster(y, x, TRUE, TRUE);
+ place_monster(y, x, true, true);
monster_level = dun_level;
object_level = dun_level + 7;
- place_object(y, x, TRUE, FALSE, OBJ_FOUND_VAULT);
+ place_object(y, x, true, false, OBJ_FOUND_VAULT);
object_level = dun_level;
break;
}
@@ -3573,10 +3456,10 @@ static void build_vault(int yval, int xval, int ymax, int xmax, std::string cons
case '8':
{
monster_level = dun_level + 40;
- place_monster(y, x, TRUE, TRUE);
+ place_monster(y, x, true, true);
monster_level = dun_level;
object_level = dun_level + 20;
- place_object(y, x, TRUE, TRUE, OBJ_FOUND_VAULT);
+ place_object(y, x, true, true, OBJ_FOUND_VAULT);
object_level = dun_level;
break;
}
@@ -3587,64 +3470,37 @@ static void build_vault(int yval, int xval, int ymax, int xmax, std::string cons
if (rand_int(100) < 50)
{
monster_level = dun_level + 3;
- place_monster(y, x, TRUE, TRUE);
+ place_monster(y, x, true, true);
monster_level = dun_level;
}
if (rand_int(100) < 50)
{
object_level = dun_level + 7;
- place_object(y, x, FALSE, FALSE, OBJ_FOUND_VAULT);
+ place_object(y, x, false, false, OBJ_FOUND_VAULT);
object_level = dun_level;
}
break;
}
- case 'p':
- {
- cave_set_feat(y, x, FEAT_PATTERN_START);
- break;
- }
-
case 'a':
- {
- cave_set_feat(y, x, FEAT_PATTERN_1);
- break;
- }
-
case 'b':
- {
- cave_set_feat(y, x, FEAT_PATTERN_2);
- break;
- }
-
case 'c':
- {
- cave_set_feat(y, x, FEAT_PATTERN_3);
- break;
- }
-
case 'd':
- {
- cave_set_feat(y, x, FEAT_PATTERN_4);
- break;
- }
-
case 'P':
- {
- cave_set_feat(y, x, FEAT_PATTERN_END);
- break;
- }
-
case 'B':
+ case 'p':
{
- cave_set_feat(y, x, FEAT_PATTERN_XTRA1);
+ // Guard against vaults containing "the pattern".
+ // There should be no vaults that do, but let's just
+ // make sure.
+ abort();
break;
}
case 'A':
{
object_level = dun_level + 12;
- place_object(y, x, TRUE, FALSE, OBJ_FOUND_VAULT);
+ place_object(y, x, true, false, OBJ_FOUND_VAULT);
object_level = dun_level;
break;
}
@@ -3707,7 +3563,7 @@ static void build_type7(int by0, int bx0)
/* Try to allocate space for room. If fails, exit */
int xval;
int yval;
- if (!room_alloc(v_ptr->wid, v_ptr->hgt, FALSE, by0, bx0, &xval, &yval))
+ if (!room_alloc(v_ptr->wid, v_ptr->hgt, false, by0, bx0, &xval, &yval))
{
if (options->cheat_room)
{
@@ -3739,7 +3595,7 @@ static void build_type7(int by0, int bx0)
if ((dun_level <= 50) ||
(randint((dun_level - 40) * (dun_level - 40) + 50) < 400))
{
- good_item_flag = TRUE;
+ good_item_flag = true;
}
/* Hack -- Build the vault */
@@ -3773,7 +3629,7 @@ static void build_type8(int by0, int bx0)
/* Try to allocate space for room. If fails, exit */
int xval;
int yval;
- if (!room_alloc(v_ptr->wid, v_ptr->hgt, FALSE, by0, bx0, &xval, &yval))
+ if (!room_alloc(v_ptr->wid, v_ptr->hgt, false, by0, bx0, &xval, &yval))
{
if (options->cheat_room)
{
@@ -3805,7 +3661,7 @@ static void build_type8(int by0, int bx0)
if ((dun_level <= 50) ||
(randint((dun_level - 40) * (dun_level - 40) + 50) < 400))
{
- good_item_flag = TRUE;
+ good_item_flag = true;
}
/* Hack -- Build the vault */
@@ -3828,7 +3684,7 @@ static void build_type9(int by0, int bx0)
rad = 2 + rand_int(8);
/* Try to allocate space for room. If fails, exit */
- if (!room_alloc(rad*2 + 1, rad*2 + 1, FALSE, by0, bx0, &x0, &y0)) return;
+ if (!room_alloc(rad*2 + 1, rad*2 + 1, false, by0, bx0, &x0, &y0)) return;
info = (randint(dun_level) <= 5) ? (CAVE_ROOM|CAVE_GLOW) : CAVE_ROOM;
@@ -3869,8 +3725,6 @@ static void store_height(int x, int y, int x0, int y0, byte val,
/* Store the value in height-map format */
/* Meant to be temporary, hence no cave_set_feat */
cave[y + y0 - yhsize][x + x0 - xhsize].feat = val;
-
- return;
}
@@ -4129,12 +3983,12 @@ void generate_hmap(int y0, int x0, int xsiz, int ysiz, int grd,
/*
* Convert from height-map back to the normal Angband cave format
*/
-static bool_ hack_isnt_wall(int y, int x, int cutoff)
+static bool hack_isnt_wall(int y, int x, int cutoff)
{
/* Already done */
if (cave[y][x].info & CAVE_ICKY)
{
- return (FALSE);
+ return false;
}
else
@@ -4146,14 +4000,14 @@ static bool_ hack_isnt_wall(int y, int x, int cutoff)
if (cave[y][x].feat <= cutoff)
{
place_floor(y, x);
- return (TRUE);
+ return true;
}
/* If greater than cutoff then is a wall */
else
{
cave_set_feat(y, x, feat_wall_outer);
- return (FALSE);
+ return false;
}
}
}
@@ -4200,8 +4054,8 @@ static void fill_hack(int y0, int x0, int y, int x, int xsize, int ysize,
}
-bool_ generate_fracave(int y0, int x0, int xsize, int ysize,
- int cutoff, bool_ light, bool_ room)
+bool generate_fracave(int y0, int x0, int xsize, int ysize,
+ int cutoff, bool light, bool room)
{
auto const &f_info = game->edit_data.f_info;
@@ -4234,7 +4088,7 @@ bool_ generate_fracave(int y0, int x0, int xsize, int ysize,
cave[y0 + y - yhsize][x0 + x - xhsize].info &= ~(CAVE_ICKY | CAVE_ROOM);
}
}
- return FALSE;
+ return false;
}
@@ -4428,7 +4282,7 @@ bool_ generate_fracave(int y0, int x0, int xsize, int ysize,
* holes in the dungeon), doesn't seem worth it.
*/
- return (TRUE);
+ return true;
}
@@ -4438,10 +4292,8 @@ bool_ generate_fracave(int y0, int x0, int xsize, int ysize,
static void build_cavern()
{
int grd, roug, cutoff, xsize, ysize, x0, y0;
- bool_ done, light, room;
- light = done = room = FALSE;
- if (dun_level <= randint(25)) light = TRUE;
+ bool const light = (dun_level <= randint(25));
/* Make a cave the size of the dungeon */
xsize = cur_wid - 1;
@@ -4453,6 +4305,7 @@ static void build_cavern()
xsize = x0 * 2;
ysize = y0 * 2;
+ bool done = false;
while (!done)
{
/* Testing values for these parameters: feel free to adjust */
@@ -4468,7 +4321,7 @@ static void build_cavern()
generate_hmap(y0, x0, xsize, ysize, grd, roug, cutoff);
/* Convert to normal format+ clean up*/
- done = generate_fracave(y0, x0, xsize, ysize, cutoff, light, room);
+ done = generate_fracave(y0, x0, xsize, ysize, cutoff, light, false);
}
}
@@ -4479,20 +4332,16 @@ static void build_type10(int by0, int bx0)
{
int grd, roug, cutoff, xsize, ysize, y0, x0;
- bool_ done, light, room;
-
/* Get size: note 'Evenness'*/
xsize = randint(22) * 2 + 6;
ysize = randint(15) * 2 + 6;
/* Try to allocate space for room. If fails, exit */
- if (!room_alloc(xsize + 1, ysize + 1, FALSE, by0, bx0, &x0, &y0)) return;
-
- light = done = FALSE;
- room = TRUE;
+ if (!room_alloc(xsize + 1, ysize + 1, false, by0, bx0, &x0, &y0)) return;
- if (dun_level <= randint(25)) light = TRUE;
+ bool const light = (dun_level <= randint(25));
+ bool done = false;
while (!done)
{
/*
@@ -4514,7 +4363,7 @@ static void build_type10(int by0, int bx0)
generate_hmap(y0, x0, xsize, ysize, grd, roug, cutoff);
/* Convert to normal format + clean up*/
- done = generate_fracave(y0, x0, xsize, ysize, cutoff, light, room);
+ done = generate_fracave(y0, x0, xsize, ysize, cutoff, light, true);
}
}
@@ -4665,27 +4514,27 @@ static void fill_treasure(int x1, int x2, int y1, int y2, int difficulty)
{
/* Meanest monster + treasure */
monster_level = dun_level + 40;
- place_monster(y, x, TRUE, TRUE);
+ place_monster(y, x, true, true);
monster_level = dun_level;
object_level = dun_level + 20;
- place_object(y, x, TRUE, FALSE, OBJ_FOUND_FLOOR);
+ place_object(y, x, true, false, OBJ_FOUND_FLOOR);
object_level = dun_level;
}
else if (value < 5)
{
/* Mean monster +treasure */
monster_level = dun_level + 20;
- place_monster(y, x, TRUE, TRUE);
+ place_monster(y, x, true, true);
monster_level = dun_level;
object_level = dun_level + 10;
- place_object(y, x, TRUE, FALSE, OBJ_FOUND_FLOOR);
+ place_object(y, x, true, false, OBJ_FOUND_FLOOR);
object_level = dun_level;
}
else if (value < 10)
{
/* Monster */
monster_level = dun_level + 9;
- place_monster(y, x, TRUE, TRUE);
+ place_monster(y, x, true, true);
monster_level = dun_level;
}
else if (value < 17)
@@ -4704,14 +4553,14 @@ static void fill_treasure(int x1, int x2, int y1, int y2, int difficulty)
/* Object or trap */
if (rand_int(100) < 25)
{
- place_object(y, x, FALSE, FALSE, OBJ_FOUND_FLOOR);
+ place_object(y, x, false, false, OBJ_FOUND_FLOOR);
}
}
else if (value < 30)
{
/* Monster */
monster_level = dun_level + 5;
- place_monster(y, x, TRUE, TRUE);
+ place_monster(y, x, true, true);
monster_level = dun_level;
}
else if (value < 40)
@@ -4720,13 +4569,13 @@ static void fill_treasure(int x1, int x2, int y1, int y2, int difficulty)
if (rand_int(100) < 50)
{
monster_level = dun_level + 3;
- place_monster(y, x, TRUE, TRUE);
+ place_monster(y, x, true, true);
monster_level = dun_level;
}
if (rand_int(100) < 50)
{
object_level = dun_level + 7;
- place_object(y, x, FALSE, FALSE, OBJ_FOUND_FLOOR);
+ place_object(y, x, false, false, OBJ_FOUND_FLOOR);
object_level = dun_level;
}
}
@@ -4741,7 +4590,7 @@ static void fill_treasure(int x1, int x2, int y1, int y2, int difficulty)
/* 20% monster, 40% trap, 20% object, 20% blank space */
if (rand_int(100) < 20)
{
- place_monster(y, x, TRUE, TRUE);
+ place_monster(y, x, true, true);
}
else if (rand_int(100) < 50)
{
@@ -4749,7 +4598,7 @@ static void fill_treasure(int x1, int x2, int y1, int y2, int difficulty)
}
else if (rand_int(100) < 50)
{
- place_object(y, x, FALSE, FALSE, OBJ_FOUND_FLOOR);
+ place_object(y, x, false, false, OBJ_FOUND_FLOOR);
}
}
@@ -4782,7 +4631,7 @@ static void build_bubble_vault(int x0, int y0, int xsize, int ysize)
int i, j, k, x = 0, y = 0;
u16b min1, min2, temp;
- bool_ done;
+ bool done;
/* Offset from center to top left hand corner */
int xhsize = xsize / 2;
@@ -4799,12 +4648,12 @@ static void build_bubble_vault(int x0, int y0, int xsize, int ysize)
for (i = 1; i < BUBBLENUM; i++)
{
- done = FALSE;
+ done = false;
/* Get center and check to see if it is unique */
for (k = 0; !done && (k < 2000); k++)
{
- done = TRUE;
+ done = true;
x = randint(xsize - 3) + 1;
y = randint(ysize - 3) + 1;
@@ -4812,7 +4661,7 @@ static void build_bubble_vault(int x0, int y0, int xsize, int ysize)
for (j = 0; j < i; j++)
{
/* Rough test to see if there is an overlap */
- if ((x == center[j].x) || (y == center[j].y)) done = FALSE;
+ if ((x == center[j].x) || (y == center[j].y)) done = false;
}
}
@@ -5046,7 +4895,6 @@ static void build_room_vault(int x0, int y0, int xsize, int ysize)
static void build_cave_vault(int x0, int y0, int xsiz, int ysiz)
{
int grd, roug, cutoff, xhsize, yhsize, xsize, ysize, x, y;
- bool_ done, light, room;
/* Round to make sizes even */
xhsize = xsiz / 2;
@@ -5059,9 +4907,7 @@ static void build_cave_vault(int x0, int y0, int xsiz, int ysiz)
msg_print("Cave Vault");
}
- light = done = FALSE;
- room = TRUE;
-
+ bool done = false;
while (!done)
{
/* Testing values for these parameters feel free to adjust */
@@ -5078,7 +4924,7 @@ static void build_cave_vault(int x0, int y0, int xsiz, int ysiz)
generate_hmap(y0, x0, xsize, ysize, grd, roug, cutoff);
/* Convert to normal format + clean up */
- done = generate_fracave(y0, x0, xsize, ysize, cutoff, light, room);
+ done = generate_fracave(y0, x0, xsize, ysize, cutoff, false, true);
}
/* Set icky flag because is a vault */
@@ -5220,7 +5066,7 @@ static void build_maze_vault(int x0, int y0, int xsize, int ysize)
int y, x, dy, dx;
int y1, x1, y2, x2;
int m, n, num_vertices;
- bool_ light;
+ bool light;
cave_type *c_ptr;
@@ -5669,13 +5515,13 @@ static void add_outer_wall(int x, int y, int light, int x1, int y1,
else if (cave[y][x].feat == FEAT_WALL_EXTRA)
{
cave[y][x].feat = feat_wall_outer;
- if (light == TRUE) cave[y][x].info |= CAVE_GLOW;
+ if (light == true) cave[y][x].info |= CAVE_GLOW;
}
/* Set bounding walls */
else if (cave[y][x].feat == FEAT_PERM_OUTER)
{
- if (light == TRUE) cave[y][x].info |= CAVE_GLOW;
+ if (light == true) cave[y][x].info |= CAVE_GLOW;
}
}
@@ -5782,7 +5628,7 @@ static void build_target_vault(int x0, int y0, int xsize, int ysize)
}
/* Find visible outer walls and set to be FEAT_OUTER */
- add_outer_wall(x0, y0, FALSE, x0 - rad - 1, y0 - rad - 1,
+ add_outer_wall(x0, y0, false, x0 - rad - 1, y0 - rad - 1,
x0 + rad + 1, y0 + rad + 1);
/* Add inner wall */
@@ -5858,7 +5704,7 @@ static void build_type11(int by0, int bx0)
ysize = randint(11) + 11;
/* Allocate in room_map. If will not fit, exit */
- if (!room_alloc(xsize + 2, ysize + 2, FALSE, by0, bx0, &x0, &y0)) return;
+ if (!room_alloc(xsize + 2, ysize + 2, false, by0, bx0, &x0, &y0)) return;
/*
* Boost the rating -- Higher than lesser vaults and lower than
@@ -5870,7 +5716,7 @@ static void build_type11(int by0, int bx0)
if ((dun_level <= 50) ||
(randint((dun_level - 40) * (dun_level - 40) + 1) < 400))
{
- good_item_flag = TRUE;
+ good_item_flag = true;
}
/* Select type of vault */
@@ -5945,7 +5791,7 @@ static void build_type11(int by0, int bx0)
static void build_type12(int by0, int bx0)
{
int light, rad, x, y, x0, y0;
- bool_ emptyflag = TRUE;
+ bool emptyflag = true;
int h1, h2, h3, h4;
/* Make a random metric */
@@ -5955,12 +5801,12 @@ static void build_type12(int by0, int bx0)
h4 = randint(32) - 16;
/* Occasional light */
- light = (randint(dun_level) <= 5) ? TRUE : FALSE;
+ light = (randint(dun_level) <= 5) ? true : false;
rad = randint(9);
/* Allocate in room_map. If will not fit, exit */
- if (!room_alloc(rad * 2 + 3, rad * 2 + 3, FALSE, by0, bx0, &x0, &y0)) return;
+ if (!room_alloc(rad * 2 + 3, rad * 2 + 3, false, by0, bx0, &x0, &y0)) return;
/* Make floor */
for (x = x0 - rad; x <= x0 + rad; x++)
@@ -6007,7 +5853,7 @@ static void build_type12(int by0, int bx0)
if (!get_is_floor(x, y))
{
/* Wall in the way */
- emptyflag = FALSE;
+ emptyflag = false;
}
}
}
@@ -6018,7 +5864,7 @@ static void build_type12(int by0, int bx0)
build_small_room(x0, y0);
/* Place a treasure in the vault */
- place_object(y0, x0, FALSE, FALSE, OBJ_FOUND_FLOOR);
+ place_object(y0, x0, false, false, OBJ_FOUND_FLOOR);
/* Let's guard the treasure well */
vault_monsters(y0, x0, rand_int(2) + 3);
@@ -6060,9 +5906,10 @@ static void build_type12(int by0, int bx0)
* FEAT_PERM_OUTER -- outer room walls (perma)
* FEAT_PERM_SOLID -- dungeon border (perma)
*/
-static void build_tunnel(int row1, int col1, int row2, int col2, bool_ water)
+static void build_tunnel(int row1, int col1, int row2, int col2, bool water)
{
auto const &d_info = game->edit_data.d_info;
+ auto const &dungeon_flags = game->dungeon_flags;
int i, y, x;
int tmp_row, tmp_col;
@@ -6070,7 +5917,7 @@ static void build_tunnel(int row1, int col1, int row2, int col2, bool_ water)
int start_row, start_col;
int main_loop_count = 0;
- bool_ door_flag = FALSE;
+ bool door_flag = false;
cave_type *c_ptr;
@@ -6216,7 +6063,7 @@ static void build_tunnel(int row1, int col1, int row2, int col2, bool_ water)
}
/* Allow door in next grid */
- door_flag = FALSE;
+ door_flag = false;
}
/* Handle corridor intersections or overlaps */
@@ -6238,7 +6085,7 @@ static void build_tunnel(int row1, int col1, int row2, int col2, bool_ water)
}
/* No door in next grid */
- door_flag = TRUE;
+ door_flag = true;
}
/* Hack -- allow pre-emptive tunnel termination */
@@ -6363,7 +6210,7 @@ static int next_to_corr(int y1, int x1)
*
* Assumes "in_bounds(y,x)"
*/
-static bool_ possible_doorway(int y, int x)
+static bool possible_doorway(int y, int x)
{
auto const &f_info = game->edit_data.f_info;
@@ -6374,19 +6221,19 @@ static bool_ possible_doorway(int y, int x)
if ((f_info[cave[y - 1][x].feat].flags & FF_WALL) &&
(f_info[cave[y + 1][x].feat].flags & FF_WALL))
{
- return (TRUE);
+ return true;
}
/* Check Horizontal */
if ((f_info[cave[y][x - 1].feat].flags & FF_WALL) &&
(f_info[cave[y][x + 1].feat].flags & FF_WALL))
{
- return (TRUE);
+ return true;
}
}
/* No doorway */
- return (FALSE);
+ return false;
}
@@ -6396,8 +6243,9 @@ static bool_ possible_doorway(int y, int x)
static void try_doors(int y, int x)
{
auto const &f_info = game->edit_data.f_info;
+ auto const &dungeon_flags = game->dungeon_flags;
- bool_ dir_ok[4];
+ bool dir_ok[4];
int i, k, n;
int yy, xx;
@@ -6414,7 +6262,7 @@ static void try_doors(int y, int x)
for (i = 0; i < 4; i++)
{
/* Assume NG */
- dir_ok[i] = FALSE;
+ dir_ok[i] = false;
/* Access location */
yy = y + ddy_ddd[i];
@@ -6433,7 +6281,7 @@ static void try_doors(int y, int x)
if (!possible_doorway(yy, xx)) continue;
/* Accept the direction */
- dir_ok[i] = TRUE;
+ dir_ok[i] = true;
/* Count good spots */
n++;
@@ -6467,11 +6315,11 @@ static void try_doors(int y, int x)
if (n == 4)
{
/* Clear OK flags XXX */
- for (i = 0; i < 4; i++) dir_ok[i] = FALSE;
+ for (i = 0; i < 4; i++) dir_ok[i] = false;
/* Put one or two locked doors */
- dir_ok[rand_int(4)] = TRUE;
- dir_ok[rand_int(4)] = TRUE;
+ dir_ok[rand_int(4)] = true;
+ dir_ok[rand_int(4)] = true;
}
/* A T-shaped intersection or two possible doorways */
@@ -6483,7 +6331,7 @@ static void try_doors(int y, int x)
for (i = 0; i < 4; i++)
{
/* Reject all but k'th OK direction */
- if (dir_ok[i] && (k-- != 0)) dir_ok[i] = FALSE;
+ if (dir_ok[i] && (k-- != 0)) dir_ok[i] = false;
}
}
@@ -6510,13 +6358,13 @@ static void try_doors(int y, int x)
* Note that we restrict the number of "crowded" rooms to reduce
* the chance of overflowing the monster list during level creation.
*/
-static bool_ room_build(int y, int x, int typ)
+static bool room_build(int y, int x, int typ)
{
/* Restrict level */
- if ((dun_level < roomdep[typ]) && !options->ironman_rooms) return (FALSE);
+ if ((dun_level < roomdep[typ]) && !options->ironman_rooms) return false;
/* Restrict "crowded" rooms */
- if (dun->crowded && ((typ == 5) || (typ == 6))) return (FALSE);
+ if (dun->crowded && ((typ == 5) || (typ == 6))) return false;
/* Build a room */
switch (typ)
@@ -6561,17 +6409,17 @@ static bool_ room_build(int y, int x, int typ)
/* Paranoia */
default:
- return (FALSE);
+ return false;
}
/* Success */
- return (TRUE);
+ return true;
}
/*
* Set level boundaries
*/
-static void set_bounders(bool_ empty_level)
+static void set_bounders(bool empty_level)
{
int y, x;
@@ -6621,23 +6469,24 @@ static void set_bounders(bool_ empty_level)
}
/* Needed to refill empty levels */
-static void fill_level(bool_ use_floor, byte smooth);
+static void fill_level(bool use_floor, byte smooth);
/*
* Generate a normal dungeon level
*/
-bool_ level_generate_dungeon()
+bool level_generate_dungeon()
{
auto const &d_info = game->edit_data.d_info;
+ auto const &dungeon_flags = game->dungeon_flags;
int i, k, y, x, y1, x1, branch = get_branch();
auto d_ptr = &d_info[dungeon_type];
int max_vault_ok = 2;
- bool_ destroyed = FALSE;
- bool_ empty_level = FALSE;
- bool_ cavern = FALSE;
+ bool destroyed = false;
+ bool empty_level = false;
+ bool cavern = false;
s16b town_level = 0;
/* Is it a town level ? */
@@ -6650,7 +6499,7 @@ bool_ level_generate_dungeon()
if ((dungeon_flags & DF_EMPTY) ||
(options->empty_levels && (rand_int(EMPTY_LEVEL) == 0)))
{
- empty_level = TRUE;
+ empty_level = true;
if (options->cheat_room || p_ptr->precognition)
{
@@ -6664,7 +6513,7 @@ bool_ level_generate_dungeon()
/* Possible cavern */
if ((dungeon_flags & DF_CAVERN) && (rand_int(dun_level / 2) > DUN_CAVERN))
{
- cavern = TRUE;
+ cavern = true;
/* Make a large fractal cave in the middle of the dungeon */
if (options->cheat_room)
@@ -6678,17 +6527,17 @@ bool_ level_generate_dungeon()
/* Possible "destroyed" level */
if ((dun_level > 10) && (rand_int(DUN_DEST) == 0))
{
- destroyed = TRUE;
+ destroyed = true;
}
/* Hack -- No destroyed "quest" levels */
- if (is_quest(dun_level)) destroyed = FALSE;
+ if (is_quest(dun_level)) destroyed = false;
/* Hack -- No destroyed "small" levels */
- if ((cur_wid != MAX_WID) || (cur_hgt != MAX_HGT)) destroyed = FALSE;
+ if ((cur_wid != MAX_WID) || (cur_hgt != MAX_HGT)) destroyed = false;
/* Hack -- No destroyed levels */
- if (dungeon_flags & DF_NO_DESTROY) destroyed = FALSE;
+ if (dungeon_flags & DF_NO_DESTROY) destroyed = false;
/* Actual maximum number of rooms on this level */
dun->row_rooms = cur_hgt / BLOCK_HGT;
@@ -6700,12 +6549,12 @@ bool_ level_generate_dungeon()
{
for (x = 0; x < dun->col_rooms; x++)
{
- dun->room_map[y][x] = FALSE;
+ dun->room_map[y][x] = false;
}
}
/* No "crowded" rooms yet */
- dun->crowded = FALSE;
+ dun->crowded = false;
/* No rooms yet */
dun->cent_n = 0;
@@ -6895,7 +6744,7 @@ bool_ level_generate_dungeon()
for (i = 0; i < dun->cent_n; i++)
{
/* Connect the room to the previous room */
- build_tunnel(dun->cent[i].y, dun->cent[i].x, y, x, FALSE);
+ build_tunnel(dun->cent[i].y, dun->cent[i].x, y, x, false);
/* Remember the "previous" room */
y = dun->cent[i].y;
@@ -6925,7 +6774,7 @@ bool_ level_generate_dungeon()
try_doors(y, x);
}
- if (strcmp(game_module, "ToME") == 0)
+ if (equals(game_module, "ToME"))
{
/* Hack -- Add some magma streamers */
if ((dungeon_type == DUNGEON_MORDOR) || (dungeon_type == DUNGEON_ANGBAND))
@@ -6982,7 +6831,7 @@ bool_ level_generate_dungeon()
if (dungeon_flags & DF_WATER_RIVERS)
{
int max = 3 + rand_int(2);
- bool_ said = FALSE;
+ bool said = false;
for (i = 0; i < max; i++)
{
@@ -6993,7 +6842,7 @@ bool_ level_generate_dungeon()
{
msg_print("Rivers of water.");
}
- said = TRUE;
+ said = true;
}
}
}
@@ -7001,7 +6850,7 @@ bool_ level_generate_dungeon()
if (dungeon_flags & DF_LAVA_RIVERS)
{
int max = 2 + rand_int(2);
- bool_ said = FALSE;
+ bool said = false;
for (i = 0; i < max; i++)
{
@@ -7012,7 +6861,7 @@ bool_ level_generate_dungeon()
{
msg_print("Rivers of lava.");
}
- said = TRUE;
+ said = true;
}
}
}
@@ -7123,9 +6972,11 @@ bool_ level_generate_dungeon()
/* Determine the character location */
if (!new_player_spot(branch))
- return FALSE;
+ {
+ return false;
+ }
- return TRUE;
+ return true;
}
/*
@@ -7260,7 +7111,7 @@ static void init_feat_info()
/*
* Fill a level with wall type specified in A: or L: line of d_info.txt
*
- * 'use_floor', when it is TRUE, tells the function to use floor type
+ * 'use_floor', when it is true, tells the function to use floor type
* terrains (L:) instead of walls (A:).
*
* Filling behaviour can be controlled by the second parameter 'smooth',
@@ -7292,7 +7143,7 @@ static void init_feat_info()
*/
#define MAX_SHIFTS 14
-static void fill_level(bool_ use_floor, byte smooth)
+static void fill_level(bool use_floor, byte smooth)
{
auto const &d_info = game->edit_data.d_info;
@@ -7383,7 +7234,7 @@ static void fill_level(bool_ use_floor, byte smooth)
/* Repeat subdivision until all the grids are filled in */
while ((step = step >> 1) > 0)
{
- bool_ y_even, x_even;
+ bool y_even, x_even;
s16b y_wrap, x_wrap;
s16b y_sel, x_sel;
u32b selector = 0;
@@ -7393,7 +7244,7 @@ static void fill_level(bool_ use_floor, byte smooth)
x_wrap = ((cur_wid - 1) / (step * 2)) * (step * 2);
/* Initialise vertical phase */
- y_even = 0;
+ y_even = false;
for (y = 0; y < cur_hgt; y += step)
{
@@ -7401,7 +7252,7 @@ static void fill_level(bool_ use_floor, byte smooth)
y_even = !y_even;
/* Initialise horizontal phase */
- x_even = 0;
+ x_even = false;
for (x = 0; x < cur_wid; x += step)
{
@@ -7546,31 +7397,23 @@ static void supersize_grid_tile(int sy, int sx, int ty, int tx)
*
* Note that "dun_body" adds about 4000 bytes of memory to the stack.
*/
-static bool_ cave_gen()
+static bool cave_gen()
{
auto const &d_info = game->edit_data.d_info;
auto const &r_info = game->edit_data.r_info;
auto const &a_info = game->edit_data.a_info;
auto &k_info = game->edit_data.k_info;
auto &alloc = game->alloc;
+ auto const &dungeon_flags = game->dungeon_flags;
auto d_ptr = &d_info[dungeon_type];
int max_vault_ok = 2;
- bool_ empty_level = FALSE;
-
- level_generator_type *generator;
+ bool empty_level = false;
dun_data dun_body;
- char generator_name[100];
-
- if (!get_dungeon_generator(generator_name))
- {
- strnfmt(generator_name, sizeof(generator_name)-1, "%s", d_ptr->generator.c_str());
- }
-
/*
* We generate a double dungeon. First we should halve the desired
* width/height, generate the dungeon normally, then double it
@@ -7586,7 +7429,7 @@ static bool_ cave_gen()
init_feat_info();
/* Set the correct monster hook */
- set_mon_num_hook();
+ reset_get_monster_hook();
/* Prepare allocation table */
get_mon_num_prep();
@@ -7608,19 +7451,12 @@ static bool_ cave_gen()
set_bounders(empty_level);
/*
- * Call the good level generator
+ * Call level generator
*/
- generator = level_generators;
- while (generator)
+ auto &generator = game->level_generators.at(d_ptr->generator);
+ if (!generator())
{
- if (!strcmp(generator->name, generator_name))
- {
- if (!generator->generator())
- return FALSE;
- break;
- }
-
- generator = generator->next;
+ return false;
}
/* Generate stairs */
@@ -7697,7 +7533,7 @@ static bool_ cave_gen()
/* Put some monsters in the dungeon */
for (i = i + k; i > 0; i--)
{
- alloc_monster(0, TRUE);
+ alloc_monster(0, true);
}
}
@@ -7714,7 +7550,7 @@ static bool_ cave_gen()
if ((!fates[i].serious) && (randint(2) != 1)) continue;
/* Player meets his/her fate now... */
- fate_flag = TRUE;
+ fate_flag = true;
switch (fates[i].fate)
{
@@ -7731,7 +7567,7 @@ static bool_ cave_gen()
object_prep(q_ptr, fates[i].o_idx);
/* Mega-Hack */
- apply_magic(q_ptr, dun_level, TRUE, TRUE, fates[i].serious);
+ apply_magic(q_ptr, dun_level, true, true, fates[i].serious);
get_pos_player(10, &oy, &ox);
@@ -7739,7 +7575,7 @@ static bool_ cave_gen()
drop_near(q_ptr, -1, oy, ox);
/* Make it icky */
- fates[i].icky = TRUE;
+ fates[i].icky = true;
break;
}
case FATE_FIND_R:
@@ -7751,7 +7587,7 @@ static bool_ cave_gen()
place_monster_one(oy, ox, fates[i].r_idx, 0, fates[i].serious, MSTATUS_ENEMY);
- fates[i].icky = TRUE;
+ fates[i].icky = true;
break;
}
case FATE_FIND_A:
@@ -7769,7 +7605,7 @@ static bool_ cave_gen()
s16b k_idx;
/* Apply restriction */
- get_obj_num_hook = kind_is_artifactable;
+ get_object_hook = kind_is_artifactable;
/* Object level a la find object fates */
obj_lev = max_dlv[dungeon_type] + randint(10);
@@ -7781,7 +7617,7 @@ static bool_ cave_gen()
k_idx = get_obj_num(obj_lev);
/* Reset restriction */
- get_obj_num_hook = kind_is_legal;
+ get_object_hook = kind_is_legal;
/* Invalidate the allocation table */
alloc.kind_table_valid = false;
@@ -7796,7 +7632,7 @@ static bool_ cave_gen()
object_prep(q_ptr, k_idx);
/* SoAC it */
- create_artifact(q_ptr, FALSE, TRUE);
+ create_artifact(q_ptr, false, true);
/* Drop the artifact from heaven */
drop_near(q_ptr, -1, oy, ox);
@@ -7823,13 +7659,13 @@ static bool_ cave_gen()
/* Save the name */
q_ptr->name1 = fates[i].a_idx;
- apply_magic(q_ptr, -1, TRUE, TRUE, TRUE);
+ apply_magic(q_ptr, -1, true, true, true);
/* Drop the artifact from heaven */
drop_near(q_ptr, -1, oy, ox);
}
- fates[i].icky = TRUE;
+ fates[i].icky = true;
break;
}
}
@@ -7842,12 +7678,12 @@ static bool_ cave_gen()
{
case FATE_FIND_A:
{
- if (a_info[fates[i].a_idx].cur_num == 1) fates[i].icky = TRUE;
+ if (a_info[fates[i].a_idx].cur_num == 1) fates[i].icky = true;
break;
}
case FATE_FIND_R:
{
- if ((r_info[fates[i].r_idx].cur_num == 1) && (r_info[fates[i].r_idx].flags & RF_UNIQUE)) fates[i].icky = TRUE;
+ if ((r_info[fates[i].r_idx].cur_num == 1) && (r_info[fates[i].r_idx].flags & RF_UNIQUE)) fates[i].icky = true;
break;
}
}
@@ -7900,9 +7736,9 @@ static bool_ cave_gen()
}
/* Place the guardian */
- m_allow_special[d_ptr->final_guardian] = TRUE;
- place_monster_one(oy, ox, d_ptr->final_guardian, 0, FALSE, MSTATUS_ENEMY);
- m_allow_special[d_ptr->final_guardian] = FALSE;
+ m_allow_special[d_ptr->final_guardian] = true;
+ place_monster_one(oy, ox, d_ptr->final_guardian, 0, false, MSTATUS_ENEMY);
+ m_allow_special[d_ptr->final_guardian] = false;
m_idx = cave[oy][ox].m_idx;
@@ -7926,7 +7762,7 @@ static bool_ cave_gen()
/* Proceed only if there's an object slot available */
if (o_idx)
{
- a_allow_special[d_ptr->final_artifact] = TRUE;
+ a_allow_special[d_ptr->final_artifact] = true;
/* Get local object */
q_ptr = &forge;
@@ -7944,7 +7780,7 @@ static bool_ cave_gen()
q_ptr->name1 = d_ptr->final_artifact;
/* Actually create it */
- apply_magic(q_ptr, -1, TRUE, TRUE, TRUE);
+ apply_magic(q_ptr, -1, true, true, true);
/* Where it is found ? */
q_ptr->found = OBJ_FOUND_MONSTER;
@@ -7953,7 +7789,7 @@ static bool_ cave_gen()
q_ptr->found_aux3 = dungeon_type;
q_ptr->found_aux4 = level_or_feat(dungeon_type, dun_level);
- a_allow_special[d_ptr->final_artifact] = FALSE;
+ a_allow_special[d_ptr->final_artifact] = false;
/* Get the item */
o_ptr = &o_list[o_idx];
@@ -7970,53 +7806,54 @@ static bool_ cave_gen()
}
}
- if (m_idx && d_ptr->final_object &&
- (k_info[d_ptr->final_object].artifact == FALSE))
+ if (m_idx && d_ptr->final_object)
{
- object_type *q_ptr, forge, *o_ptr;
- int o_idx;
+ auto k_ptr = k_info.at(d_ptr->final_object);
- /* Get new object */
- o_idx = o_pop();
-
- /* Proceed only if there's an object slot available */
- if (o_idx)
+ if (k_ptr->artifact == false)
{
- /* Get local object */
- q_ptr = &forge;
+ /* Get new object */
+ int o_idx = o_pop();
- k_allow_special[d_ptr->final_object] = TRUE;
+ /* Proceed only if there's an object slot available */
+ if (o_idx)
+ {
+ /* Get local object */
+ object_type forge;
+ object_type *q_ptr = &forge;
- /* Wipe the object */
- object_wipe(q_ptr);
+ k_info[d_ptr->final_object]->allow_special = true;
- /* Create the final object */
- object_prep(q_ptr, d_ptr->final_object);
- apply_magic(q_ptr, 1, FALSE, FALSE, FALSE);
+ /* Wipe the object */
+ object_wipe(q_ptr);
- /* Where it is found ? */
- q_ptr->found = OBJ_FOUND_MONSTER;
- q_ptr->found_aux1 = d_ptr->final_guardian;
- q_ptr->found_aux2 = 0;
- q_ptr->found_aux3 = dungeon_type;
- q_ptr->found_aux4 = level_or_feat(dungeon_type, dun_level);
+ /* Create the final object */
+ object_prep(q_ptr, d_ptr->final_object);
+ apply_magic(q_ptr, 1, false, false, false);
- k_allow_special[d_ptr->final_object] = FALSE;
+ /* Where it is found ? */
+ q_ptr->found = OBJ_FOUND_MONSTER;
+ q_ptr->found_aux1 = d_ptr->final_guardian;
+ q_ptr->found_aux2 = 0;
+ q_ptr->found_aux3 = dungeon_type;
+ q_ptr->found_aux4 = level_or_feat(dungeon_type, dun_level);
- k_info[d_ptr->final_object].artifact = TRUE;
+ k_ptr->allow_special = false;
+ k_ptr->artifact = true;
- /* Get the item */
- o_ptr = &o_list[o_idx];
+ /* Get the item */
+ object_type *o_ptr = &o_list[o_idx];
- /* Structure copy */
- object_copy(o_ptr, q_ptr);
+ /* Structure copy */
+ object_copy(o_ptr, q_ptr);
- /* Build a stack */
- o_ptr->held_m_idx = m_idx;
- o_ptr->ix = 0;
- o_ptr->iy = 0;
+ /* Build a stack */
+ o_ptr->held_m_idx = m_idx;
+ o_ptr->ix = 0;
+ o_ptr->iy = 0;
- m_list[m_idx].hold_o_idxs.push_back(o_idx);
+ m_list[m_idx].hold_o_idxs.push_back(o_idx);
+ }
}
}
}
@@ -8055,7 +7892,7 @@ static bool_ cave_gen()
p_ptr->px *= 2;
}
- return TRUE;
+ return true;
}
@@ -8067,7 +7904,7 @@ static bool_ cave_gen()
/* Mega-Hack */
#define REGEN_HACK 0x02
-bool_ build_special_level()
+bool build_special_level()
{
auto const &d_info = game->edit_data.d_info;
auto &level_markers = game->level_markers;
@@ -8075,21 +7912,20 @@ bool_ build_special_level()
/* No special levels on the surface */
if (!dun_level)
{
- return FALSE;
+ return false;
}
auto const level = dun_level - d_info[dungeon_type].mindepth;
- char buf[80];
-
- if ((!get_dungeon_save(buf)) && !is_normal_level(level_markers[level][dungeon_type]))
+ if ((!get_dungeon_save_extension()) && !is_normal_level(level_markers[level][dungeon_type]))
{
- return FALSE;
+ return false;
}
- if (!get_dungeon_special(buf))
+ auto map_name = get_dungeon_map_name();
+ if (!map_name)
{
- return FALSE;
+ return false;
}
/* Big town */
@@ -8113,7 +7949,7 @@ bool_ build_special_level()
}
}
/* Set the correct monster hook */
- set_mon_num_hook();
+ reset_get_monster_hook();
/* Prepare allocation table */
get_mon_num_prep();
@@ -8121,13 +7957,13 @@ bool_ build_special_level()
init_flags = INIT_CREATE_DUNGEON | INIT_POSITION;
int ystart = 2;
int xstart = 2;
- process_dungeon_file(buf, &ystart, &xstart, cur_hgt, cur_wid, TRUE, TRUE);
+ process_dungeon_file(map_name->c_str(), &ystart, &xstart, cur_hgt, cur_wid, true, true);
game->level_markers[level][dungeon_type] = level_marker::REGENERATE;
game->generate_special_feeling = true;
/* Special feeling because it's special */
- good_item_flag = TRUE;
+ good_item_flag = true;
/*
* Hack -- It's better/more dangerous than a greater vault.
@@ -8135,7 +7971,7 @@ bool_ build_special_level()
*/
rating += 40;
- return TRUE;
+ return true;
}
/*
@@ -8160,12 +7996,11 @@ static void wipe_special_level()
auto const level = dun_level - d_info[dungeon_type].mindepth;
/* No special level at this depth? */
- char buf[80];
- if ((!get_dungeon_save(buf)) && !is_normal_level(level_markers[level][dungeon_type]))
+ if ((!get_dungeon_save_extension()) && !is_normal_level(level_markers[level][dungeon_type]))
{
return;
}
- if (!get_dungeon_special(buf))
+ if (!get_dungeon_map_name())
{
return;
}
@@ -8198,12 +8033,11 @@ static void finalise_special_level()
auto const level = dun_level - d_info[dungeon_type].mindepth;
/* No special level at this depth? */
- char buf[80];
- if ((!get_dungeon_save(buf)) && !is_normal_level(level_markers[level][dungeon_type]))
+ if ((!get_dungeon_save_extension()) && !is_normal_level(level_markers[level][dungeon_type]))
{
return;
}
- if (!get_dungeon_special(buf))
+ if (!get_dungeon_map_name())
{
return;
}
@@ -8221,11 +8055,11 @@ static void finalise_special_level()
static void generate_grid_mana()
{
int y, x, mana, mult;
- bool_ xtra_magic = FALSE;
+ bool xtra_magic = false;
if (randint(XTRA_MAGIC) == 1)
{
- xtra_magic = TRUE;
+ xtra_magic = true;
if (options->cheat_room || p_ptr->precognition)
{
@@ -8256,6 +8090,29 @@ static void generate_grid_mana()
/*
+ * Clear dungeon
+ */
+static void clear_dungeon()
+{
+ /* Clear any lasting effects */
+ game->lasting_effects.clear();
+
+ /* Start with a blank cave */
+ for (int y = 0; y < MAX_HGT; y++)
+ {
+ for (int x = 0; x < MAX_WID; x++)
+ {
+ /* Wipe */
+ cave[y][x].wipe();
+
+ /* No features */
+ cave_set_feat(y, x, FEAT_PERM_INNER);
+ }
+ }
+}
+
+
+/*
* Generates a random dungeon level -RAK-
*
* Hack -- regenerate any "overflow" levels
@@ -8267,16 +8124,16 @@ void generate_cave()
auto const &d_info = game->edit_data.d_info;
auto &a_info = game->edit_data.a_info;
auto const &level_markers = game->level_markers;
+ auto &dungeon_flags = game->dungeon_flags;
auto d_ptr = &d_info[dungeon_type];
int tester_1, tester_2;
- int y, x, num, i;
- bool_ loaded = FALSE;
- char buf[80];
+ int num, i;
+ bool loaded = false;
s16b town_level = 0;
/* The dungeon is not ready */
- character_dungeon = FALSE;
+ character_dungeon = false;
game->generate_special_feeling = false;
/* Initialize the flags with the basic dungeon flags */
@@ -8308,64 +8165,32 @@ void generate_cave()
process_hooks_new(HOOK_GEN_LEVEL_BEGIN, NULL, NULL);
/* Try to load a saved level */
- if (get_dungeon_save(buf))
+ if (auto ext = get_dungeon_save_extension())
{
- /* No effects */
- for (i = 0; i < MAX_EFFECTS; i++)
- {
- effects[i].time = 0;
- }
-
- /* Start with a blank cave */
- for (y = 0; y < MAX_HGT; y++)
- {
- for (x = 0; x < MAX_WID; x++)
- {
- /* Wipe */
- cave[y][x].wipe();
-
- /* No features */
- cave_set_feat(y, x, FEAT_PERM_INNER);
- }
- }
-
- loaded = load_dungeon(buf);
+ /* Clear */
+ clear_dungeon();
+ /* Load */
+ loaded = load_dungeon(*ext);
}
/* No saved level -- generate new one */
if (!loaded)
{
auto const level = dun_level - d_info[dungeon_type].mindepth;
- if (!get_dungeon_special(buf) || is_normal_level(level_markers[level][dungeon_type]))
+ if (!get_dungeon_map_name() || is_normal_level(level_markers[level][dungeon_type]))
{
- get_level_flags();
+ dungeon_flags |= get_level_flags();
}
/* Generate */
- for (num = 0; TRUE; num++)
+ for (num = 0; true; num++)
{
- bool_ okay = TRUE;
-
- cptr why = NULL;
-
- /* No effects */
- for (i = 0; i < MAX_EFFECTS; i++)
- {
- effects[i].time = 0;
- }
+ bool okay = true;
- /* Start with a blank cave */
- for (y = 0; y < MAX_HGT; y++)
- {
- for (x = 0; x < MAX_WID; x++)
- {
- /* Wipe */
- cave[y][x].wipe();
+ const char *why = NULL;
- /* No features */
- cave_set_feat(y, x, FEAT_PERM_INNER);
- }
- }
+ /* Clear */
+ clear_dungeon();
/* XXX XXX XXX XXX */
@@ -8391,21 +8216,24 @@ void generate_cave()
object_level = dun_level;
/* Nothing special here yet */
- good_item_flag = FALSE;
+ good_item_flag = false;
/* Nothing good here yet */
rating = 0;
/* No ambush here yet */
- ambush_flag = FALSE;
+ ambush_flag = false;
/* No fated level here yet */
- fate_flag = FALSE;
+ fate_flag = false;
/* Quest levels -KMW- */
if (p_ptr->inside_quest)
{
- process_hooks_new(HOOK_GEN_QUEST, NULL, NULL);
+ struct hook_quest_gen_in in = {
+ game->dungeon_flags
+ };
+ process_hooks_new(HOOK_GEN_QUEST, &in, NULL);
}
/* Special levels */
@@ -8444,7 +8272,7 @@ void generate_cave()
}
- okay = TRUE;
+ okay = true;
}
/* Build a dungeon level */
@@ -8551,7 +8379,7 @@ void generate_cave()
if (!cave_gen())
{
why = "could not place player";
- okay = FALSE;
+ okay = false;
}
}
@@ -8583,7 +8411,7 @@ void generate_cave()
why = "too many objects";
/* Message */
- okay = FALSE;
+ okay = false;
}
/* Prevent monster over-flow */
@@ -8593,7 +8421,7 @@ void generate_cave()
why = "too many monsters";
/* Message */
- okay = FALSE;
+ okay = false;
}
/* Mega-Hack -- "auto-scum" */
@@ -8615,7 +8443,7 @@ void generate_cave()
}
/* Try again */
- okay = FALSE;
+ okay = false;
}
}
@@ -8632,7 +8460,7 @@ void generate_cave()
wipe_m_list();
/* Clear the fate icky flags */
- for (i = 0; i < MAX_FATES; i++) fates[i].icky = FALSE;
+ for (i = 0; i < MAX_FATES; i++) fates[i].icky = false;
/*
* Mega-Hack -- Reset special level flag if necessary
@@ -8662,7 +8490,7 @@ void generate_cave()
a_info[fates[i].a_idx].cur_num = 1;
}
fates[i].fate = FATE_NONE;
- fates[i].icky = FALSE;
+ fates[i].icky = false;
}
}
@@ -8681,7 +8509,7 @@ void generate_cave()
}
/* The dungeon is ready */
- character_dungeon = TRUE;
+ character_dungeon = true;
/* Remember when this level was "created" */
old_turn = turn;
diff --git a/src/generate.hpp b/src/generate.hpp
index a21ba069..d3d2b9b5 100644
--- a/src/generate.hpp
+++ b/src/generate.hpp
@@ -1,12 +1,12 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
-bool_ new_player_spot(int branch);
-void add_level_generator(cptr name, bool_ (*generator)());
-bool_ level_generate_dungeon();
-bool_ generate_fracave(int y0, int x0,int xsize,int ysize,int cutoff,bool_ light,bool_ room);
+bool new_player_spot(int branch);
+void add_level_generator(const char *name, bool (*generator)());
+bool level_generate_dungeon();
+bool generate_fracave(int y0, int x0, int xsize, int ysize, int cutoff, bool light, bool room);
void generate_hmap(int y0, int x0,int xsiz,int ysiz,int grd,int roug,int cutoff);
-bool_ room_alloc(int x,int y,bool_ crowded,int by0,int bx0,int *xx,int *yy);
+bool room_alloc(int x,int y,bool crowded,int by0,int bx0,int *xx,int *yy);
void generate_cave();
void build_rectangle(int y1, int x1, int y2, int x2, int feat, int info);
diff --git a/src/gods.cc b/src/gods.cc
index 82d8d300..41b99233 100644
--- a/src/gods.cc
+++ b/src/gods.cc
@@ -13,13 +13,15 @@
#include "skill_type.hpp"
#include "stats.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "xtra2.hpp"
+#include "z-form.hpp"
+#include <boost/algorithm/string/predicate.hpp>
#include <cassert>
+using boost::algorithm::equals;
+
/*
* Add amt piety is god is god
*/
@@ -54,7 +56,7 @@ void abandon_god(int god)
/*
* Check if god may be followed by player
*/
-static bool_ may_follow_god(int god)
+static bool may_follow_god(int god)
{
if (god == GOD_MELKOR)
{
@@ -67,18 +69,18 @@ static bool_ may_follow_god(int god)
{
msg_print("The One Ring has corrupted "
"you, and you are rejected.");
- return FALSE;
+ return false;
}
}
}
/* Default is to allow */
- return TRUE;
+ return true;
}
/*
* Get a religion
*/
-void follow_god(int god, bool_ silent)
+void follow_god(int god, bool silent)
{
auto &s_info = game->s_info;
@@ -112,7 +114,7 @@ void follow_god(int god, bool_ silent)
/*
* Show religious info.
*/
-bool_ show_god_info()
+bool show_god_info()
{
int pgod = p_ptr->pgod;
@@ -122,7 +124,7 @@ bool_ show_god_info()
{
msg_print("You don't worship anyone.");
msg_print(NULL);
- return FALSE;
+ return false;
}
else
{
@@ -132,21 +134,19 @@ bool_ show_god_info()
msg_print(NULL);
- character_icky = TRUE;
- Term_save();
+ screen_save_no_flush();
text_out(format("You worship %s. ", d_ptr->name));
- for (i = 0; (i < 10) && (strcmp(d_ptr->desc[i], "")); i++)
+ for (i = 0; (i < 10) && (!equals(d_ptr->desc[i], "")); i++)
text_out(d_ptr->desc[i]);
text_out("\n");
inkey();
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
}
- return TRUE;
+ return true;
}
/*
@@ -178,7 +178,7 @@ deity_type *god_at(byte god_idx)
/*
* Check if god is enabled for the current module
*/
-bool_ god_enabled(struct deity_type *deity)
+bool god_enabled(struct deity_type *deity)
{
int i;
@@ -186,15 +186,15 @@ bool_ god_enabled(struct deity_type *deity)
{
if (deity->modules[i] == game_module_idx)
{
- return TRUE;
+ return true;
}
}
/* Not enabled */
- return FALSE;
+ return false;
}
/* Find a god by name */
-int find_god(cptr name)
+int find_god(const char *name)
{
int i;
@@ -203,7 +203,7 @@ int find_god(cptr name)
/* The name matches and god is "enabled" for the
current module. */
if (god_enabled(&deity_info[i]) &&
- streq(deity_info[i].name, name))
+ equals(deity_info[i].name, name))
{
return (i);
}
diff --git a/src/gods.hpp b/src/gods.hpp
index 2a5f2bb5..f8e4ca9a 100644
--- a/src/gods.hpp
+++ b/src/gods.hpp
@@ -1,13 +1,13 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void inc_piety(int god, s32b amt);
void abandon_god(int god);
int wisdom_scale(int max);
-int find_god(cptr name);
-void follow_god(int god, bool_ silent);
-bool_ god_enabled(struct deity_type *deity);
+int find_god(const char *name);
+void follow_god(int god, bool silent);
+bool god_enabled(struct deity_type *deity);
deity_type *god_at(byte god_idx);
-bool_ show_god_info();
+bool show_god_info();
bool praying_to(int god);
diff --git a/src/h-basic.h b/src/h-basic.h
deleted file mode 100644
index a65780a5..00000000
--- a/src/h-basic.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * The most basic "include" file.
- *
- * This file simply includes other low level header files.
- */
-
-/* System Configuration */
-#include "h-config.h"
-
-/* System includes/externs */
-#include "h-system.h"
-
-/* Basic types */
-#include "h-type.h"
-
-/* Basic constants and macros */
-#include "h-define.h"
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/src/h-basic.hpp b/src/h-basic.hpp
new file mode 100644
index 00000000..a9a533fe
--- /dev/null
+++ b/src/h-basic.hpp
@@ -0,0 +1,134 @@
+#pragma once
+
+#include <cstdint>
+
+/*
+ * Choose the hardware, operating system, and compiler.
+ * Also, choose various "system level" compilation options.
+ * A lot of these definitions take effect in "h-system.h"
+ *
+ * Note that you may find it simpler to define some of these
+ * options in the "Makefile", especially any options describing
+ * what "system" is being used.
+ */
+
+/*
+ * Extract the "WINDOWS" flag from the compiler
+ */
+#if defined(_Windows) || defined(__WINDOWS__) || \
+ defined(__WIN32__) || defined(WIN32) || \
+ defined(__WINNT__) || defined(__NT__)
+# ifndef WINDOWS
+# define WINDOWS
+# endif
+#endif
+
+
+
+/*
+ * OPTION: set "SET_UID" if the machine is a "multi-user" machine.
+ * This option is used to verify the use of "uids" and "gids" for
+ * various "Unix" calls, and of "pids" for getting a random seed,
+ * and of the "umask()" call for various reasons, and to guess if
+ * the "kill()" function is available, and for permission to use
+ * functions to extract user names and expand "tildes" in filenames.
+ * Basically, SET_UID should *only* be set for "Unix" machines.
+ */
+#if !defined(WINDOWS)
+# define SET_UID
+#endif
+
+
+/*
+ * Every system seems to use its own symbol as a path separator.
+ * Default to the standard Unix slash, but attempt to change this
+ * for various other systems. Note that any system that uses the
+ * "period" as a separator (i.e. ACORN) will have to pretend that
+ * it uses the slash, and do its own mapping of period <-> slash.
+ */
+#undef PATH_SEP
+#define PATH_SEP "/"
+#if defined(WINDOWS) || defined(WINNT)
+# undef PATH_SEP
+# define PATH_SEP "\\"
+#endif
+
+
+
+/*
+ * Basic "types".
+ *
+ * Note the attempt to make all basic types have 4 letters.
+ * This improves readibility and standardizes the code.
+ *
+ * Likewise, all complex types are at least 4 letters.
+ * Thus, almost every three letter word is a legal variable.
+ * But beware of certain reserved words ('for' and 'if' and 'do').
+ *
+ * Note that the type used in structures for bit flags should be unsigned int.
+ * As long as these bit flags are sequential, they will be space smart.
+ *
+ * Note that on some machines, apparently "signed char" is illegal.
+ *
+ * It must be true that char/byte takes exactly 1 byte
+ * It must be true that sind/uind takes exactly 2 bytes
+ * It must be true that sbig/ubig takes exactly 4 bytes
+ *
+ * On Sparc's, a sint takes 4 bytes (2 is legal)
+ * On Sparc's, a long takes 4 bytes (8 is legal)
+ * On Sparc's, a real takes 8 bytes (4 is legal)
+ *
+ * Note that some files have already been included by "h-include.h"
+ * These include <stdio.h> and <sys/types>, which define some types
+ */
+
+
+/* Error codes for function return values */
+/* Success = 0, Failure = -N, Problem = +N */
+typedef int errr;
+
+
+/* Note that unsigned values can cause math problems */
+/* An unsigned byte of memory */
+typedef unsigned char byte;
+
+/* Fixed-size integral types */
+using s16b = int16_t;
+using u16b = uint16_t;
+using s32b = int32_t;
+using u32b = uint32_t;
+
+
+/*
+ * Hack -- Define NULL
+ */
+#ifndef NULL
+# ifdef __STDC__
+# define NULL ((void*)0)
+# else
+# define NULL ((char*)0)
+# endif /* __STDC__ */
+#endif /* NULL */
+
+
+/**** Simple "Macros" ****/
+
+/*
+ * Non-typed absolute value macro
+ */
+#undef ABS
+#define ABS(a) (((a) < 0) ? (-(a)) : (a))
+
+
+/*
+ * Note that all "index" values must be "lowercase letters", while
+ * all "digits" must be "digits". Control characters can be made
+ * from any legal characters. XXX XXX XXX
+ */
+#define A2I(X) ((X) - 'a')
+#define I2A(X) ((X) + 'a')
+#define I2C(X) (static_cast<char>(I2A(X)))
+#define D2I(X) ((X) - '0')
+#define I2D(X) ((X) + '0')
+#define KTRL(X) ((X) & 0x1F)
+#define ESCAPE '\033'
diff --git a/src/h-config.h b/src/h-config.h
deleted file mode 100644
index 09e9bac8..00000000
--- a/src/h-config.h
+++ /dev/null
@@ -1,84 +0,0 @@
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Choose the hardware, operating system, and compiler.
- * Also, choose various "system level" compilation options.
- * A lot of these definitions take effect in "h-system.h"
- *
- * Note that you may find it simpler to define some of these
- * options in the "Makefile", especially any options describing
- * what "system" is being used.
- */
-
-
-/*
- * no system definitions are needed for 4.3BSD, SUN OS, DG/UX
- */
-
-/*
- * OPTION: Compile on Windows (automatic)
- */
-#ifndef WINDOWS
-/* #define WINDOWS */
-#endif
-
-
-/*
- * Extract the "WINDOWS" flag from the compiler
- */
-#if defined(_Windows) || defined(__WINDOWS__) || \
- defined(__WIN32__) || defined(WIN32) || \
- defined(__WINNT__) || defined(__NT__)
-# ifndef WINDOWS
-# define WINDOWS
-# endif
-#endif
-
-
-
-/*
- * OPTION: Define "L64" if a "long" is 64-bits. See "h-types.h".
- * The only such platform that angband is ported to is currently
- * DEC Alpha AXP running OSF/1 (OpenVMS uses 32-bit longs).
- */
-#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(__ia64) || defined(__ia64__) || defined(__mips64) || defined(__ppc64__) || defined(__PPC64__) || defined(__powerpc64__) || defined(__64BIT__) || defined(__sparc64__) || defined(__LP64__)
-# define L64
-#endif
-
-
-
-/*
- * OPTION: set "SET_UID" if the machine is a "multi-user" machine.
- * This option is used to verify the use of "uids" and "gids" for
- * various "Unix" calls, and of "pids" for getting a random seed,
- * and of the "umask()" call for various reasons, and to guess if
- * the "kill()" function is available, and for permission to use
- * functions to extract user names and expand "tildes" in filenames.
- * Basically, SET_UID should *only* be set for "Unix" machines.
- */
-#if !defined(WINDOWS)
-# define SET_UID
-#endif
-
-
-/*
- * Every system seems to use its own symbol as a path separator.
- * Default to the standard Unix slash, but attempt to change this
- * for various other systems. Note that any system that uses the
- * "period" as a separator (i.e. ACORN) will have to pretend that
- * it uses the slash, and do its own mapping of period <-> slash.
- */
-#undef PATH_SEP
-#define PATH_SEP "/"
-#if defined(WINDOWS) || defined(WINNT)
-# undef PATH_SEP
-# define PATH_SEP "\\"
-#endif
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/src/h-define.h b/src/h-define.h
deleted file mode 100644
index 76e7e339..00000000
--- a/src/h-define.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* File: h-define.h */
-
-#ifndef INCLUDED_H_DEFINE_H
-#define INCLUDED_H_DEFINE_H
-
-/*
- * Define some simple constants
- */
-
-
-/*
- * Hack -- Define NULL
- */
-#ifndef NULL
-# ifdef __STDC__
-# define NULL ((void*)0)
-# else
-# define NULL ((char*)0)
-# endif /* __STDC__ */
-#endif /* NULL */
-
-
-/*
- * Hack -- force definitions -- see fd_seek()
- */
-#ifndef SEEK_SET
-# define SEEK_SET 0
-#endif
-#ifndef SEEK_CUR
-# define SEEK_CUR 1
-#endif
-#ifndef SEEK_END
-# define SEEK_END 2
-#endif
-
-
-/*
- * The constants "TRUE" and "FALSE"
- */
-
-#undef TRUE
-#define TRUE 1
-
-#undef FALSE
-#define FALSE 0
-
-
-
-
-/**** Simple "Macros" ****/
-
-/*
- * Force a character to lowercase/uppercase
- */
-#define FORCELOWER(A) ((isupper((A))) ? tolower((A)) : (A))
-#define FORCEUPPER(A) ((islower((A))) ? toupper((A)) : (A))
-
-
-/*
- * Non-typed minimum value macro
- */
-#undef MIN
-#define MIN(a,b) (((a) > (b)) ? (b) : (a))
-
-/*
- * Non-typed maximum value macro
- */
-#undef MAX
-#define MAX(a,b) (((a) < (b)) ? (b) : (a))
-
-/*
- * Non-typed absolute value macro
- */
-#undef ABS
-#define ABS(a) (((a) < 0) ? (-(a)) : (a))
-
-
-/*
- * Note that all "index" values must be "lowercase letters", while
- * all "digits" must be "digits". Control characters can be made
- * from any legal characters. XXX XXX XXX
- */
-#define A2I(X) ((X) - 'a')
-#define I2A(X) ((X) + 'a')
-#define D2I(X) ((X) - '0')
-#define I2D(X) ((X) + '0')
-#define KTRL(X) ((X) & 0x1F)
-#define ESCAPE '\033'
-
-
-#endif
-
diff --git a/src/h-system.h b/src/h-system.h
deleted file mode 100644
index 92041742..00000000
--- a/src/h-system.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* File: h-system.h */
-
-#ifndef INCLUDED_H_SYSTEM_H
-#define INCLUDED_H_SYSTEM_H
-
-/*
- * Include the basic "system" files.
- *
- * Make sure all "system" constants/macros are defined.
- * Make sure all "system" functions have "extern" declarations.
- *
- * This file is a big hack to make other files less of a hack.
- * This file has been rebuilt -- it may need a little more work.
- */
-
-
-#include <stdio.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include <stdlib.h>
-
-
-#ifdef SET_UID
-
-# include <sys/types.h>
-
-# if defined(linux)
-# include <sys/time.h>
-# endif
-
-# include <sys/timeb.h>
-
-#endif
-
-
-#include <time.h>
-
-
-
-#if defined(WINDOWS)
-# include <io.h>
-#endif
-
-#include <memory.h>
-
-
-# include <fcntl.h>
-
-
-#ifdef SET_UID
-
-# include <sys/param.h>
-# include <sys/file.h>
-
-# ifdef linux
-# include <sys/file.h>
-# endif
-
-# include <pwd.h>
-
-# include <unistd.h>
-
-# include <sys/stat.h>
-
-
-#endif
-
-#ifdef SET_UID
-
-# include <strings.h>
-
-#else
-
-# include <string.h>
-
-#endif
-
-
-
-
-#include <stdarg.h>
-
-
-#endif
-
-/* There was a bug introduced in 10.4.11; working around it */
-#ifdef __APPLE__
-#define GETLOGIN_BROKEN
-#endif
diff --git a/src/h-type.h b/src/h-type.h
deleted file mode 100644
index bcf013bb..00000000
--- a/src/h-type.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/* File: h-type.h */
-
-#ifndef INCLUDED_H_TYPE_H
-#define INCLUDED_H_TYPE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * Basic "types".
- *
- * Note the attempt to make all basic types have 4 letters.
- * This improves readibility and standardizes the code.
- *
- * Likewise, all complex types are at least 4 letters.
- * Thus, almost every three letter word is a legal variable.
- * But beware of certain reserved words ('for' and 'if' and 'do').
- *
- * Note that the type used in structures for bit flags should be uint.
- * As long as these bit flags are sequential, they will be space smart.
- *
- * Note that on some machines, apparently "signed char" is illegal.
- *
- * It must be true that char/byte takes exactly 1 byte
- * It must be true that sind/uind takes exactly 2 bytes
- * It must be true that sbig/ubig takes exactly 4 bytes
- *
- * On Sparc's, a sint takes 4 bytes (2 is legal)
- * On Sparc's, a uint takes 4 bytes (2 is legal)
- * On Sparc's, a long takes 4 bytes (8 is legal)
- * On Sparc's, a huge takes 4 bytes (8 is legal)
- * On Sparc's, a vptr takes 4 bytes (8 is legal)
- * On Sparc's, a real takes 8 bytes (4 is legal)
- *
- * Note that some files have already been included by "h-include.h"
- * These include <stdio.h> and <sys/types>, which define some types
- * In particular, uint is defined so we do not have to define it
- *
- * Also, see <limits.h> for min/max values for sind, uind, long, huge
- * (SHRT_MIN, SHRT_MAX, USHRT_MAX, LONG_MIN, LONG_MAX, ULONG_MAX)
- * These limits should be verified and coded into "h-constant.h".
- */
-
-
-
-/*** Special 4 letter names for some standard types ***/
-
-
-/* A standard pointer (to "void" because ANSI C says so) */
-typedef void *vptr;
-
-/* A simple pointer (to unmodifiable strings) */
-typedef const char *cptr;
-typedef char *mcptr;
-
-
-/* Since float's are silly, hard code real numbers as doubles */
-typedef double real;
-
-
-/* Error codes for function return values */
-/* Success = 0, Failure = -N, Problem = +N */
-typedef int errr;
-
-
-/*
- * Hack -- prevent problems with non-MACINTOSH
- */
-#undef uint
-#define uint uint_hack
-
-/*
- * Hack -- prevent problems with WINDOWS
- */
-#undef huge
-#define huge huge_hack
-
-/* Note that "signed char" is not always "defined" */
-/* So always use "s16b" to hold small signed values */
-/* A signed byte of memory */
-/* typedef signed char syte; */
-
-/* Note that unsigned values can cause math problems */
-/* An unsigned byte of memory */
-typedef unsigned char byte;
-
-/* Note that a bool is smaller than a full "int" */
-/* Simple True/False type */
-typedef char bool_;
-
-
-/* A signed, standard integer (at least 2 bytes) */
-typedef int sint;
-
-/* An unsigned, "standard" integer (often pre-defined) */
-typedef unsigned int uint;
-
-
-/* The largest possible signed integer (pre-defined) */
-/* typedef long long; */
-
-/* The largest possible unsigned integer */
-typedef unsigned long huge;
-
-
-/* Signed/Unsigned 16 bit value */
-typedef signed short s16b;
-typedef unsigned short u16b;
-#define FMTs16b "%hd"
-#define FMTu16b "%hu"
-
-/* Signed/Unsigned 32 bit value */
-#ifdef L64 /* 64 bit longs */
-typedef signed int s32b;
-typedef unsigned int u32b;
-#define FMTs32b "%d"
-#define FMTu32b "%u"
-#else
-typedef signed long s32b;
-typedef unsigned long u32b;
-#define FMTs32b "%ld"
-#define FMTu32b "%lu"
-#endif
-
-
-/*** Pointers to all the basic types defined above ***/
-
-typedef real *real_ptr;
-typedef errr *errr_ptr;
-typedef char *char_ptr;
-typedef byte *byte_ptr;
-typedef bool_ *bool_ptr;
-typedef sint *sint_ptr;
-typedef uint *uint_ptr;
-typedef long *long_ptr;
-typedef huge *huge_ptr;
-typedef s16b *s16b_ptr;
-typedef u16b *u16b_ptr;
-typedef s32b *s32b_ptr;
-typedef u32b *u32b_ptr;
-typedef vptr *vptr_ptr;
-typedef cptr *cptr_ptr;
-
-
-
-/*** Pointers to Functions with simple return types and any args ***/
-
-typedef void (*func_void)();
-typedef errr (*func_errr)();
-typedef char (*func_char)();
-typedef byte (*func_byte)();
-typedef bool_ (*func_bool)();
-typedef sint (*func_sint)();
-typedef uint (*func_uint)();
-typedef real (*func_real)();
-typedef vptr (*func_vptr)();
-typedef cptr (*func_cptr)();
-
-
-
-/*** Pointers to Functions of special types (for various purposes) ***/
-
-/* A generic function takes a user data and a special data */
-typedef errr (*func_gen)(vptr, vptr);
-
-/* An equality testing function takes two things to compare (bool) */
-typedef bool_ (*func_eql)(vptr, vptr);
-
-/* A comparison function takes two things and to compare (-1,0,+1) */
-typedef sint (*func_cmp)(vptr, vptr);
-
-/* A hasher takes a thing (and a max hash size) to hash (0 to siz - 1) */
-typedef uint (*func_hsh)(vptr, uint);
-
-/* A key extractor takes a thing and returns (a pointer to) some key */
-typedef vptr (*func_key)(vptr);
-
-
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif
-
diff --git a/src/help.cc b/src/help.cc
index 08956f70..0f236e41 100644
--- a/src/help.cc
+++ b/src/help.cc
@@ -10,6 +10,7 @@
#include "help.hpp"
#include "cave_type.hpp"
+#include "defines.hpp"
#include "files.hpp"
#include "hook_get_in.hpp"
#include "hook_identify_in.hpp"
@@ -22,6 +23,11 @@
#include "skills.hpp"
#include "util.hpp"
#include "variable.hpp"
+#include "z-term.hpp"
+
+#include <boost/algorithm/string/predicate.hpp>
+
+using boost::algorithm::equals;
#define DESC_MAX 14
#define TRIGGERED_HELP_MAX 16
@@ -46,7 +52,7 @@
/**
* Game started?
*/
-static bool_ game_started = FALSE;
+static bool game_started = false;
/**
* Struct for help triggered by a boolean condition
@@ -59,9 +65,9 @@ struct triggered_help_type
/* Hook type */
int hook_type;
/* Trigger function */
- bool_ (*trigger_func)(void *in, void *out);
+ bool (*trigger_func)(void *in, void *out);
/* Description; NULL terminated */
- cptr desc[DESC_MAX];
+ const char *desc[DESC_MAX];
};
/**
@@ -70,8 +76,8 @@ struct triggered_help_type
typedef struct context_help_type context_help_type;
struct context_help_type
{
- cptr key; /* Lookup key */
- cptr file_name; /* Name of help file */
+ const char *key; /* Lookup key */
+ const char *file_name; /* Name of help file */
int anchor; /* Anchor in file */
};
@@ -304,90 +310,88 @@ context_help_type ability_table[] =
/**
* Trigger functions
*/
-static bool_ trigger_void_jumpgate(void *in, void *out) {
+static bool trigger_void_jumpgate(void *in, void *out) {
hook_move_in *p = (hook_move_in *) in;
return cave[p->y][p->x].feat == FEAT_BETWEEN;
}
-static bool_ trigger_fountain(void *in, void *out) {
+static bool trigger_fountain(void *in, void *out) {
hook_move_in *p = (hook_move_in *) in;
return cave[p->y][p->x].feat == FEAT_FOUNTAIN;
}
-static bool_ trigger_found_object(void *in, void *out) {
+static bool trigger_found_object(void *in, void *out) {
hook_move_in *p = (hook_move_in *) in;
return !cave[p->y][p->x].o_idxs.empty();
}
-static bool_ trigger_found_altar(void *in, void *out) {
+static bool trigger_found_altar(void *in, void *out) {
hook_move_in *p = (hook_move_in *) in;
return ((cave[p->y][p->x].feat >= FEAT_ALTAR_HEAD) &&
(cave[p->y][p->x].feat <= FEAT_ALTAR_TAIL));
}
-static bool_ trigger_found_stairs(void *in, void *out) {
+static bool trigger_found_stairs(void *in, void *out) {
hook_move_in *p = (hook_move_in *) in;
return (cave[p->y][p->x].feat == FEAT_MORE);
}
-static bool_ trigger_get_rod(void *in, void *out) {
+static bool trigger_get_rod(void *in, void *out) {
hook_get_in *g = (hook_get_in *) in;
return (g->o_ptr->tval == TV_ROD_MAIN);
}
-static bool_ trigger_get_rod_tip(void *in, void *out) {
+static bool trigger_get_rod_tip(void *in, void *out) {
hook_get_in *g = (hook_get_in *) in;
return (g->o_ptr->tval == TV_ROD);
}
-static bool_ trigger_get_magic_device(void *in, void *out) {
+static bool trigger_get_magic_device(void *in, void *out) {
hook_get_in *g = (hook_get_in *) in;
return ((g->o_ptr->tval == TV_WAND) ||
(g->o_ptr->tval == TV_STAFF));
}
-static bool_ trigger_end_turn_wilderness(void *in, void *out) {
+static bool trigger_end_turn_wilderness(void *in, void *out) {
return (((p_ptr->wilderness_x != 34) ||
(p_ptr->wilderness_y != 21)) &&
(!p_ptr->astral));
}
-static bool_ trigger_game_theme(void *in, void *out) {
+static bool trigger_game_theme(void *in, void *out) {
return (game_module_idx == MODULE_THEME);
}
-static bool_ trigger_game_tome(void *in, void *out) {
+static bool trigger_game_tome(void *in, void *out) {
return (game_module_idx == MODULE_TOME);
}
-static bool_ trigger_1st_level(void *in, void *out) {
+static bool trigger_1st_level(void *in, void *out) {
return (p_ptr->lev > 1);
}
-static bool_ trigger_20th_level(void *in, void *out) {
+static bool trigger_20th_level(void *in, void *out) {
return (p_ptr->lev >= 20);
}
-static bool_ trigger_identify_spell_item(void *in_, void *out) {
+static bool trigger_identify_spell_item(void *in_, void *out) {
hook_identify_in *in = (hook_identify_in *) in_;
- if (in->mode == IDENT_FULL)
+ auto const f = object_flags(in->o_ptr);
+ if (f & TR_SPELL_CONTAIN)
{
- auto const f = object_flags(in->o_ptr);
- if (f & TR_SPELL_CONTAIN)
- {
- return TRUE;
- }
+ return true;
}
- return FALSE;
+
+ return false;
}
-static bool_ trigger_melee_skills(void *in, void *out) {
+static bool trigger_melee_skills(void *in, void *out) {
return (game_started && (get_melee_skills() > 1));
}
-static bool_ trigger_always(void *in, void *out) {
- return TRUE;
+static bool trigger_always(void *in, void *out) {
+ return true;
}
/**
@@ -581,7 +585,7 @@ static bool triggered_help_hook(void *data, void *in, void *out)
static bool hook_game_start(void *data, void *in, void *out)
{
- game_started = TRUE;
+ game_started = true;
return false;
}
@@ -645,7 +649,7 @@ static void show_context_help(context_help_type *context_help)
/*
* Find context help
*/
-static context_help_type *find_context_help(context_help_type table[], cptr key)
+static context_help_type *find_context_help(context_help_type table[], const char *key)
{
int i;
@@ -658,7 +662,7 @@ static context_help_type *find_context_help(context_help_type table[], cptr key)
return NULL; /* End of list */
}
- if (streq(key, context_help->key))
+ if (equals(key, context_help->key))
{
return context_help;
}
@@ -683,7 +687,7 @@ void help_class(std::string const &klass)
show_context_help(find_context_help(class_table, klass.c_str()));
}
-void help_god(cptr god)
+void help_god(const char *god)
{
context_help_type *context_help =
find_context_help(god_table, god);
diff --git a/src/help.hpp b/src/help.hpp
index a805a62b..c66379be 100644
--- a/src/help.hpp
+++ b/src/help.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include <string>
@@ -8,6 +8,6 @@ void init_hooks_help();
void help_race(std::string const &race);
void help_subrace(std::string const &subrace);
void help_class(std::string const &klass);
-void help_god(cptr god);
+void help_god(const char *god);
void help_skill(std::string const &skill);
void help_ability(std::string const &ability);
diff --git a/src/help_info.hpp b/src/help_info.hpp
index 1b4a3757..eed91029 100644
--- a/src/help_info.hpp
+++ b/src/help_info.hpp
@@ -1,6 +1,8 @@
#pragma once
-#include "h-basic.h"
+#include <array>
+
+#include "h-basic.hpp"
/**
* Maximum number of help items.
@@ -12,6 +14,6 @@ constexpr int HELP_MAX = 64;
*/
struct help_info
{
- bool enabled = false; /* ingame help enabled */
- bool activated[HELP_MAX] = { false }; /* help item #i activated? */
+ bool enabled = false; /* ingame help enabled */
+ std::array<bool, HELP_MAX> activated { }; /* help item #i activated? */
};
diff --git a/src/hiscore.cc b/src/hiscore.cc
index 971b84cd..09530e37 100644
--- a/src/hiscore.cc
+++ b/src/hiscore.cc
@@ -3,11 +3,12 @@
#include "util.hpp"
#include <cassert>
+#include <cstring>
int highscore_seek(int highscore_fd, int i)
{
/* Seek for the requested record */
- return (fd_seek(highscore_fd, (huge)(i) * sizeof(high_score)));
+ return (fd_seek(highscore_fd, (unsigned long)(i) * sizeof(high_score)));
}
errr highscore_read(int highscore_fd, high_score *score)
@@ -48,7 +49,7 @@ int highscore_where(int highscore_fd, high_score *score)
int highscore_add(int highscore_fd, high_score *score)
{
int i, slot;
- bool_ done = FALSE;
+ bool done = false;
high_score the_score, tmpscore;
@@ -70,7 +71,7 @@ int highscore_add(int highscore_fd, high_score *score)
{
/* Read the old guy, note errors */
if (highscore_seek(highscore_fd, i)) return ( -1);
- if (highscore_read(highscore_fd, &tmpscore)) done = TRUE;
+ if (highscore_read(highscore_fd, &tmpscore)) done = true;
/* Back up and dump the score we were holding */
if (highscore_seek(highscore_fd, i)) return ( -1);
diff --git a/src/hiscore.hpp b/src/hiscore.hpp
index 990c91aa..f53c6558 100644
--- a/src/hiscore.hpp
+++ b/src/hiscore.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* Maximum number of high scores in the high score file
diff --git a/src/hook_build_room1_in.hpp b/src/hook_build_room1_in.hpp
index e9a5d367..ba155525 100644
--- a/src/hook_build_room1_in.hpp
+++ b/src/hook_build_room1_in.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct hook_build_room1_in {
s32b y;
diff --git a/src/hook_calculate_hp_in.hpp b/src/hook_calculate_hp_in.hpp
index 924add45..165d9e75 100644
--- a/src/hook_calculate_hp_in.hpp
+++ b/src/hook_calculate_hp_in.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct hook_calculate_hp_in {
s32b mhp;
diff --git a/src/hook_calculate_hp_out.hpp b/src/hook_calculate_hp_out.hpp
index 7923997f..28d52350 100644
--- a/src/hook_calculate_hp_out.hpp
+++ b/src/hook_calculate_hp_out.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct hook_calculate_hp_out {
s32b mhp;
diff --git a/src/hook_chardump_in.hpp b/src/hook_chardump_in.hpp
index c8edea62..4c9976cc 100644
--- a/src/hook_chardump_in.hpp
+++ b/src/hook_chardump_in.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct hook_chardump_in {
FILE *file;
diff --git a/src/hook_chat_in.hpp b/src/hook_chat_in.hpp
index 5062b0e6..8b9efe9c 100644
--- a/src/hook_chat_in.hpp
+++ b/src/hook_chat_in.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct hook_chat_in {
s32b m_idx;
diff --git a/src/hook_eat_out.hpp b/src/hook_eat_out.hpp
deleted file mode 100644
index 70bb92a4..00000000
--- a/src/hook_eat_out.hpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-#include "h-basic.h"
-
-struct hook_eat_out {
- bool_ ident;
-};
diff --git a/src/hook_enter_dungeon_in.hpp b/src/hook_enter_dungeon_in.hpp
index 2f667c78..3cfe6736 100644
--- a/src/hook_enter_dungeon_in.hpp
+++ b/src/hook_enter_dungeon_in.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct hook_enter_dungeon_in {
s32b d_idx;
diff --git a/src/hook_identify_in.hpp b/src/hook_identify_in.hpp
index 40a8fc79..9e7c9d40 100644
--- a/src/hook_identify_in.hpp
+++ b/src/hook_identify_in.hpp
@@ -1,9 +1,7 @@
#pragma once
#include "object_type_fwd.hpp"
-#include "identify_mode.hpp"
struct hook_identify_in {
object_type *o_ptr;
- identify_mode mode;
};
diff --git a/src/hook_mon_speak_in.hpp b/src/hook_mon_speak_in.hpp
index f3a14338..337daaf8 100644
--- a/src/hook_mon_speak_in.hpp
+++ b/src/hook_mon_speak_in.hpp
@@ -1,8 +1,8 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct hook_mon_speak_in {
s32b m_idx;
- cptr m_name;
+ const char *m_name;
};
diff --git a/src/hook_monster_ai_in.hpp b/src/hook_monster_ai_in.hpp
index 492006aa..44f76a39 100644
--- a/src/hook_monster_ai_in.hpp
+++ b/src/hook_monster_ai_in.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "monster_type_fwd.hpp"
struct hook_monster_ai_in {
diff --git a/src/hook_monster_ai_out.hpp b/src/hook_monster_ai_out.hpp
index 4c5ef28f..c26b5138 100644
--- a/src/hook_monster_ai_out.hpp
+++ b/src/hook_monster_ai_out.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct hook_monster_ai_out {
s32b y;
diff --git a/src/hook_monster_death_in.hpp b/src/hook_monster_death_in.hpp
index 354c37d2..f9aabfa0 100644
--- a/src/hook_monster_death_in.hpp
+++ b/src/hook_monster_death_in.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct hook_monster_death_in {
s32b m_idx;
diff --git a/src/hook_new_monster_in.hpp b/src/hook_new_monster_in.hpp
index 10b0420c..b08f36db 100644
--- a/src/hook_new_monster_in.hpp
+++ b/src/hook_new_monster_in.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct hook_new_monster_in {
s32b r_idx;
diff --git a/src/hook_quest_fail_in.hpp b/src/hook_quest_fail_in.hpp
index 2edf86a3..834e7ea3 100644
--- a/src/hook_quest_fail_in.hpp
+++ b/src/hook_quest_fail_in.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct hook_quest_fail_in {
s16b q_idx;
diff --git a/src/hook_quest_finish_in.hpp b/src/hook_quest_finish_in.hpp
index 55490be4..4e953bb6 100644
--- a/src/hook_quest_finish_in.hpp
+++ b/src/hook_quest_finish_in.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct hook_quest_finish_in {
s32b q_idx;
diff --git a/src/hook_quest_gen_in.hpp b/src/hook_quest_gen_in.hpp
new file mode 100644
index 00000000..0370f143
--- /dev/null
+++ b/src/hook_quest_gen_in.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "dungeon_flag_set.hpp"
+
+struct hook_quest_gen_in {
+
+ dungeon_flag_set &dungeon_flags_ref;
+
+};
diff --git a/src/hook_stair_out.hpp b/src/hook_stair_out.hpp
index 5e3d515a..b3470bc0 100644
--- a/src/hook_stair_out.hpp
+++ b/src/hook_stair_out.hpp
@@ -1,7 +1,7 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct hook_stair_out {
- bool_ allow;
+ bool allow;
};
diff --git a/src/hook_wild_gen_in.hpp b/src/hook_wild_gen_in.hpp
index 147a74db..f6cd82f3 100644
--- a/src/hook_wild_gen_in.hpp
+++ b/src/hook_wild_gen_in.hpp
@@ -1,7 +1,7 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct hook_wild_gen_in {
- bool_ small;
+ bool small;
};
diff --git a/src/hooks.cc b/src/hooks.cc
index bd2ea905..cd09e64e 100644
--- a/src/hooks.cc
+++ b/src/hooks.cc
@@ -8,7 +8,7 @@
#include "hooks.hpp"
#include <algorithm>
-#include <assert.h>
+#include <cassert>
#include <unordered_map>
#include <vector>
@@ -37,7 +37,7 @@ public:
/**
* Invoke the hook with the given input and output pointers.
*/
- bool_ invoke(void *in, void *out) const {
+ bool invoke(void *in, void *out) const {
return m_hook_func(m_hook_data, in, out);
}
};
@@ -49,7 +49,7 @@ std::unordered_map<size_t, std::vector<hook_data>> &hooks_instance()
}
-int process_hooks_restart = FALSE;
+int process_hooks_restart = false;
static std::vector<hook_data>::iterator find_hook(std::vector<hook_data> &hooks, hook_func_t hook_func)
{
@@ -60,7 +60,7 @@ static std::vector<hook_data>::iterator find_hook(std::vector<hook_data> &hooks,
});
}
-void add_hook_new(int h_idx, hook_func_t hook_func, cptr name, void *data)
+void add_hook_new(int h_idx, hook_func_t hook_func, const char *name, void *data)
{
auto &hooks = hooks_instance()[h_idx];
// Only insert if not already present.
@@ -91,7 +91,7 @@ bool process_hooks_new(int h_idx, void *in, void *out)
auto &hook_data = *hooks_it;
/* Invoke hook function; stop processing if the hook
- returns TRUE */
+ returns true */
if (hook_data.invoke(in, out))
{
return true;
@@ -101,7 +101,7 @@ bool process_hooks_new(int h_idx, void *in, void *out)
if (process_hooks_restart)
{
hooks_it = hooks.begin();
- process_hooks_restart = FALSE;
+ process_hooks_restart = false;
}
else
{
diff --git a/src/hooks.hpp b/src/hooks.hpp
index 7cf4285b..c250e06c 100644
--- a/src/hooks.hpp
+++ b/src/hooks.hpp
@@ -1,10 +1,10 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
typedef bool (*hook_func_t)(void *, void *, void *);
-void add_hook_new(int h_idx, hook_func_t hook_func, cptr name, void *data);
+void add_hook_new(int h_idx, hook_func_t hook_func, const char *name, void *data);
void del_hook_new(int h_idx, hook_func_t hook_func);
extern int process_hooks_restart;
bool process_hooks_new(int h_idx, void *in, void *out);
diff --git a/src/identify_mode.hpp b/src/identify_mode.hpp
deleted file mode 100644
index 687a1fae..00000000
--- a/src/identify_mode.hpp
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-typedef enum { IDENT_NORMAL, IDENT_FULL } identify_mode;
diff --git a/src/include/tome/enum_string_map.hpp b/src/include/tome/enum_string_map.hpp
index 814827fe..bd554b5c 100644
--- a/src/include/tome/enum_string_map.hpp
+++ b/src/include/tome/enum_string_map.hpp
@@ -35,6 +35,10 @@ public:
return i->second.c_str();
}
+ E parse(std::string const &s) const {
+ return parse(s.c_str());
+ }
+
E parse(const char *s) const {
E e;
bool result = parse(s, &e);
@@ -42,6 +46,10 @@ public:
return e;
}
+ bool parse(std::string const &s, E *e) const {
+ return parse(s.c_str(), e);
+ }
+
bool parse(const char *s, E *e) const {
auto i = bimap.right.find(s);
if (i == bimap.right.end())
diff --git a/src/include/tome/squelch/condition.hpp b/src/include/tome/squelch/condition.hpp
index 584ecb0e..cc5deb64 100644
--- a/src/include/tome/squelch/condition.hpp
+++ b/src/include/tome/squelch/condition.hpp
@@ -20,10 +20,10 @@ namespace squelch {
* Types of matches used for conditions.
*/
enum class match_type {
- AND , OR , NOT , NAME , CONTAIN ,
- INSCRIBED, DISCOUNT, SYMBOL , STATE , STATUS ,
- TVAL , SVAL , RACE , SUBRACE , CLASS ,
- LEVEL , SKILL , ABILITY, INVENTORY, EQUIPMENT };
+ AND , OR , NOT , NAME , CONTAIN,
+ INSCRIBED, DISCOUNT, SYMBOL , STATUS , TVAL ,
+ SVAL , RACE , SUBRACE , CLASS , LEVEL ,
+ SKILL , ABILITY , INVENTORY, EQUIPMENT };
/**
* Bidirectional map between enumeration values and strings.
@@ -31,18 +31,6 @@ enum class match_type {
EnumStringMap<match_type> &match_mapping();
/**
- * Identification states an object can have: identified or not
- * identified.
- */
-enum class identification_state {
- IDENTIFIED, NOT_IDENTIFIED };
-
-/**
- * Biredectional map between identification_state values and strings.
- */
-EnumStringMap<identification_state> &identification_state_mapping();
-
-/**
* Condition represents a tree of checks which
* can be applied to objects, the player, etc.
*/
@@ -133,7 +121,7 @@ private:
class NameCondition : public Condition
{
public:
- NameCondition(std::string name) :
+ NameCondition(std::string const &name) :
Condition(match_type::NAME),
m_name(name) {
}
@@ -157,7 +145,7 @@ private:
class ContainCondition : public Condition
{
public:
- ContainCondition(std::string contain) :
+ ContainCondition(std::string const &contain) :
Condition(match_type::CONTAIN),
m_contain(contain) {
}
@@ -302,7 +290,7 @@ private:
class RaceCondition : public Condition
{
public:
- RaceCondition(std::string race)
+ RaceCondition(std::string const &race)
: Condition(match_type::RACE)
, m_race(race) {
}
@@ -326,7 +314,7 @@ private:
class SubraceCondition : public Condition
{
public:
- SubraceCondition(std::string subrace)
+ SubraceCondition(std::string const &subrace)
: Condition(match_type::SUBRACE)
, m_subrace(subrace) {
}
@@ -350,7 +338,7 @@ private:
class ClassCondition : public Condition
{
public:
- ClassCondition(std::string klass)
+ ClassCondition(std::string const &klass)
: Condition(match_type::CLASS)
, m_class(klass) {
}
@@ -374,7 +362,7 @@ private:
class InscriptionCondition : public Condition
{
public:
- InscriptionCondition(std::string inscription)
+ InscriptionCondition(std::string const &inscription)
: Condition(match_type::INSCRIBED)
, m_inscription(inscription) {
}
@@ -473,30 +461,6 @@ private:
};
/**
- * Check identification state
- */
-class StateCondition : public Condition
-{
-public:
- StateCondition(identification_state state)
- : Condition(match_type::STATE)
- , m_state(state) {
- }
-
- bool is_match(object_type *) const override;
-
- static std::shared_ptr<Condition> from_json(jsoncons::json const &);
-
-protected:
- void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
-
- void to_json(jsoncons::json &) const override;
-
-private:
- identification_state m_state;
-};
-
-/**
* Check object symbol
*/
class SymbolCondition : public Condition
diff --git a/src/include/tome/squelch/object_status.hpp b/src/include/tome/squelch/object_status.hpp
index c52a35ea..2d90ac1a 100644
--- a/src/include/tome/squelch/object_status.hpp
+++ b/src/include/tome/squelch/object_status.hpp
@@ -1,6 +1,7 @@
#ifndef H_e3f9ebbe_ff9a_4687_a847_6101f094b483
#define H_e3f9ebbe_ff9a_4687_a847_6101f094b483
+#include "object_type_fwd.hpp"
#include "tome/enum_string_map.hpp"
namespace squelch {
@@ -11,7 +12,8 @@ namespace squelch {
*/
enum class status_type {
BAD , VERY_BAD, AVERAGE, GOOD, VERY_GOOD,
- SPECIAL, TERRIBLE, NONE, CHEST_EMPTY, CHEST_DISARMED };
+ SPECIAL, TERRIBLE, NONE
+};
/**
* Bidirectional map between status_type values and strings.
diff --git a/src/include/tome/squelch/rule.hpp b/src/include/tome/squelch/rule.hpp
index af86dfc8..1270266d 100644
--- a/src/include/tome/squelch/rule.hpp
+++ b/src/include/tome/squelch/rule.hpp
@@ -84,6 +84,13 @@ public:
*/
static std::shared_ptr<Rule> parse_rule(jsoncons::json const &);
+ /**
+ * Destructor.
+ */
+ virtual ~Rule()
+ {
+ };
+
protected:
virtual bool do_apply_rule(object_type *, int) const = 0;
virtual void do_write_tree(TreePrinter *p) const = 0;
diff --git a/src/include/tome/unique_handle.hpp b/src/include/tome/unique_handle.hpp
new file mode 100644
index 00000000..32cb73e2
--- /dev/null
+++ b/src/include/tome/unique_handle.hpp
@@ -0,0 +1,88 @@
+#pragma once
+
+/**
+ * Taken from
+ *
+ * https://github.com/milleniumbug/wiertlo/blob/master/include/wiertlo/unique_handle.hpp
+ *
+ */
+
+#include <utility>
+
+template<typename Policy>
+class unique_handle
+{
+ typename Policy::handle_type h;
+
+public:
+ unique_handle(const unique_handle&) = delete;
+
+ typename Policy::handle_type get() const
+ {
+ return h;
+ }
+
+ typename Policy::handle_type release()
+ {
+ typename Policy::handle_type temp = h;
+ h = Policy::get_null();
+ return temp;
+ }
+
+ explicit operator bool() const
+ {
+ return !Policy::is_null(h);
+ }
+
+ bool operator!() const
+ {
+ return !static_cast<bool>(*this);
+ }
+
+ void reset(typename Policy::handle_type new_handle)
+ {
+ typename Policy::handle_type old_handle = h;
+ h = new_handle;
+ if(!Policy::is_null(old_handle))
+ {
+ Policy::close(old_handle);
+ }
+ }
+
+ void swap(unique_handle& other)
+ {
+ std::swap(this->h, other.h);
+ }
+
+ void reset()
+ {
+ reset(Policy::get_null());
+ }
+
+ ~unique_handle()
+ {
+ reset();
+ }
+
+ unique_handle& operator=(unique_handle other) noexcept
+ {
+ this->swap(other);
+ return *this;
+ }
+
+ unique_handle(unique_handle&& other) noexcept
+ {
+ this->h = other.h;
+ other.h = Policy::get_null();
+ }
+
+ unique_handle()
+ {
+ h = Policy::get_null();
+ }
+
+ unique_handle(typename Policy::handle_type handle)
+ {
+ h = handle;
+ }
+};
diff --git a/src/init1.cc b/src/init1.cc
index e367f603..34e3bc81 100644
--- a/src/init1.cc
+++ b/src/init1.cc
@@ -40,18 +40,21 @@
#include "tables.hpp"
#include "town_type.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "wilderness_type_info.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
+#include "z-util.hpp"
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
+#include <boost/optional.hpp>
+using boost::algorithm::equals;
using boost::algorithm::iequals;
using boost::algorithm::ends_with;
+using boost::algorithm::starts_with;
/**
@@ -91,7 +94,7 @@ template <class T> typename std::vector<T>::reference expand_to_fit_index(std::v
/*
* Monster Blow Methods
*/
-static cptr r_info_blow_method[] =
+static const char *r_info_blow_method[] =
{
"*",
"HIT",
@@ -125,7 +128,7 @@ static cptr r_info_blow_method[] =
/*
* Monster Blow Effects
*/
-static cptr r_info_blow_effect[] =
+static const char *r_info_blow_effect[] =
{
"*",
"HURT",
@@ -182,16 +185,16 @@ namespace detail {
template <size_t N> struct flag_tie_impl {
private:
u32b *m_mask;
- cptr (&m_flags)[N];
+ const char *(&m_flags)[N];
public:
- flag_tie_impl(u32b *mask, cptr (&flags)[N]): m_mask(mask), m_flags(flags) {
+ flag_tie_impl(u32b *mask, const char *(&flags)[N]): m_mask(mask), m_flags(flags) {
// Empty
}
- bool match(cptr flag) {
+ bool match(const char *flag) {
for (unsigned int i = 0; i < N; i++)
{
- if (streq(flag, m_flags[i]))
+ if (equals(flag, m_flags[i]))
{
*m_mask |= (1L << i);
return true;
@@ -207,7 +210,7 @@ public:
* Tie a flags value pointer and its corresponding array
* of text strings.
*/
-template<size_t N> detail::flag_tie_impl<N> flag_tie(u32b *mask, cptr (&flags)[N]) {
+template<size_t N> detail::flag_tie_impl<N> flag_tie(u32b *mask, const char *(&flags)[N]) {
static_assert(N <= 32, "Array too large to represent result");
return detail::flag_tie_impl<N>(mask, flags);
}
@@ -215,7 +218,7 @@ template<size_t N> detail::flag_tie_impl<N> flag_tie(u32b *mask, cptr (&flags)[N
/**
* Look up flag in array of flags.
*/
-template<size_t N> bool lookup_flags(cptr)
+template<size_t N> bool lookup_flags(const char *)
{
// Base case: No match
return false;
@@ -224,7 +227,7 @@ template<size_t N> bool lookup_flags(cptr)
/**
* Look up flag in array of flags.
*/
-template<size_t N, typename... Pairs> bool lookup_flags(cptr flag, detail::flag_tie_impl<N> tie, Pairs&&...rest) {
+template<size_t N, typename... Pairs> bool lookup_flags(const char *flag, detail::flag_tie_impl<N> tie, Pairs&&...rest) {
// Inductive case: Check against current "tie"
if (tie.match(flag)) {
// Match
@@ -244,7 +247,7 @@ template<size_t N, typename... Pairs> bool lookup_flags(cptr flag, detail::flag_
*/
static struct
{
-cptr name;
+const char *name;
int feat;
}
d_info_dtypes[] =
@@ -322,7 +325,7 @@ static const char *activation_names[] =
"EOL", /* 31*/
"UMBAR", /* 32*/
"NUMENOR", /* 33*/
- "KNOWLEDGE", /* 34*/
+ "XXX34",
"UNDEATH", /* 35*/
"THRAIN", /* 36*/
"BARAHIR", /* 37*/
@@ -331,7 +334,7 @@ static const char *activation_names[] =
"NENYA", /* 40*/
"VILYA", /* 41*/
"POWER", /* 42*/
- "STONE_LORE", /* 43*/
+ "XXX43",
"RAZORBACK", /* 44*/
"BLADETURNER", /* 45*/
"MEDIATOR", /* 46*/
@@ -403,8 +406,8 @@ static const char *activation_names[] =
"MAP_LIGHT", /* 112*/
"DETECT_ALL", /* 113*/
"DETECT_XTRA", /* 114*/
- "ID_FULL", /* 115*/
- "ID_PLAIN", /* 116*/
+ "XXX115", /* 115*/
+ "XXX116", /* 116*/
"RUNE_EXPLO", /* 117*/
"RUNE_PROT", /* 118*/
"SATIATE", /* 119*/
@@ -636,8 +639,8 @@ static void strappend(char **s, const char *t)
/*
* Grab one race flag from a textual string
*/
-static bool_ unknown_shut_up = FALSE;
-static errr grab_one_class_flag(u32b *choice, cptr what)
+static bool unknown_shut_up = false;
+static errr grab_one_class_flag(std::array<u32b, 2> &choice, const char *what)
{
auto const &class_info = game->edit_data.class_info;
@@ -658,7 +661,7 @@ static errr grab_one_class_flag(u32b *choice, cptr what)
return (1);
}
-static errr grab_one_race_allow_flag(u32b *choice, cptr what)
+static errr grab_one_race_allow_flag(std::array<u32b, 2> &choice, const char *what)
{
auto const &race_info = game->edit_data.race_info;
@@ -682,10 +685,10 @@ static errr grab_one_race_allow_flag(u32b *choice, cptr what)
/*
* Grab one flag from a textual string
*/
-static errr grab_one_skill_flag(skill_flag_set *flags, cptr what)
+static errr grab_one_skill_flag(skill_flag_set *flags, const char *what)
{
#define SKF(tier, index, name) \
- if (streq(what, #name)) \
+ if (equals(what, #name)) \
{ \
*flags |= BOOST_PP_CAT(SKF_,name); \
return 0; \
@@ -702,10 +705,10 @@ static errr grab_one_skill_flag(skill_flag_set *flags, cptr what)
/*
* Grab one flag from a textual string
*/
-static errr grab_one_player_race_flag(player_race_flag_set *flags, cptr what)
+static errr grab_one_player_race_flag(player_race_flag_set *flags, const char *what)
{
#define PR(tier, index, name) \
- if (streq(what, #name)) \
+ if (equals(what, #name)) \
{ \
*flags |= BOOST_PP_CAT(PR_,name); \
return 0; \
@@ -739,11 +742,11 @@ static int get_activation(char *activation)
/*
* Convert string to object_flag_set value
*/
-static object_flag_set object_flag_set_from_string(cptr what)
+static object_flag_set object_flag_set_from_string(const char *what)
{
for (auto const flag_meta: object_flags_meta())
{
- if (streq(what, flag_meta->e_name))
+ if (equals(what, flag_meta->e_name))
{
return flag_meta->flag_set;
};
@@ -755,7 +758,7 @@ static object_flag_set object_flag_set_from_string(cptr what)
/*
* Grab one flag in an object_kind from a textual string
*/
-static errr grab_object_flag(object_flag_set *flags, cptr what)
+static errr grab_object_flag(object_flag_set *flags, const char *what)
{
if (object_flag_set f = object_flag_set_from_string(what))
{
@@ -773,7 +776,7 @@ static errr grab_object_flag(object_flag_set *flags, cptr what)
/*
* Read skill values
*/
-static int read_skill_modifiers(skill_modifiers *skill_modifiers, cptr buf)
+static int read_skill_modifiers(skill_modifiers *skill_modifiers, const char *buf)
{
long val, mod;
char v, m;
@@ -804,7 +807,7 @@ static int read_skill_modifiers(skill_modifiers *skill_modifiers, cptr buf)
/*
* Read prototype objects
*/
-static int read_proto_object(std::vector<object_proto> *protos, cptr buf)
+static int read_proto_object(std::vector<object_proto> *protos, const char *buf)
{
int s0, s1, s2, s3, s4;
@@ -871,6 +874,25 @@ static int read_ability(std::vector<player_race_ability_type> *abilities, char *
}
+/**
+ * Find a power by its name
+ */
+static boost::optional<int> find_power_idx(const char *name)
+{
+ for (auto const &entry: game->powers)
+ {
+ auto power_ptr = entry.second;
+
+ if (iequals(power_ptr->name, name))
+ {
+ return entry.first;
+ }
+ }
+
+ return boost::none;
+}
+
+
/*
* Initialize the "player" arrays, by parsing an ascii "template" file
*/
@@ -1041,15 +1063,14 @@ errr init_player_info_txt(FILE *fp)
char const *s = buf + 4;
/* Find it in the list */
- int i;
- for (i = 0; i < POWER_MAX; i++)
+ if (auto power_idx = find_power_idx(s))
{
- if (iequals(s, powers_type[i].name)) break;
+ rp_ptr->ps.powers.push_back(*power_idx);
+ }
+ else
+ {
+ return 6;
}
-
- if (i == POWER_MAX) return (6);
-
- rp_ptr->ps.powers.push_back(i);
/* Next... */
continue;
@@ -1189,14 +1210,7 @@ errr init_player_info_txt(FILE *fp)
char const *s = buf + 6;
/* Place */
- if (buf[4] == 'A')
- {
- rmp_ptr->place = TRUE;
- }
- else
- {
- rmp_ptr->place = FALSE;
- }
+ rmp_ptr->place = (buf[4] == 'A');
/* Description */
if (!rmp_ptr->description.empty())
@@ -1268,15 +1282,14 @@ errr init_player_info_txt(FILE *fp)
char const *s = buf + 4;
/* Find it in the list */
- int i;
- for (i = 0; i < POWER_MAX; i++)
+ if (auto power_idx = find_power_idx(s))
{
- if (iequals(s, powers_type[i].name)) break;
+ rmp_ptr->ps.powers.push_back(*power_idx);
+ }
+ else
+ {
+ return 6;
}
-
- if (i == POWER_MAX) return (6);
-
- rmp_ptr->ps.powers.push_back(i);
/* Next... */
continue;
@@ -1373,7 +1386,7 @@ errr init_player_info_txt(FILE *fp)
/* Process 'C' for "Class choice flags" (multiple lines) */
if ((buf[0] == 'S') && (buf[2] == 'C'))
{
- u32b choice[2] = {0, 0};
+ std::array<u32b, 2> choice { };
if (0 != grab_one_class_flag(choice, buf + 6))
{
return (5);
@@ -1459,8 +1472,8 @@ errr init_player_info_txt(FILE *fp)
case '1': /* Class title */
/* Copy */
- assert(!c_ptr->titles[tit_idx]);
- c_ptr->titles[tit_idx] = my_strdup(s);
+ assert(c_ptr->titles[tit_idx].empty());
+ c_ptr->titles[tit_idx] = s;
/* Go to next title in array */
tit_idx++;
@@ -1569,7 +1582,7 @@ errr init_player_info_txt(FILE *fp)
{
int i;
- if (streq(buf + 4, "All Gods"))
+ if (equals(buf + 4, "All Gods"))
c_ptr->gods = 0xFFFFFFFF;
else
{
@@ -1588,15 +1601,14 @@ errr init_player_info_txt(FILE *fp)
char const *s = buf + 4;
/* Find it in the list */
- int i;
- for (i = 0; i < POWER_MAX; i++)
+ if (auto power_idx = find_power_idx(s))
{
- if (iequals(s, powers_type[i].name)) break;
+ c_ptr->ps.powers.push_back(*power_idx);
+ }
+ else
+ {
+ return 6;
}
-
- if (i == POWER_MAX) return (6);
-
- c_ptr->ps.powers.push_back(i);
/* Next... */
continue;
@@ -1738,7 +1750,7 @@ errr init_player_info_txt(FILE *fp)
{
int i;
- if (streq(buf + 6, "All Gods"))
+ if (equals(buf + 6, "All Gods"))
s_ptr->gods = 0xFFFFFFFF;
else
{
@@ -1885,7 +1897,7 @@ errr init_v_info_txt(FILE *fp)
if (buf[0] == 'D')
{
/* Acquire the text */
- cptr s = buf + 2;
+ const char *s = buf + 2;
/* Append data */
v_ptr->data += s;
@@ -1963,10 +1975,10 @@ errr init_v_info_txt(FILE *fp)
/*
* Grab one flag in an feature_type from a textual string
*/
-static int grab_one_feature_flag(cptr what, feature_flag_set *flags)
+static int grab_one_feature_flag(const char *what, feature_flag_set *flags)
{
#define FF(tier, index, name) \
- if (streq(what, #name)) \
+ if (equals(what, #name)) \
{ \
*flags |= BOOST_PP_CAT(FF_,name); \
return 0; \
@@ -2040,8 +2052,8 @@ errr init_f_info_txt(FILE *fp)
f_ptr = &expand_to_fit_index(f_info, i);
/* Copy name */
- assert(!f_ptr->name);
- f_ptr->name = my_strdup(s);
+ assert(f_ptr->name.empty());
+ f_ptr->name = s;
/* Initialize */
f_ptr->mimic = i;
@@ -2153,7 +2165,7 @@ errr init_f_info_txt(FILE *fp)
if (buf[0] == 'E')
{
int side, dice, freq, type;
- cptr tmp;
+ const char *tmp;
int i;
/* Find the next empty blow slot (if any) */
@@ -2183,12 +2195,17 @@ errr init_f_info_txt(FILE *fp)
j = 0;
while (d_info_dtypes[j].name != NULL)
- if (strcmp(d_info_dtypes[j].name, tmp) == 0)
+ {
+ if (equals(d_info_dtypes[j].name, tmp))
{
f_ptr->d_type[i] = d_info_dtypes[j].feat;
break;
}
- else j++;
+ else
+ {
+ j++;
+ }
+ }
if (d_info_dtypes[j].name == NULL) return (1);
}
@@ -2238,8 +2255,7 @@ errr init_k_info_txt(FILE *fp)
char *s, *t;
/* Current entry */
- object_kind *k_ptr = NULL;
-
+ std::shared_ptr<object_kind> k_ptr;
/* Just before the first record */
error_idx = -1;
@@ -2285,18 +2301,10 @@ errr init_k_info_txt(FILE *fp)
/* Save the index */
error_idx = i;
- /* Point at the "info" */
- k_ptr = &expand_to_fit_index(k_info, i);
-
- /* Advance and Save the name index */
- assert(!k_ptr->name);
- k_ptr->name = my_strdup(s);
-
- /* Ensure empty description */
- k_ptr->text = my_strdup("");
-
- /* Needed hack */
- k_ptr->power = -1;
+ /* Point at the "info"; automatically creates an entry */
+ k_info.emplace(std::make_pair(i, std::make_shared<object_kind>(i)));
+ k_ptr = k_info[i];
+ k_ptr->name = s;
/* Next... */
continue;
@@ -2311,15 +2319,13 @@ errr init_k_info_txt(FILE *fp)
/* Acquire the text */
s = buf + 2;
- if (!k_ptr->text)
- {
- k_ptr->text = my_strdup(s);
- }
- else
+ if (!k_ptr->text.empty())
{
- strappend(&k_ptr->text, format("\n%s", s));
+ k_ptr->text += '\n';
}
+ k_ptr->text += s;
+
/* Next... */
continue;
}
@@ -2374,7 +2380,15 @@ errr init_k_info_txt(FILE *fp)
{
char *spl = strchr(buf + 2, '=') + 1;
- pval2 = find_spell(spl);
+ if (auto spell_idx = find_spell(spl))
+ {
+ pval2 = *spell_idx;
+ }
+ else
+ {
+ msg_format("No spell '%s'.", spl);
+ return 1;
+ }
}
}
@@ -2427,20 +2441,18 @@ errr init_k_info_txt(FILE *fp)
/* Process 'Z' for "Granted power" */
if (buf[0] == 'Z')
{
- int i;
-
/* Acquire the text */
s = buf + 2;
/* Find it in the list */
- for (i = 0; i < POWER_MAX; i++)
+ if (auto power_idx = find_power_idx(s))
{
- if (iequals(s, powers_type[i].name)) break;
+ k_ptr->power = *power_idx;
+ }
+ else
+ {
+ return 6;
}
-
- if (i == POWER_MAX) return (6);
-
- k_ptr->power = i;
/* Next... */
continue;
@@ -2627,9 +2639,6 @@ errr init_a_info_txt(FILE *fp)
TR_IGNORE_FIRE |
TR_IGNORE_COLD;
- /* Needed hack */
- a_ptr->power = -1;
-
/*Require activating artifacts to have a activation type */
if (a_ptr && (a_ptr->flags & TR_ACTIVATE) && !a_ptr->activate)
{
@@ -2729,20 +2738,18 @@ errr init_a_info_txt(FILE *fp)
/* Process 'Z' for "Granted power" */
if (buf[0] == 'Z')
{
- int i;
-
/* Acquire the text */
s = buf + 2;
/* Find it in the list */
- for (i = 0; i < POWER_MAX; i++)
+ if (auto power_idx = find_power_idx(s))
{
- if (iequals(s, powers_type[i].name)) break;
+ a_ptr->power = *power_idx;
+ }
+ else
+ {
+ return 6;
}
-
- if (i == POWER_MAX) return (6);
-
- a_ptr->power = i;
/* Next... */
continue;
@@ -3085,7 +3092,7 @@ errr init_s_info_txt(FILE *fp)
expand_to_fit_index(s_info, i);
/* Copy name */
- s_ptr->name = my_strdup(s);
+ s_ptr->name = s;
/* Next... */
continue;
@@ -3355,7 +3362,7 @@ errr init_ab_info_txt(FILE *fp)
for (stat = 0; stat < 6; stat++)
{
- if (!strcmp(stat_names[stat], sec))
+ if (equals(stat_names[stat], sec))
break;
}
@@ -3382,7 +3389,7 @@ errr init_ab_info_txt(FILE *fp)
static ego_flag_set lookup_ego_flag(const char *what)
{
#define ETR(tier, index, name) \
- if (streq(what, #name)) \
+ if (equals(what, #name)) \
{ \
return BOOST_PP_CAT(ETR_,name); \
};
@@ -3397,13 +3404,13 @@ static ego_flag_set lookup_ego_flag(const char *what)
*
* We explicitly allow nullptr for the "ego" parameter.
*/
-static bool_ grab_one_ego_item_flag(object_flag_set *flags, ego_flag_set *ego, cptr what)
+static bool grab_one_ego_item_flag(object_flag_set *flags, ego_flag_set *ego, const char *what)
{
/* Lookup as an object_flag */
if (auto f = object_flag_set_from_string(what))
{
*flags |= f;
- return 0;
+ return false;
}
/* Lookup as ego flag */
@@ -3412,7 +3419,7 @@ static bool_ grab_one_ego_item_flag(object_flag_set *flags, ego_flag_set *ego, c
if (auto f = lookup_ego_flag(what))
{
*ego |= f;
- return (0);
+ return (false);
}
}
@@ -3420,7 +3427,7 @@ static bool_ grab_one_ego_item_flag(object_flag_set *flags, ego_flag_set *ego, c
msg_format("Unknown ego-item flag '%s'.", what);
/* Error */
- return (1);
+ return (true);
}
@@ -3489,10 +3496,7 @@ errr init_e_info_txt(FILE *fp)
/* Point at the "info" */
e_ptr = &expand_to_fit_index(e_info, i);
-
- /* Copy name */
- assert(!e_ptr->name);
- e_ptr->name = my_strdup(s);
+ e_ptr->name = s;
/* Next... */
continue;
@@ -3559,7 +3563,7 @@ errr init_e_info_txt(FILE *fp)
/* Save the values */
/* e_ptr->slot = slot; */
e_ptr->rating = rating;
- e_ptr->before = (pos == 'B') ? TRUE : FALSE;
+ e_ptr->before = (pos == 'B');
/* Next... */
continue;
@@ -3606,20 +3610,18 @@ errr init_e_info_txt(FILE *fp)
/* Process 'Z' for "Granted power" */
if (buf[0] == 'Z')
{
- int i;
-
/* Acquire the text */
s = buf + 2;
/* Find it in the list */
- for (i = 0; i < POWER_MAX; i++)
+ if (auto power_idx = find_power_idx(s))
{
- if (iequals(s, powers_type[i].name)) break;
+ e_ptr->power = *power_idx;
+ }
+ else
+ {
+ return 6;
}
-
- if (i == POWER_MAX) return (6);
-
- e_ptr->power = i;
/* Next... */
continue;
@@ -3920,20 +3922,15 @@ errr init_ra_info_txt(FILE *fp)
char const *s = buf + 2;
/* Find it in the list */
- std::size_t i;
- for (i = 0; i < POWER_MAX; i++)
+ if (auto power_idx = find_power_idx(s))
{
- if (iequals(s, powers_type[i].name)) break;
+ ra_ptr->power = *power_idx;
}
-
- /* Not present? Fail */
- if (i == POWER_MAX)
+ else
{
- return (6);
+ return 6;
}
- ra_ptr->power = i;
-
/* Next... */
continue;
}
@@ -3977,10 +3974,10 @@ errr init_ra_info_txt(FILE *fp)
}
-static errr grab_monster_race_flag(monster_race_flag_set *flags, cptr what)
+static errr grab_monster_race_flag(monster_race_flag_set *flags, const char *what)
{
#define RF(tier, index, name) \
- if (streq(what, #name)) \
+ if (equals(what, #name)) \
{ \
*flags |= BOOST_PP_CAT(RF_,name); \
return 0; \
@@ -3999,11 +3996,11 @@ static errr grab_monster_race_flag(monster_race_flag_set *flags, cptr what)
/*
* Grab one (spell) flag in a monster_race from a textual string
*/
-static errr grab_one_monster_spell_flag(monster_spell_flag_set *flags, cptr what)
+static errr grab_one_monster_spell_flag(monster_spell_flag_set *flags, const char *what)
{
for (auto const &monster_spell: monster_spells())
{
- if (streq(what, monster_spell->name))
+ if (equals(what, monster_spell->name))
{
*flags |= monster_spell->flag_set;
return 0;
@@ -4263,7 +4260,7 @@ errr init_r_info_txt(FILE *fp)
/* Analyze the method */
for (n1 = 0; r_info_blow_method[n1]; n1++)
{
- if (streq(s, r_info_blow_method[n1])) break;
+ if (equals(s, r_info_blow_method[n1])) break;
}
/* Invalid method */
@@ -4278,7 +4275,7 @@ errr init_r_info_txt(FILE *fp)
/* Analyze effect */
for (n2 = 0; r_info_blow_effect[n2]; n2++)
{
- if (streq(s, r_info_blow_effect[n2])) break;
+ if (equals(s, r_info_blow_effect[n2])) break;
}
/* Invalid effect */
@@ -4506,7 +4503,7 @@ errr init_re_info_txt(FILE *fp)
re_ptr->rarity = rar;
re_ptr->weight = (wt << 2) + monster_ego_modify(mwt);
re_ptr->mexp = (exp << 2) + monster_ego_modify(mexp);
- re_ptr->before = (pos == 'B') ? TRUE : FALSE;
+ re_ptr->before = (pos == 'B') ? true : false;
/* Next... */
continue;
@@ -4532,7 +4529,7 @@ errr init_re_info_txt(FILE *fp)
/* Analyze the method */
for (n1 = 0; r_info_blow_method[n1]; n1++)
{
- if (streq(s, r_info_blow_method[n1])) break;
+ if (equals(s, r_info_blow_method[n1])) break;
}
/* Invalid method */
@@ -4547,7 +4544,7 @@ errr init_re_info_txt(FILE *fp)
/* Analyze effect */
for (n2 = 0; r_info_blow_effect[n2]; n2++)
{
- if (streq(s, r_info_blow_effect[n2])) break;
+ if (equals(s, r_info_blow_effect[n2])) break;
}
/* Invalid effect */
@@ -4651,7 +4648,7 @@ errr init_re_info_txt(FILE *fp)
char const *s = buf + 2;
/* XXX XXX XXX Hack -- Read no flags */
- if (!strcmp(s, "MF_ALL"))
+ if (equals(s, "MF_ALL"))
{
re_ptr->nflags = ~monster_race_flag_set();
}
@@ -4712,7 +4709,7 @@ errr init_re_info_txt(FILE *fp)
}
/* XXX XXX XXX Hack -- Read no flags */
- if (!strcmp(s, "MF_ALL"))
+ if (equals(s, "MF_ALL"))
{
/* No flags */
re_ptr->nspells = ~monster_spell_flag_set();
@@ -4750,7 +4747,7 @@ errr init_re_info_txt(FILE *fp)
errr grab_one_dungeon_flag(dungeon_flag_set *flags, const char *str)
{
#define DF(tier, index, name) \
- if (streq(str, #name)) { *flags |= DF_##name; return 0; }
+ if (equals(str, #name)) { *flags |= DF_##name; return 0; }
#include "dungeon_flag_list.hpp"
#undef DF
@@ -4763,6 +4760,44 @@ errr grab_one_dungeon_flag(dungeon_flag_set *flags, const char *str)
/*
+ * Post-process "d_info" array.
+ */
+static void post_d_info()
+{
+ auto &d_info = game->edit_data.d_info;
+
+ for (std::size_t parent_d_idx = 0; parent_d_idx < d_info.size(); parent_d_idx++)
+ {
+ auto parent_d_ptr = &d_info[parent_d_idx];
+
+ if (parent_d_ptr->name.empty())
+ {
+ continue;
+ }
+
+ // Go through all the references to side dungeons
+ // and fill in back-references to "parent" dungeons.
+ for (auto &parent_depth_and_level_data: parent_d_ptr->level_data_by_depth)
+ {
+ auto parent_depth = std::get<0>(parent_depth_and_level_data);
+ auto &parent_level_data = std::get<1>(parent_depth_and_level_data);
+
+ // Do we have a branch-off point at this level?
+ if (parent_level_data.branch > 0)
+ {
+ // Look up target dungeon.
+ auto child_d_ptr = &d_info[parent_level_data.branch];
+ auto &child_level_data = child_d_ptr->level_data_by_depth[child_d_ptr->mindepth];
+
+ // Set up back-reference.
+ child_level_data.fbranch = parent_d_idx;
+ child_level_data.flevel = parent_depth - parent_d_ptr->mindepth;
+ }
+ }
+ }
+}
+
+/*
* Initialize the "d_info" array, by parsing an ascii "template" file
*/
errr init_d_info_txt(FILE *fp)
@@ -5011,7 +5046,7 @@ errr init_d_info_txt(FILE *fp)
if (buf[0] == 'E')
{
int side, dice, freq, type;
- cptr tmp;
+ const char *tmp;
/* Find the next empty blow slot (if any) */
std::size_t i;
@@ -5047,7 +5082,7 @@ errr init_d_info_txt(FILE *fp)
j = 0;
while (d_info_dtypes[j].name != NULL)
- if (strcmp(d_info_dtypes[j].name, tmp) == 0)
+ if (equals(d_info_dtypes[j].name, tmp))
{
d_ptr->d_type[i] = d_info_dtypes[j].feat;
break;
@@ -5211,10 +5246,64 @@ errr init_d_info_txt(FILE *fp)
continue;
}
+ /* Process '@' for level-dependent information */
+ if (buf[0] == '@')
+ {
+ /* Split into fields */
+ std::string buf_s(buf + 2);
+ std::vector<std::string> fields;
+ boost::algorithm::split(fields, buf_s, boost::is_any_of(":"));
+
+ // Get the depth; depths are relative to the first floor
+ // of the dungeon. This is consistent with the handling of
+ // the 'A' flag.
+ int const depth = std::stoi(fields[0]);
+ auto &level_data = d_ptr->level_data_by_depth[depth + d_ptr->mindepth];
+
+ // Parse into appropriate field.
+ if (fields[1] == "B")
+ {
+ level_data.branch = std::stoi(fields[2]);
+ }
+ else if (fields[1] == "F")
+ {
+ if (0 != grab_one_dungeon_flag(&level_data.flags, fields[2].c_str()))
+ {
+ return 5;
+ }
+ }
+ else if (fields[1] == "S")
+ {
+ level_data.save_extension = fields[2];
+ }
+ else if (fields[1] == "U")
+ {
+ level_data.map_name = fields[2];
+ }
+ else if (fields[1] == "N")
+ {
+ level_data.name = fields[2];
+ }
+ else if (fields[1] == "D")
+ {
+ level_data.description = fields[2];
+ }
+ else
+ {
+ return 1;
+ }
+
+ /* Next... */
+ continue;
+ }
+
/* Oops */
return (6);
}
+ /* Post-process */
+ post_d_info();
+
/* Success */
return (0);
}
@@ -5222,25 +5311,25 @@ errr init_d_info_txt(FILE *fp)
/*
* Grab one race flag from a textual string
*/
-static errr grab_one_race_flag(owner_type *ow_ptr, int state, cptr what)
+static errr grab_one_race_flag(owner_type *ow_ptr, int state, const char *what)
{
/* Scan race flags */
- unknown_shut_up = TRUE;
+ unknown_shut_up = true;
if (!grab_one_race_allow_flag(ow_ptr->races[state], what))
{
- unknown_shut_up = FALSE;
+ unknown_shut_up = false;
return (0);
}
/* Scan classes flags */
if (!grab_one_class_flag(ow_ptr->classes[state], what))
{
- unknown_shut_up = FALSE;
+ unknown_shut_up = false;
return (0);
}
/* Oops */
- unknown_shut_up = FALSE;
+ unknown_shut_up = false;
msg_format("Unknown race/class flag '%s'.", what);
/* Failure */
@@ -5250,10 +5339,10 @@ static errr grab_one_race_flag(owner_type *ow_ptr, int state, cptr what)
/*
* Grab one store flag from a textual string
*/
-static errr grab_one_store_flag(store_flag_set *flags, cptr what)
+static errr grab_one_store_flag(store_flag_set *flags, const char *what)
{
#define STF(tier, index, name) \
- if (streq(what, #name)) { \
+ if (equals(what, #name)) { \
*flags |= BOOST_PP_CAT(STF_,name); \
return 0; \
}
@@ -5352,10 +5441,17 @@ errr init_st_info_txt(FILE *fp)
if (!*s) return (1);
/* Add to items array */
- store_item item;
- item.chance = atoi(buf + 2);
- item.kind = test_item_name(s);
- st_ptr->items.emplace_back(item);
+ auto chance = atoi(buf + 2);
+ int k_idx = test_item_name(s);
+
+ if (k_idx < 0)
+ {
+ msg_format("Unknown k_info entry: [%s].", s);
+ return 1;
+ }
+
+ st_ptr->items.emplace_back(
+ store_item::k_idx(k_idx, chance));
/* Next... */
continue;
@@ -5371,11 +5467,10 @@ errr init_st_info_txt(FILE *fp)
&rar1, &tv1, &sv1)) return (1);
/* Add to the items array */
- store_item item;
- item.chance = rar1;
- item.kind = (sv1 < 256)
- ? lookup_kind(tv1, sv1)
- : tv1 + 10000; /* An SVAL of 256 means all possible items. */
+ store_item item = (sv1 < 256)
+ ? store_item::k_idx(lookup_kind(tv1, sv1), rar1)
+ : store_item::tval(tv1, rar1); /* An SVAL of 256 means all possible items. */
+
st_ptr->items.emplace_back(item);
/* Next... */
@@ -5912,21 +6007,23 @@ struct dungeon_grid
int bx, by; /* For between gates */
int mimic; /* Mimiced features */
s32b mflag; /* monster's mflag */
- bool_ ok;
- bool_ defined;
+ bool ok;
+ bool defined;
};
-static bool_ meta_sleep = TRUE;
+static bool meta_sleep = true;
static dungeon_grid letter[255];
/*
* Parse a sub-file of the "extra info"
*/
-static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalstart, int ymax, int xmax, bool_ full)
+static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalstart, int ymax, int xmax, bool full)
{
auto &wilderness = game->wilderness;
auto &wf_info = game->edit_data.wf_info;
auto &a_info = game->edit_data.a_info;
+ auto &k_info = game->edit_data.k_info;
+ auto &dungeon_flags = game->dungeon_flags;
int i;
@@ -5950,7 +6047,7 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst
if (buf[0] == '%')
{
/* Attempt to Process the given file */
- return (process_dungeon_file(buf + 2, yval, xval, ymax, xmax, FALSE, full));
+ return (process_dungeon_file(buf + 2, yval, xval, ymax, xmax, false, full));
}
/* Process "N:<sleep>" */
@@ -5986,8 +6083,8 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst
letter[index].random = 0;
letter[index].mimic = 0;
letter[index].mflag = 0;
- letter[index].ok = TRUE;
- letter[index].defined = TRUE;
+ letter[index].ok = true;
+ letter[index].defined = true;
if (num > 1)
{
@@ -6096,7 +6193,7 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst
letter[index].special = 0;
for (i = 0; i < MAX_Q_IDX; i++)
{
- if (!strcmp(&field[1], quest[i].name))
+ if (equals(&field[1], quest[i].name))
{
letter[index].special = i;
break;
@@ -6200,16 +6297,16 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst
monster_level = quest[p_ptr->inside_quest].level + monster_index;
- m_idx = place_monster(y, x, meta_sleep, FALSE);
+ m_idx = place_monster(y, x, meta_sleep, false);
monster_level = level;
}
else if (monster_index)
{
/* Place it */
- m_allow_special[monster_index] = TRUE;
- m_idx = place_monster_aux(y, x, monster_index, meta_sleep, FALSE, MSTATUS_ENEMY);
- m_allow_special[monster_index] = FALSE;
+ m_allow_special[monster_index] = true;
+ m_idx = place_monster_aux(y, x, monster_index, meta_sleep, false, MSTATUS_ENEMY);
+ m_allow_special[monster_index] = false;
}
/* Set the mflag of the monster */
@@ -6225,25 +6322,25 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst
object_level = quest[p_ptr->inside_quest].level + object_index;
if (rand_int(100) < 75)
- place_object(y, x, FALSE, FALSE, OBJ_FOUND_SPECIAL);
+ place_object(y, x, false, false, OBJ_FOUND_SPECIAL);
else if (rand_int(100) < 80)
- place_object(y, x, TRUE, FALSE, OBJ_FOUND_SPECIAL);
+ place_object(y, x, true, false, OBJ_FOUND_SPECIAL);
else
- place_object(y, x, TRUE, TRUE, OBJ_FOUND_SPECIAL);
+ place_object(y, x, true, true, OBJ_FOUND_SPECIAL);
object_level = level;
}
else if (rand_int(100) < 75)
{
- place_object(y, x, FALSE, FALSE, OBJ_FOUND_SPECIAL);
+ place_object(y, x, false, false, OBJ_FOUND_SPECIAL);
}
else if (rand_int(100) < 80)
{
- place_object(y, x, TRUE, FALSE, OBJ_FOUND_SPECIAL);
+ place_object(y, x, true, false, OBJ_FOUND_SPECIAL);
}
else
{
- place_object(y, x, TRUE, TRUE, OBJ_FOUND_SPECIAL);
+ place_object(y, x, true, true, OBJ_FOUND_SPECIAL);
}
}
else if (object_index)
@@ -6251,17 +6348,17 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst
/* Get local object */
object_type *o_ptr = &object_type_body;
- k_allow_special[object_index] = TRUE;
+ k_info[object_index]->allow_special = true;
/* Create the item */
object_prep(o_ptr, object_index);
/* Apply magic (no messages, no artifacts) */
- apply_magic(o_ptr, dun_level, FALSE, TRUE, FALSE);
+ apply_magic(o_ptr, dun_level, false, true, false);
o_ptr->found = OBJ_FOUND_SPECIAL;
- k_allow_special[object_index] = FALSE;
+ k_info[object_index]->allow_special = false;
drop_near(o_ptr, -1, y, x);
}
@@ -6277,7 +6374,7 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst
object_type forge;
object_type *q_ptr = &forge;
- a_allow_special[artifact_index] = TRUE;
+ a_allow_special[artifact_index] = true;
/* Wipe the object */
object_wipe(q_ptr);
@@ -6306,7 +6403,7 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst
a_info[artifact_index].cur_num = 1;
- a_allow_special[artifact_index] = FALSE;
+ a_allow_special[artifact_index] = false;
/* It's amazing that this "creating objects anywhere"
junk ever worked.
@@ -6527,10 +6624,10 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst
/*
* Helper function for "process_dungeon_file()"
*/
-static cptr process_dungeon_file_expr(char **sp, char *fp)
+static const char *process_dungeon_file_expr(char **sp, char *fp)
{
static char pref_tmp_value[8];
- cptr v;
+ const char *v;
char *b;
char *s;
@@ -6571,40 +6668,40 @@ static cptr process_dungeon_file_expr(char **sp, char *fp)
}
/* Function: IOR */
- else if (streq(t, "IOR"))
+ else if (equals(t, "IOR"))
{
v = "0";
while (*s && (f != b2))
{
t = process_dungeon_file_expr(&s, &f);
- if (*t && !streq(t, "0")) v = "1";
+ if (*t && !equals(t, "0")) v = "1";
}
}
/* Function: AND */
- else if (streq(t, "AND"))
+ else if (equals(t, "AND"))
{
v = "1";
while (*s && (f != b2))
{
t = process_dungeon_file_expr(&s, &f);
- if (*t && streq(t, "0")) v = "0";
+ if (*t && equals(t, "0")) v = "0";
}
}
/* Function: NOT */
- else if (streq(t, "NOT"))
+ else if (equals(t, "NOT"))
{
v = "1";
while (*s && (f != b2))
{
t = process_dungeon_file_expr(&s, &f);
- if (*t && streq(t, "1")) v = "0";
+ if (*t && equals(t, "1")) v = "0";
}
}
/* Function: EQU */
- else if (streq(t, "EQU"))
+ else if (equals(t, "EQU"))
{
v = "1";
if (*s && (f != b2))
@@ -6615,39 +6712,7 @@ static cptr process_dungeon_file_expr(char **sp, char *fp)
{
p = t;
t = process_dungeon_file_expr(&s, &f);
- if (*t && !streq(p, t)) v = "0";
- }
- }
-
- /* Function: LEQ */
- else if (streq(t, "LEQ"))
- {
- v = "1";
- if (*s && (f != b2))
- {
- t = process_dungeon_file_expr(&s, &f);
- }
- while (*s && (f != b2))
- {
- p = t;
- t = process_dungeon_file_expr(&s, &f);
- if (*t && (strcmp(p, t) > 0)) v = "0";
- }
- }
-
- /* Function: GEQ */
- else if (streq(t, "GEQ"))
- {
- v = "1";
- if (*s && (f != b2))
- {
- t = process_dungeon_file_expr(&s, &f);
- }
- while (*s && (f != b2))
- {
- p = t;
- t = process_dungeon_file_expr(&s, &f);
- if (*t && (strcmp(p, t) < 0)) v = "0";
+ if (*t && !equals(p, t)) v = "0";
}
}
@@ -6670,7 +6735,7 @@ static cptr process_dungeon_file_expr(char **sp, char *fp)
/* Other */
else
{
- bool_ text_mode = FALSE;
+ bool text_mode = false;
/* Accept all printables except spaces and brackets */
while (isprint(*s))
@@ -6696,66 +6761,29 @@ static cptr process_dungeon_file_expr(char **sp, char *fp)
/* Variable */
if (*b == '$')
{
- /* System */
- if (streq(b + 1, "SYS"))
- {
- v = ANGBAND_SYS;
- }
-
- /* Race */
- else if (streq(b + 1, "RACE"))
- {
- v = rp_ptr->title.c_str(); // The string SHOULD be stable enough for this
- }
-
- /* Race Mod */
- else if (streq(b + 1, "RACEMOD"))
- {
- v = rmp_ptr->title.c_str(); // The string SHOULD be stable enough for this
- }
-
- /* Class */
- else if (streq(b + 1, "CLASS"))
- {
- v = cp_ptr->title.c_str(); // The string SHOULD be stable enough for this
- }
-
- /* Player */
- else if (streq(b + 1, "PLAYER"))
- {
- v = game->player_base.c_str(); // The string SHOULD be stable enough for this
- }
-
/* Town */
- else if (streq(b + 1, "TOWN"))
+ if (equals(b + 1, "TOWN"))
{
strnfmt(pref_tmp_value, 8, "%d", p_ptr->town_num);
v = pref_tmp_value;
}
/* Town destroyed */
- else if (prefix(b + 1, "TOWN_DESTROY"))
+ else if (starts_with(b + 1, "TOWN_DESTROY"))
{
strnfmt(pref_tmp_value, 8, "%d", town_info[atoi(b + 13)].destroyed);
v = pref_tmp_value;
}
- /* Current quest number */
- else if (streq(b + 1, "QUEST_NUMBER"))
- {
- strnfmt(pref_tmp_value, 8, "%d", p_ptr->inside_quest);
- v = pref_tmp_value;
- }
-
/* Number of last quest */
- else if (streq(b + 1, "LEAVING_QUEST"))
+ else if (equals(b + 1, "LEAVING_QUEST"))
{
strnfmt(pref_tmp_value, 8, "%d", leaving_quest);
v = pref_tmp_value;
}
/* DAYTIME status */
- else if (prefix(b + 1, "DAYTIME"))
+ else if (starts_with(b + 1, "DAYTIME"))
{
if ((bst(HOUR, turn) >= 6) && (bst(HOUR, turn) < 18))
v = "1";
@@ -6764,7 +6792,7 @@ static cptr process_dungeon_file_expr(char **sp, char *fp)
}
/* Quest status */
- else if (prefix(b + 1, "QUEST"))
+ else if (starts_with(b + 1, "QUEST"))
{
/* "QUEST" uses a special parameter to determine the number of the quest */
if (*(b + 6) != '"')
@@ -6783,7 +6811,7 @@ static cptr process_dungeon_file_expr(char **sp, char *fp)
strcpy(pref_tmp_value, "-1");
for (i = 0; i < MAX_Q_IDX; i++)
{
- if (streq(c, quest[i].name))
+ if (equals(c, quest[i].name))
{
strnfmt(pref_tmp_value, 8, "%d", quest[i].status);
break;
@@ -6793,17 +6821,6 @@ static cptr process_dungeon_file_expr(char **sp, char *fp)
v = pref_tmp_value;
}
- /* Variant name */
- else if (streq(b + 1, "VARIANT"))
- {
- v = "ToME";
- }
-
- /* Wilderness */
- else if (streq(b + 1, "WILDERNESS"))
- {
- v = "NORMAL";
- }
}
/* Constant */
@@ -6824,7 +6841,7 @@ static cptr process_dungeon_file_expr(char **sp, char *fp)
}
-errr process_dungeon_file(cptr name, int *yval, int *xval, int ymax, int xmax, bool_ init, bool_ full)
+errr process_dungeon_file(const char *name, int *yval, int *xval, int ymax, int xmax, bool init, bool full)
{
FILE *fp = 0;
@@ -6834,19 +6851,19 @@ errr process_dungeon_file(cptr name, int *yval, int *xval, int ymax, int xmax, b
errr err = 0;
- bool_ bypass = FALSE;
+ bool bypass = false;
/* Save the start since it ought to be modified */
int xmin = *xval;
if (init)
{
- meta_sleep = TRUE;
+ meta_sleep = true;
for (i = 0; i < 255; i++)
{
- letter[i].defined = FALSE;
- if (i == ' ') letter[i].ok = TRUE;
- else letter[i].ok = FALSE;
+ letter[i].defined = false;
+ if (i == ' ') letter[i].ok = true;
+ else letter[i].ok = false;
letter[i].bx = 0;
letter[i].by = 0;
}
@@ -6886,7 +6903,7 @@ errr process_dungeon_file(cptr name, int *yval, int *xval, int ymax, int xmax, b
if ((buf[0] == '?') && (buf[1] == ':'))
{
char f;
- cptr v;
+ const char *v;
char *s;
/* Start */
@@ -6896,7 +6913,7 @@ errr process_dungeon_file(cptr name, int *yval, int *xval, int ymax, int xmax, b
v = process_dungeon_file_expr(&s, &f);
/* Set flag */
- bypass = (streq(v, "0") ? TRUE : FALSE);
+ bypass = (equals(v, "0") ? true : false);
/* Continue */
continue;
@@ -6910,7 +6927,7 @@ errr process_dungeon_file(cptr name, int *yval, int *xval, int ymax, int xmax, b
if (buf[0] == '%')
{
/* Process that file if allowed */
- process_dungeon_file(buf + 2, yval, xval, ymax, xmax, FALSE, full);
+ process_dungeon_file(buf + 2, yval, xval, ymax, xmax, false, full);
/* Continue */
continue;
diff --git a/src/init1.hpp b/src/init1.hpp
index 1c417285..577c5b00 100644
--- a/src/init1.hpp
+++ b/src/init1.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "dungeon_flag_set.hpp"
int color_char_to_attr(char c);
@@ -24,4 +24,4 @@ errr init_st_info_txt(FILE *fp);
errr init_ow_info_txt(FILE *fp);
errr init_wf_info_txt(FILE *fp);
errr grab_one_dungeon_flag(dungeon_flag_set *flags, const char *str);
-errr process_dungeon_file(cptr name, int *yval, int *xval, int ymax, int xmax, bool_ init, bool_ full);
+errr process_dungeon_file(const char *name, int *yval, int *xval, int ymax, int xmax, bool init, bool full);
diff --git a/src/init2.cc b/src/init2.cc
index 894e4767..0afaa5ce 100644
--- a/src/init2.cc
+++ b/src/init2.cc
@@ -1,5 +1,4 @@
#include "init2.hpp"
-#include "init2.h"
#include "ability_type.hpp"
#include "alloc_entry.hpp"
@@ -7,6 +6,7 @@
#include "cave.hpp"
#include "cave_type.hpp"
#include "cli_comm.hpp"
+#include "config.hpp"
#include "dungeon_info_type.hpp"
#include "ego_item_type.hpp"
#include "files.hpp"
@@ -48,16 +48,21 @@
#include "tome/make_array.hpp"
#include "town_type.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "vault_type.hpp"
#include "wilderness_map.hpp"
#include "wilderness_type_info.hpp"
+#include "z-form.hpp"
+#include "z-util.hpp"
+#include <boost/algorithm/string/predicate.hpp>
#include <cassert>
+#include <fcntl.h>
+#include <fmt/format.h>
#include <type_traits>
+using boost::algorithm::equals;
+
/*
* This file is used to initialise various variables and arrays for the
* Angband game. Note the use of "fd_read()" and "fd_write()" to bypass
@@ -125,8 +130,6 @@ void init_file_paths(char *path)
free(ANGBAND_DIR);
/* Free the sub-paths */
- free(ANGBAND_DIR_CORE);
- free(ANGBAND_DIR_DNGN);
free(ANGBAND_DIR_DATA);
free(ANGBAND_DIR_EDIT);
free(ANGBAND_DIR_FILE);
@@ -149,7 +152,7 @@ void init_file_paths(char *path)
{
int seplen = strlen(PATH_SEP);
- if (strcmp(path + pathlen - seplen, PATH_SEP) == 0)
+ if (equals(path + pathlen - seplen, PATH_SEP))
{
path[pathlen - seplen] = '\0';
ANGBAND_DIR = strdup(path);
@@ -173,14 +176,6 @@ void init_file_paths(char *path)
/*** Build the sub-directory names ***/
/* Build a path name */
- strcpy(tail, "core");
- ANGBAND_DIR_CORE = strdup(path);
-
- /* Build a path name */
- strcpy(tail, "dngn");
- ANGBAND_DIR_DNGN = strdup(path);
-
- /* Build a path name */
strcpy(tail, "data");
ANGBAND_DIR_DATA = strdup(path);
@@ -240,7 +235,7 @@ s16b error_line;
/*
* Standard error message text
*/
-static cptr err_str[9] =
+static const char *err_str[9] =
{
NULL,
"parse error",
@@ -257,7 +252,7 @@ static cptr err_str[9] =
/*
* Hack -- take notes on line 23
*/
-static void note(cptr str)
+static void note(const char *str)
{
Term_erase(0, 23, 255);
Term_putstr(20, 23, -1, TERM_WHITE, str);
@@ -484,7 +479,7 @@ template<typename T> static errr init_x_info() {
if (err)
{
/* Error string */
- cptr oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
+ const char *oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
/* Oops */
msg_format("Error %d at line %d of '%s'.", err, error_line, T::name);
@@ -512,7 +507,7 @@ static void init_basic()
/* Macro variables */
macro__pat = make_array<char *>(MACRO_MAX);
macro__act = make_array<char *>(MACRO_MAX);
- macro__cmd = make_array<bool_>(MACRO_MAX);
+ macro__cmd = make_array<bool>(MACRO_MAX);
/* Macro action buffer */
macro__buf = make_array<char>(1024);
@@ -530,18 +525,12 @@ static void init_basic()
*/
static errr init_misc()
{
- int xstart = 0;
- int ystart = 0;
- int i;
-
- /*** Prepare the various "bizarre" arrays ***/
-
/* Initialise the values */
- process_dungeon_file("misc.txt", &ystart, &xstart, 0, 0, TRUE, FALSE);
-
- /* Init the spell effects */
- for (i = 0; i < MAX_EFFECTS; i++)
- effects[i].time = 0;
+ {
+ int xstart = 0;
+ int ystart = 0;
+ process_dungeon_file("misc.txt", &ystart, &xstart, 0, 0, true, false);
+ }
/* Initialize timers */
TIMER_INERTIA_CONTROL =
@@ -608,7 +597,7 @@ void create_stores_stock(int t)
st_ptr->stock.reserve(st_ptr->stock_size);
}
- t_ptr->stocked = TRUE;
+ t_ptr->stocked = true;
}
/*
@@ -618,16 +607,14 @@ static errr init_other()
{
auto const &d_info = game->edit_data.d_info;
auto const &r_info = game->edit_data.r_info;
- auto const &k_info = game->edit_data.k_info;
auto const &a_info = game->edit_data.a_info;
auto &level_markers = game->level_markers;
/*** Prepare the "dungeon" information ***/
/* Allocate and Wipe the special gene flags */
- m_allow_special = make_array<bool_>(r_info.size());
- k_allow_special = make_array<bool_>(k_info.size());
- a_allow_special = make_array<bool_>(a_info.size());
+ m_allow_special = make_array<bool>(r_info.size());
+ a_allow_special = make_array<bool>(a_info.size());
/*** Prepare "vinfo" array ***/
@@ -678,14 +665,12 @@ static errr init_other()
/*
* Install the various level generators
*/
- add_level_generator("dungeon", level_generate_dungeon);
- add_level_generator("maze", level_generate_maze);
- add_level_generator("life", level_generate_life);
-
- /*** Pre-allocate space for the "format()" buffer ***/
-
- /* Hack -- Just call the "format()" function */
- format("%s (%s).", "Dark God <darkgod@t-o-m-e.net>", MAINTAINER);
+ {
+ auto &g = game->level_generators;
+ g.insert({ "dungeon", level_generate_dungeon });
+ g.insert({ "maze", level_generate_maze });
+ g.insert({ "life", level_generate_life });
+ }
/* Success */
return (0);
@@ -716,9 +701,9 @@ static errr init_alloc()
/* Scan the objects */
std::size_t kind_size = 0;
- for (auto const &k_ref: k_info)
+ for (auto const &k_entry: k_info)
{
- auto k_ptr = &k_ref;
+ auto const &k_ptr = k_entry.second;
/* Scan allocation pairs */
for (std::size_t j = 0; j < ALLOCATION_MAX; j++)
@@ -753,9 +738,9 @@ static errr init_alloc()
alloc.kind_table.resize(kind_size);
/* Scan the objects */
- for (std::size_t i = 1; i < k_info.size(); i++)
+ for (auto const &k_entry: k_info)
{
- auto k_ptr = &k_info[i];
+ auto const &k_ptr = k_entry.second;
/* Scan allocation pairs */
for (std::size_t j = 0; j < ALLOCATION_MAX; j++)
@@ -779,7 +764,7 @@ static errr init_alloc()
/* Load the entry */
auto &entry = alloc.kind_table[z];
- entry.index = i;
+ entry.index = k_entry.first;
entry.level = x;
entry.prob1 = p;
entry.prob2 = p;
@@ -930,7 +915,7 @@ static void init_guardians()
/* Mark the final object */
if (d_ptr->final_object)
{
- auto k_ptr = &k_info[d_ptr->final_object];
+ auto const &k_ptr = k_info.at(d_ptr->final_object);
k_ptr->flags |= TR_SPECIAL_GENE;
}
@@ -950,7 +935,7 @@ static void init_guardians()
* may or may not be initialised, but the "plog()" and "quit()"
* functions are "supposed" to work under any conditions.
*/
-static void init_angband_aux(cptr why)
+static void init_angband_aux(const char *why)
{
/* Why */
plog(why);
@@ -1017,7 +1002,7 @@ static void init_angband_aux(cptr why)
* Note that the "graf-xxx.prf" file must be loaded separately,
* if needed, in the first (?) pass through "TERM_XTRA_REACT".
*/
-void init_angband()
+void init_angband(program_args const &args)
{
int fd = -1;
@@ -1033,7 +1018,7 @@ void init_angband()
init_basic();
/* Select & init a module if needed */
- select_module();
+ select_module(args);
/*** Choose which news.txt file to use ***/
@@ -1249,29 +1234,17 @@ void init_angband()
/* Initialise feature info */
note("[Initialising user pref files...]");
- /* Access the "basic" pref file */
- strcpy(buf, "pref.prf");
-
- /* Process that file */
- process_pref_file(buf);
-
- /* Access the "basic" system pref file */
- sprintf(buf, "pref-%s.prf", ANGBAND_SYS);
-
- /* Process that file */
- process_pref_file(buf);
-
- /* Access the "user" pref file */
- sprintf(buf, "user.prf");
+ /* Process the "basic" pref file */
+ process_pref_file(name_file_pref("pref"));
- /* Process that file */
- process_pref_file(buf);
+ /* Process the "basic" system pref file */
+ process_pref_file(name_file_pref(fmt::format("pref-{}", ANGBAND_SYS)));
- /* Access the "user" system pref file */
- sprintf(buf, "user-%s.prf", ANGBAND_SYS);
+ /* Process the "user" pref file */
+ process_pref_file(name_file_pref("user"));
- /* Process that file */
- process_pref_file(buf);
+ /* Process the "user" system pref file */
+ process_pref_file(name_file_pref(fmt::format("user-{}", ANGBAND_SYS)));
/* Done */
note("[Initialisation complete]");
diff --git a/src/init2.h b/src/init2.h
deleted file mode 100644
index bdc525bf..00000000
--- a/src/init2.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-// C linkage required for these functions since main-* code uses them.
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void init_file_paths(char *path);
-void init_angband();
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/src/init2.hpp b/src/init2.hpp
index de575e77..0317dabd 100644
--- a/src/init2.hpp
+++ b/src/init2.hpp
@@ -1,7 +1,10 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
+#include "program_args.hpp"
+void init_file_paths(char *path);
+void init_angband(program_args const &);
void init_corruptions();
void create_stores_stock(int t);
errr init_v_info();
diff --git a/src/inscription_info_type.hpp b/src/inscription_info_type.hpp
index 4e1e4c32..783ac366 100644
--- a/src/inscription_info_type.hpp
+++ b/src/inscription_info_type.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* Inscriptions
diff --git a/src/joke.cc b/src/joke.cc
index 07149b3f..72bc403d 100644
--- a/src/joke.cc
+++ b/src/joke.cc
@@ -15,7 +15,7 @@ static void gen_joke_place_monster(int r_idx)
int x = randint(cur_hgt - 4) + 2;
int y = randint(cur_wid - 4) + 2;
- if (place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_ENEMY))
+ if (place_monster_one(y, x, r_idx, 0, false, MSTATUS_ENEMY))
{
return;
}
@@ -30,11 +30,11 @@ bool gen_joke_monsters(void *data, void *in, void *out)
(dun_level == 72))
{
int r_idx = test_monster_name("Neil, the Sorceror");
- m_allow_special[r_idx] = TRUE;
+ m_allow_special[r_idx] = true;
gen_joke_place_monster(r_idx);
- m_allow_special[r_idx] = FALSE;
+ m_allow_special[r_idx] = false;
}
}
- return FALSE;
+ return false;
}
diff --git a/src/joke.hpp b/src/joke.hpp
index 2721636e..e00d1ef0 100644
--- a/src/joke.hpp
+++ b/src/joke.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
bool gen_joke_monsters(void *data, void *in, void *out);
diff --git a/src/key_queue.cc b/src/key_queue.cc
new file mode 100644
index 00000000..7d611e3a
--- /dev/null
+++ b/src/key_queue.cc
@@ -0,0 +1 @@
+#include "key_queue.hpp"
diff --git a/src/key_queue.hpp b/src/key_queue.hpp
new file mode 100644
index 00000000..ae05f74e
--- /dev/null
+++ b/src/key_queue.hpp
@@ -0,0 +1,76 @@
+#pragma once
+
+#include "key_queue_fwd.hpp"
+
+#include <boost/circular_buffer.hpp>
+
+
+/*
+ * Low-level key queue handling.
+ */
+class key_queue {
+
+private:
+ boost::circular_buffer<char> m_buffer;
+
+public:
+ /*
+ * Overflow signal
+ */
+ enum class push_result_t {
+ OK,
+ OVERFLOW,
+ };
+
+public:
+ explicit key_queue(std::size_t k)
+ : m_buffer(k)
+ {
+ }
+
+ void clear()
+ {
+ m_buffer.clear();
+ }
+
+ void push_back(char c)
+ {
+ if (m_buffer.full())
+ {
+ return; // Ignore
+ }
+
+ m_buffer.push_back(c);
+ }
+
+ push_result_t push_front(char k)
+ {
+ if (m_buffer.full())
+ {
+ return push_result_t::OVERFLOW;
+ }
+
+ m_buffer.push_front(k);
+ return push_result_t::OK;
+ }
+
+ char front() const
+ {
+ assert(!empty());
+ return m_buffer.front();
+ }
+
+ char pop_front()
+ {
+ assert(!empty());
+ auto ch = m_buffer.front();
+ m_buffer.pop_front();
+ return ch;
+ }
+
+ bool empty() const
+ {
+ return m_buffer.empty();
+ }
+
+};
diff --git a/src/key_queue_fwd.hpp b/src/key_queue_fwd.hpp
new file mode 100644
index 00000000..c21603ed
--- /dev/null
+++ b/src/key_queue_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+class key_queue;
diff --git a/src/level_data.cc b/src/level_data.cc
new file mode 100644
index 00000000..3380a3bd
--- /dev/null
+++ b/src/level_data.cc
@@ -0,0 +1 @@
+#include "level_data.hpp"
diff --git a/src/level_data.hpp b/src/level_data.hpp
new file mode 100644
index 00000000..0e1d3a5b
--- /dev/null
+++ b/src/level_data.hpp
@@ -0,0 +1,56 @@
+#pragma once
+
+#include "dungeon_flag_set.hpp"
+
+#include <boost/optional.hpp>
+#include <string>
+#include <unordered_map>
+
+/**
+ * Read-only game data for individual levels of a dungeon.
+ */
+struct level_data
+{
+ /**
+ * Target dungeon number for side dungeon, if any.
+ */
+ int branch = 0;
+
+ /**
+ * Dungeon number for parent dungeon, if any. Filled in by post_d_info().
+ */
+ int fbranch = 0;
+
+ /**
+ * Dungeon depth for parent dungeon, if any. Filled in by post_d_info().
+ */
+ int flevel = 0;
+
+ /**
+ * Dungeon flags.
+ */
+ dungeon_flag_set flags;
+
+ /**
+ * Save file extension to use for this level, if any.
+ */
+ boost::optional<std::string> save_extension;
+
+ /**
+ * Get map name for special levels.
+ */
+ boost::optional<std::string> map_name;
+
+ /**
+ * Short name for special levels, replaces
+ * the regular depth display.
+ */
+ boost::optional<std::string> name;
+
+ /**
+ * One-line description for special levels,
+ * replaces the level feeling.
+ */
+ boost::optional<std::string> description;
+
+};
diff --git a/src/levels.cc b/src/levels.cc
index 2a1bb3ab..4c0b687a 100644
--- a/src/levels.cc
+++ b/src/levels.cc
@@ -1,252 +1,62 @@
-/*
- * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
- *
- * This software may be copied and distributed for educational, research, and
- * not for profit purposes provided that this copyright and statement are
- * included in all such copies.
- */
-
#include "levels.hpp"
-#include "dungeon_info_type.hpp"
#include "game.hpp"
-#include "init1.hpp"
-#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
-
-/*
- * Return the parameter of the given command in the given file
- */
-static int start_line = 0;
-static bool_ get_command(const char *file, char comm, char *param)
+static level_data const &current_level_data()
{
- char buf[1024];
- int i = -1;
- FILE *fp;
- char *s;
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_DNGN, file);
-
- /* Open the file */
- fp = my_fopen(buf, "r");
+ static level_data *default_level_data = new level_data { };
- /* The file exists ? */
- /* no ? then command not found */
- if (!fp) return FALSE;
+ auto const &d_info = game->edit_data.d_info;
+ auto const &level_data_by_depth = d_info[dungeon_type].level_data_by_depth;
- /* Parse to the end of the file or when the command is found */
- while (0 == my_fgets(fp, buf, 1024))
+ auto const it = level_data_by_depth.find(dun_level);
+ if (it != level_data_by_depth.end())
{
- /* Advance the line number */
- i++;
-
- /* Skip comments and blank lines */
- if (!buf[0] || (buf[0] == '#')) continue;
-
- /* Is it the command we are looking for ? */
- if ((i > start_line) && (buf[0] == comm))
- {
- /* Acquire the text */
- s = buf + 2;
-
- start_line = i;
-
- /* Get the parameter */
- strcpy(param, s);
-
- /* Close it */
- my_fclose(fp);
-
- return TRUE;
- }
-
+ return it->second;
+ }
+ else
+ {
+ return *default_level_data;
}
-
- /* Close it */
- my_fclose(fp);
-
- /* Assume command not found */
- return FALSE;
}
-
-/*
- * Return the dungeon branch starting form the current dungeon/level
- */
int get_branch()
{
- auto const &d_info = game->edit_data.d_info;
-
- char file[20], buf[5];
-
- sprintf(file, "dun%d.%d", dungeon_type, dun_level - d_info[dungeon_type].mindepth);
-
- /* Get and return the branch */
- start_line = -1;
- if (get_command(file, 'B', buf)) return (atoi(buf));
-
- /* No branch ? return 0 */
- else return 0;
+ return current_level_data().branch;
}
-/*
- * Return the father dungeon branch
- */
int get_fbranch()
{
- auto const &d_info = game->edit_data.d_info;
-
- char file[20], buf[5];
-
- sprintf(file, "dun%d.%d", dungeon_type, dun_level - d_info[dungeon_type].mindepth);
-
- /* Get and return the branch */
- start_line = -1;
- if (get_command(file, 'A', buf)) return (atoi(buf));
-
- /* No branch ? return 0 */
- else return 0;
+ return current_level_data().fbranch;
}
-/*
- * Return the father dungeon level
- */
int get_flevel()
{
- auto const &d_info = game->edit_data.d_info;
-
- char file[20], buf[5];
-
- sprintf(file, "dun%d.%d", dungeon_type, dun_level - d_info[dungeon_type].mindepth);
-
- /* Get and return the level */
- start_line = -1;
- if (get_command(file, 'L', buf)) return (atoi(buf));
-
- /* No level ? return 0 */
- else return 0;
+ return current_level_data().flevel;
}
-/*
- * Return the extension of the savefile for the level
- */
-bool_ get_dungeon_save(char *buf)
+boost::optional<std::string> get_dungeon_save_extension()
{
- auto const &d_info = game->edit_data.d_info;
-
- char file[20];
-
- sprintf(file, "dun%d.%d", dungeon_type, dun_level - d_info[dungeon_type].mindepth);
-
- /* Get and return the level */
- start_line = -1;
- if (get_command(file, 'S', buf)) return (TRUE);
- else return FALSE;
+ return current_level_data().save_extension;
}
-/*
- * Return the level generator
- */
-bool_ get_dungeon_generator(char *buf)
+boost::optional<std::string> get_dungeon_map_name()
{
- auto const &d_info = game->edit_data.d_info;
-
- char file[20];
- sprintf(file, "dun%d.%d", dungeon_type, dun_level - d_info[dungeon_type].mindepth);
-
- /* Get and return the level */
- start_line = -1;
- if (get_command(file, 'G', buf)) return (TRUE);
- else return FALSE;
+ return current_level_data().map_name;
}
-/*
- * Return the special level
- */
-bool_ get_dungeon_special(char *buf)
+boost::optional<std::string> get_dungeon_name()
{
- auto const &d_info = game->edit_data.d_info;
-
- char file[20];
- sprintf(file, "dun%d.%d", dungeon_type, dun_level - d_info[dungeon_type].mindepth);
-
- /* Get and return the level */
- start_line = -1;
- if (get_command(file, 'U', buf)) return (TRUE);
- else return FALSE;
-}
-
-/*
- * Return the special level name
- */
-bool_ get_dungeon_name(char *buf)
-{
- auto const &d_info = game->edit_data.d_info;
-
- char file[20];
- sprintf(file, "dun%d.%d", dungeon_type, dun_level - d_info[dungeon_type].mindepth);
-
- /* Get and return the level */
- start_line = -1;
- if (get_command(file, 'N', buf)) return (TRUE);
- else return FALSE;
+ return current_level_data().name;
}
-/*
- * Return the special level name
- */
-void get_level_flags()
+dungeon_flag_set get_level_flags()
{
- auto const &d_info = game->edit_data.d_info;
-
- char file[20];
- char buf[1024], *s, *t;
-
- sprintf(file, "dun%d.%d", dungeon_type, dun_level - d_info[dungeon_type].mindepth);
-
- start_line = -1;
-
- /* Parse until done */
- while (get_command(file, 'F', buf))
- {
- /* Parse every entry textually */
- for (s = buf; *s; )
- {
- /* Find the end of this entry */
- for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
-
- /* Nuke and skip any dividers */
- if (*t)
- {
- *t++ = '\0';
- while (*t == ' ' || *t == '|') t++;
- }
-
- /* Parse this entry */
- if (0 != grab_one_dungeon_flag(&dungeon_flags, s)) return;
-
- /* Start the next entry */
- s = t;
- }
- }
+ return current_level_data().flags;
}
-/*
- * Return the special level desc
- */
-bool_ get_level_desc(char *buf)
+boost::optional<std::string> get_level_description()
{
- auto const &d_info = game->edit_data.d_info;
-
- char file[20];
- sprintf(file, "dun%d.%d", dungeon_type, dun_level - d_info[dungeon_type].mindepth);
-
- /* Get and return the level */
- start_line = -1;
- if (get_command(file, 'D', buf)) return (TRUE);
- else return FALSE;
+ return current_level_data().description;
}
diff --git a/src/levels.hpp b/src/levels.hpp
index a48f1d95..46ec273e 100644
--- a/src/levels.hpp
+++ b/src/levels.hpp
@@ -1,13 +1,50 @@
#pragma once
-#include "h-basic.h"
+#include "dungeon_flag_set.hpp"
-bool_ get_dungeon_generator(char *buf);
-bool_ get_level_desc(char *buf);
-void get_level_flags();
-bool_ get_dungeon_name(char *buf);
-bool_ get_dungeon_special(char *buf);
+#include <boost/optional.hpp>
+#include <string>
+
+/**
+ * Get the level description, for special levels.
+ */
+boost::optional<std::string> get_level_description();
+
+/**
+ * Get the level name, for special levels.
+ */
+boost::optional<std::string> get_dungeon_name();
+
+/**
+ * Get the map name, for special levels.
+ */
+boost::optional<std::string> get_dungeon_map_name();
+
+/**
+ * Get the dungeon save file extension, for special levels.
+ */
+boost::optional<std::string> get_dungeon_save_extension();
+
+/**
+ * Get dungeon flags, for special levels. Returns an empty
+ * set of flags for non-special levels.
+ */
+dungeon_flag_set get_level_flags();
+
+/**
+ * Get target dungeon to which this level branches, if any.
+ * Returns 0 when the dungeon level does not branch.
+ */
int get_branch();
+
+/**
+ * Get parent dungeon of this dungeon, if any.
+ * Returns 0 when the dungeon was not entered via a branch.
+ */
int get_fbranch();
+
+/**
+ * Get the target depth of the parent dungeon, if any.
+ * Returns 0 when the dungeon has no parent dungeon.
+ */
int get_flevel();
-bool_ get_dungeon_save(char *buf);
diff --git a/src/loadsave.cc b/src/loadsave.cc
index 3c843a36..f120b7a2 100644
--- a/src/loadsave.cc
+++ b/src/loadsave.cc
@@ -1,12 +1,13 @@
#include "loadsave.hpp"
-#include "loadsave.h"
#include "artifact_type.hpp"
#include "birth.hpp"
#include "cave_type.hpp"
#include "dungeon_info_type.hpp"
#include "ego_item_type.hpp"
+#include "files.hpp"
#include "game.hpp"
+#include "hooks.hpp"
#include "init1.hpp"
#include "init2.hpp"
#include "levels.hpp"
@@ -24,25 +25,25 @@
#include "player_race.hpp"
#include "player_race_mod.hpp"
#include "player_type.hpp"
-#include "hooks.hpp"
#include "skill_type.hpp"
#include "store_type.hpp"
#include "tables.hpp"
#include "timer_type.hpp"
#include "town_type.hpp"
#include "util.hpp"
-#include "util.h"
#include "wilderness_map.hpp"
-#include "variable.h"
#include "variable.hpp"
#include "xtra2.hpp"
#include "z-rand.hpp"
#include <boost/filesystem.hpp>
#include <cassert>
+#include <fcntl.h>
#include <fmt/format.h>
#include <memory>
+namespace fs = boost::filesystem;
+
static u32b vernum; /* Version flag */
static FILE *fff; /* Local savefile ptr */
@@ -51,7 +52,7 @@ static FILE *fff; /* Local savefile ptr */
*
* Avoid the top two lines, to avoid interference with "msg_print()".
*/
-static void note(cptr msg)
+static void note(const char *msg)
{
static int y = 2;
@@ -80,7 +81,7 @@ namespace {
struct option_value {
std::string name;
- bool_ value;
+ bool value;
};
} // namespace (anonymous)
@@ -133,16 +134,6 @@ static void do_char(char *c, ls_flag_t flag)
do_byte((byte *) c, flag);
}
-static void do_bool(bool_ *f, ls_flag_t flag)
-{
- byte b = *f;
- do_byte(&b, flag);
- if (flag == ls_flag_t::LOAD)
- {
- *f = b;
- }
-}
-
static void do_std_bool(bool *x, ls_flag_t flag)
{
switch (flag)
@@ -216,6 +207,23 @@ static void do_s32b(s32b *ip, ls_flag_t flag)
do_u32b((u32b *)ip, flag);
}
+static void do_int(int *sz, ls_flag_t flag)
+{
+ u32b x;
+
+ if (flag == ls_flag_t::SAVE)
+ {
+ x = *sz;
+ }
+
+ do_u32b(&x, flag);
+
+ if (flag == ls_flag_t::LOAD)
+ {
+ *sz = x;
+ }
+}
+
static void save_std_string(std::string const *s)
{
// Length prefix.
@@ -264,7 +272,7 @@ static void do_std_string(std::string &s, ls_flag_t flag)
static void do_option_value(option_value *option_value, ls_flag_t flag)
{
do_std_string(option_value->name, flag);
- do_bool(&option_value->value, flag);
+ do_std_bool(&option_value->value, flag);
}
@@ -322,6 +330,96 @@ template<typename A, typename F> void do_array(std::string const &what, ls_flag_
}
}
+template<typename M, typename FK, typename FV> void do_fixed_map(ls_flag_t flag, M &map, FK fk, FV fv)
+{
+ // Since our file format is currently quite inflexible, we'll
+ // have to prefix with the size of the map and store everything
+ // as key-value pairs.
+ u32b n = map.size();
+ do_u32b(&n, flag);
+
+ if (flag == ls_flag_t::LOAD)
+ {
+ // Read each of the n entries. We ignore data for keys
+ // which no longer exist. This is pretty common if e.g.
+ // game data gets removed.
+ for (std::size_t i = 0; i < n; i++)
+ {
+ // Read key
+ typename M::key_type key;
+ fk(&key, flag);
+ // If the key is present, we'll update the value
+ // by reading. Otherwise just read into a dummy
+ // value.
+ if (map.count(key))
+ {
+ fv(map.at(key), flag);
+ }
+ else
+ {
+ typename M::mapped_type v;
+ fv(v, flag);
+ }
+ }
+ }
+
+ if (flag == ls_flag_t::SAVE)
+ {
+ // Write each of the n entries.
+ for (auto &entry: map)
+ {
+ auto key = entry.first;
+ auto value = entry.second;
+ fk(&key, flag);
+ fv(value, flag);
+ }
+ }
+}
+
+template<typename S, typename F> void do_unordered_set(ls_flag_t flag, S &set, F f)
+{
+ // Since our file format is currently quite inflexible, we'll
+ // have to prefix with the size of the set.
+ u32b n = set.size();
+ do_u32b(&n, flag);
+
+ if (flag == ls_flag_t::LOAD)
+ {
+ // Read each of the n entries.
+ for (std::size_t i = 0; i < n; i++)
+ {
+ // Read entry
+ typename S::key_type key;
+ f(&key, flag);
+
+ // Insert into set
+ set.insert(key);
+ }
+ }
+
+ if (flag == ls_flag_t::SAVE)
+ {
+ // We must copy out the entries because the 'f' function
+ // takes a non-const argument (for loading) and the fact
+ // that iterating through the set only allows us 'const'
+ // access to the keys. (We could cast away the const, but
+ // that might lead to accidental UB; here the worst case
+ // is that 'f' modifies the keys and has no effect on the
+ // original set.)
+ std::vector<typename S::key_type> keys;
+ std::copy(
+ std::cbegin(set),
+ std::cend(set),
+ std::back_inserter(keys));
+
+ // Write each of the n entries.
+ for (auto &key: keys)
+ {
+ f(&key, flag);
+ }
+ }
+}
+
static void do_bytes(ls_flag_t flag, std::uint8_t *buf, std::size_t n)
{
for (std::size_t i = 0; i < n; i++)
@@ -347,6 +445,40 @@ static void do_seed(seed_t *seed, ls_flag_t flag)
}
}
+template <typename T, typename F>
+static void do_boost_optional(boost::optional<T> &maybe_v, ls_flag_t flag, F f)
+{
+ if (flag == ls_flag_t::SAVE)
+ {
+ // Size
+ u32b n = maybe_v
+ ? 1
+ : 0;
+ do_u32b(&n, flag);
+
+ // Value
+ if (maybe_v)
+ {
+ auto v = *maybe_v;
+ f(&v, flag);
+ }
+ }
+
+ if (flag == ls_flag_t::LOAD)
+ {
+ // Size
+ u32b n;
+ do_u32b(&n, flag);
+
+ // Value
+ while (n-- > 0)
+ {
+ maybe_v.emplace(); // Default-construct in place
+ f(&maybe_v.get(), flag);
+ }
+ }
+}
+
} // namespace (anonymous)
@@ -370,7 +502,7 @@ static void do_quick_start(ls_flag_t flag, birther &previous_char)
}
do_s16b(&previous_char.luck, flag);
- do_bool(&previous_char.quick_ok, flag);
+ do_std_bool(&previous_char.quick_ok, flag);
}
static void do_skill_modifier(skill_modifier *s, ls_flag_t flag)
@@ -405,7 +537,7 @@ static void do_subrace(ls_flag_t flag)
do_std_string(sr_ptr->title, flag);
do_std_string(sr_ptr->description, flag);
- do_bool(&sr_ptr->place, flag);
+ do_std_bool(&sr_ptr->place, flag);
for (i = 0; i < 6; i++)
{
@@ -479,7 +611,7 @@ static void do_level_marker(level_marker *marker, ls_flag_t flag)
/*
* Misc. other data
*/
-static bool_ do_extra(ls_flag_t flag)
+static bool do_extra(ls_flag_t flag)
{
auto const &d_info = game->edit_data.d_info;
auto &s_info = game->s_info;
@@ -499,7 +631,7 @@ static bool_ do_extra(ls_flag_t flag)
{
if (tmp8u > d_info.size())
{
- note(format("Too many dungeon types!", static_cast<int>(tmp8u)));
+ note(fmt::format("Too many dungeon types: {:d}", tmp8u).c_str());
}
}
@@ -509,7 +641,7 @@ static bool_ do_extra(ls_flag_t flag)
{
if (tmp16u > MAX_DUNGEON_DEPTH)
{
- note(format("Too many (%d) max level by dungeon type!", static_cast<int>(tmp16u)));
+ note(fmt::format("Too many max level by dungeon type: {:d}", tmp16u).c_str());
}
}
@@ -625,7 +757,7 @@ static bool_ do_extra(ls_flag_t flag)
/* Gods */
do_s32b(&p_ptr->grace, flag);
do_s32b(&p_ptr->grace_delay, flag);
- do_bool(&p_ptr->praying, flag);
+ do_std_bool(&p_ptr->praying, flag);
do_s16b(&p_ptr->melkor_sacrifice, flag);
do_byte(&p_ptr->pgod, flag);
@@ -745,16 +877,16 @@ static bool_ do_extra(ls_flag_t flag)
do_array("corruptions", flag, p_ptr->corruptions, CORRUPTIONS_MAX,
[](auto corruption, auto flag) -> void {
- do_bool(corruption, flag);
+ do_std_bool(corruption, flag);
}
);
- do_bool(&p_ptr->corrupt_anti_teleport_stopped, flag);
+ do_std_bool(&p_ptr->corrupt_anti_teleport_stopped, flag);
do_byte(&p_ptr->confusing, flag);
- do_bool(&p_ptr->black_breath, flag);
- do_bool(&fate_flag, flag);
- do_bool(&ambush_flag, flag);
+ do_std_bool(&p_ptr->black_breath, flag);
+ do_std_bool(&fate_flag, flag);
+ do_std_bool(&ambush_flag, flag);
do_byte(&p_ptr->allow_one_death, flag);
do_s16b(&no_breeds, flag);
@@ -767,18 +899,52 @@ static bool_ do_extra(ls_flag_t flag)
do_u32b(&p_ptr->necro_extra2, flag);
do_u16b(&p_ptr->body_monster, flag);
- do_bool(&p_ptr->disembodied, flag);
+ do_std_bool(&p_ptr->disembodied, flag);
/* Are we in astral mode? */
- do_bool(&p_ptr->astral, flag);
+ do_std_bool(&p_ptr->astral, flag);
// Powers
- do_array("powers", flag, p_ptr->powers_mod, POWER_MAX,
- [](auto pwr, auto flag) -> void {
- do_bool(pwr, flag);
+ do_unordered_set(
+ flag,
+ p_ptr->powers_mod,
+ [](auto *pwr_idx, auto flag) -> void {
+ // Key
+ s32b tmp;
+
+ if (flag == ls_flag_t::SAVE)
+ {
+ tmp = *pwr_idx;
+ }
+
+ do_s32b(&tmp, flag);
+
+ if (flag == ls_flag_t::LOAD)
+ {
+ *pwr_idx = tmp;
+ }
}
);
+ // Fix up any removed powers.
+ if (flag == ls_flag_t::LOAD)
+ {
+ for (auto it = std::begin(p_ptr->powers_mod);
+ it != std::end(p_ptr->powers_mod); )
+ {
+ if (game->powers.count(*it))
+ {
+ // Exists, skip.
+ ++it;
+ }
+ else
+ {
+ // Does not exist, delete.
+ it = p_ptr->powers_mod.erase(it);
+ }
+ }
+ }
+
/* The tactic */
do_char(&p_ptr->tactic, flag);
@@ -789,7 +955,7 @@ static bool_ do_extra(ls_flag_t flag)
do_s16b(&p_ptr->companion_killed, flag);
/* The fate */
- do_bool(&p_ptr->no_mortal, flag);
+ do_std_bool(&p_ptr->no_mortal, flag);
/* Random spells */
do_vector(flag, p_ptr->random_spells, do_random_spell);
@@ -803,7 +969,7 @@ static bool_ do_extra(ls_flag_t flag)
do_u16b(&noscore, flag);
/* Write death */
- do_bool(&death, flag);
+ do_std_bool(&death, flag);
/* Level feeling */
do_s16b(&feeling, flag);
@@ -814,7 +980,7 @@ static bool_ do_extra(ls_flag_t flag)
/* Current turn */
do_s32b(&turn, flag);
- return TRUE;
+ return true;
}
@@ -876,7 +1042,7 @@ static void do_monster(monster_type *m_ptr, ls_flag_t flag)
/*
* Determine if an item can be wielded/worn (e.g. helmet, sword, bow, arrow)
*/
-static bool_ wearable_p(object_type *o_ptr)
+static bool wearable_p(object_type *o_ptr)
{
/* Valid "tval" codes */
switch (o_ptr->tval)
@@ -916,12 +1082,12 @@ static bool_ wearable_p(object_type *o_ptr)
case TV_DAEMON_BOOK:
case TV_TOOL:
{
- return (TRUE);
+ return true;
}
}
/* Nope */
- return (FALSE);
+ return false;
}
@@ -930,15 +1096,24 @@ static bool_ wearable_p(object_type *o_ptr)
*/
static void do_item(object_type *o_ptr, ls_flag_t flag)
{
- auto &k_info = game->edit_data.k_info;
auto &a_info = game->edit_data.a_info;
auto &e_info = game->edit_data.e_info;
+ auto &k_info = game->edit_data.k_info;
byte old_dd;
byte old_ds;
/* Kind */
- do_s16b(&o_ptr->k_idx, flag);
+ if (flag == ls_flag_t::SAVE)
+ {
+ do_s16b(&o_ptr->k_ptr->idx, flag);
+ }
+ if (flag == ls_flag_t::LOAD)
+ {
+ s16b k_idx;
+ do_s16b(&k_idx, flag);
+ o_ptr->k_ptr = k_info.at(k_idx);
+ }
/* Location */
do_byte(&o_ptr->iy, flag);
@@ -984,7 +1159,7 @@ static void do_item(object_type *o_ptr, ls_flag_t flag)
do_byte(&o_ptr->ds, ls_flag_t::SAVE);
}
- do_byte(&o_ptr->ident, flag);
+ do_std_bool(&o_ptr->identified, flag);
do_byte(&o_ptr->marked, flag);
@@ -1004,9 +1179,6 @@ static void do_item(object_type *o_ptr, ls_flag_t flag)
do_byte(&o_ptr->elevel, flag);
do_s32b(&o_ptr->exp, flag);
- /* Read the pseudo-id */
- do_byte(&o_ptr->sense, flag);
-
/* Read the found info */
do_byte(&o_ptr->found, flag);
do_s16b(&o_ptr->found_aux1, flag);
@@ -1029,7 +1201,7 @@ static void do_item(object_type *o_ptr, ls_flag_t flag)
/*********** END OF ls_flag_t::SAVE ***************/
/* Obtain the "kind" template */
- object_kind *k_ptr = &k_info[o_ptr->k_idx];
+ auto k_ptr = o_ptr->k_ptr;
/* Obtain tval/sval from k_info */
o_ptr->tval = k_ptr->tval;
@@ -1073,7 +1245,10 @@ static void do_item(object_type *o_ptr, ls_flag_t flag)
e_ptr = &e_info[o_ptr->name2];
/* Verify that ego-item */
- if (!e_ptr->name) o_ptr->name2 = 0;
+ if (e_ptr->name.empty())
+ {
+ o_ptr->name2 = 0;
+ }
}
@@ -1122,7 +1297,7 @@ static void do_cave_type(cave_type *c_ptr, ls_flag_t flag)
do_s16b(&c_ptr->special2, flag);
do_s16b(&c_ptr->inscription, flag);
do_byte(&c_ptr->mana, flag);
- do_s16b(&c_ptr->effect, flag);
+ do_boost_optional(c_ptr->maybe_effect, flag, do_s16b);
}
static void do_grid(ls_flag_t flag)
@@ -1203,7 +1378,7 @@ static bool do_objects(ls_flag_t flag, bool no_companions)
/* Oops */
if (i != o_idx)
{
- note(format("Object allocation error (%d <> %d)", i, o_idx));
+ note(fmt::format("Object allocation error ({} <> {})", i, o_idx).c_str());
return false;
}
@@ -1303,7 +1478,7 @@ static bool do_monsters(ls_flag_t flag, bool no_companions)
/* Oops */
if (i != m_idx)
{
- note(format("Monster allocation error (%d <> %d)", i, m_idx));
+ note(fmt::format("Monster allocation error ({} <> {})", i, m_idx).c_str());
return false;
}
@@ -1350,8 +1525,11 @@ static bool do_monsters(ls_flag_t flag, bool no_companions)
* The monsters/objects must be loaded in the same order
* that they were stored, since the actual indexes matter.
*/
-static bool_ do_dungeon(ls_flag_t flag, bool no_companions)
+static bool do_dungeon(ls_flag_t flag, bool no_companions)
{
+ auto &dungeon_flags = game->dungeon_flags;
+ auto &effects = game->lasting_effects;
+
/* Header info */
do_s16b(&dun_level, flag);
do_byte(&dungeon_type, flag);
@@ -1370,7 +1548,7 @@ static bool_ do_dungeon(ls_flag_t flag, bool no_companions)
do_s16b(&last_teleportation_y, flag);
/* Spell effects */
- do_array("spell effects", flag, effects, MAX_EFFECTS,
+ do_vector(flag, effects,
[](auto effect, auto flag) -> void {
do_s16b(&effect->type, flag);
do_s16b(&effect->dam, flag);
@@ -1395,14 +1573,14 @@ static bool_ do_dungeon(ls_flag_t flag, bool no_companions)
int ystart = 0;
/* Init the wilderness */
process_dungeon_file("w_info.txt", &ystart, &xstart, cur_hgt, cur_wid,
- TRUE, FALSE);
+ true, false);
/* Init the town */
xstart = 0;
ystart = 0;
init_flags = 0;
process_dungeon_file("t_info.txt", &ystart, &xstart, cur_hgt, cur_wid,
- TRUE, FALSE);
+ true, false);
}
do_grid(flag);
@@ -1410,44 +1588,45 @@ static bool_ do_dungeon(ls_flag_t flag, bool no_companions)
/*** Objects ***/
if (!do_objects(flag, no_companions))
{
- return FALSE;
+ return false;
}
/*** Monsters ***/
if (!do_monsters(flag, no_companions))
{
- return FALSE;
+ return false;
}
/*** Success ***/
/* The dungeon is ready */
- if (flag == ls_flag_t::LOAD) character_dungeon = TRUE;
+ if (flag == ls_flag_t::LOAD)
+ {
+ character_dungeon = true;
+ }
/* Success */
- return (TRUE);
+ return true;
}
/* Save the current persistent dungeon -SC- */
void save_dungeon()
{
- char tmp[16];
- char name[1024], buf[5];
-
- /* Save only persistent dungeons */
- if (!get_dungeon_save(buf) || (!dun_level)) return;
-
- /* Construct filename */
- sprintf(tmp, "%s.%s", game->player_base.c_str(), buf);
- path_build(name, 1024, ANGBAND_DIR_SAVE, tmp);
+ if (!dun_level)
+ {
+ return;
+ }
- /* Open the file */
- fff = my_fopen(name, "wb");
+ if (auto ext = get_dungeon_save_extension())
+ {
+ /* Open the file */
+ fff = my_fopen(name_file_dungeon_save(*ext).c_str(), "wb");
- /* Save the dungeon */
- do_dungeon(ls_flag_t::SAVE, true);
+ /* Save the dungeon */
+ do_dungeon(ls_flag_t::SAVE, true);
- my_fclose(fff);
+ my_fclose(fff);
+ }
}
@@ -1510,11 +1689,6 @@ static void do_randomizer(ls_flag_t flag)
if (flag == ls_flag_t::LOAD)
{
set_complex_rng_state(state);
- }
-
- /* Accept */
- if (flag == ls_flag_t::LOAD)
- {
set_complex_rng();
}
}
@@ -1547,16 +1721,16 @@ static void do_options(ls_flag_t flag)
do_byte(&options->hitpoint_warn, flag);
/*** Cheating options ***/
- do_bool(&wizard, flag);
- do_bool(&options->cheat_peek, flag);
- do_bool(&options->cheat_hear, flag);
- do_bool(&options->cheat_room, flag);
- do_bool(&options->cheat_xtra, flag);
- do_bool(&options->cheat_live, flag);
+ do_std_bool(&wizard, flag);
+ do_std_bool(&options->cheat_peek, flag);
+ do_std_bool(&options->cheat_hear, flag);
+ do_std_bool(&options->cheat_room, flag);
+ do_std_bool(&options->cheat_xtra, flag);
+ do_std_bool(&options->cheat_live, flag);
/*** Autosave options */
- do_bool(&options->autosave_l, flag);
- do_bool(&options->autosave_t, flag);
+ do_std_bool(&options->autosave_l, flag);
+ do_std_bool(&options->autosave_t, flag);
do_s16b(&options->autosave_freq, flag);
// Standard options
@@ -1679,7 +1853,7 @@ static void do_options(ls_flag_t flag)
* Handle player inventory. Note that the inventory is
* "re-sorted" later by "dungeon()".
*/
-static bool_ do_inventory(ls_flag_t flag)
+static bool do_inventory(ls_flag_t flag)
{
auto const &a_info = game->edit_data.a_info;
@@ -1695,7 +1869,7 @@ static bool_ do_inventory(ls_flag_t flag)
equip_cnt = 0;
/* Read until done */
- while (1)
+ while (true)
{
u16b n;
@@ -1715,7 +1889,7 @@ static bool_ do_inventory(ls_flag_t flag)
do_item(q_ptr, ls_flag_t::LOAD);
/* Hack -- verify item */
- if (!q_ptr->k_idx) return (FALSE);
+ if (!q_ptr->k_ptr) return false;
/* Wield equipment */
if (n >= INVEN_WIELD)
@@ -1726,7 +1900,7 @@ static bool_ do_inventory(ls_flag_t flag)
/* Take care of item sets */
if (q_ptr->name1)
{
- wield_set(q_ptr->name1, a_info[q_ptr->name1].set, TRUE);
+ wield_set(q_ptr->name1, a_info[q_ptr->name1].set, true);
}
/* One more item */
@@ -1740,7 +1914,7 @@ static bool_ do_inventory(ls_flag_t flag)
note("Too many items in the inventory!");
/* Fail */
- return (FALSE);
+ return false;
}
/* Carry inventory */
@@ -1762,7 +1936,7 @@ static bool_ do_inventory(ls_flag_t flag)
for (u16b i = 0; i < INVEN_TOTAL; i++)
{
object_type *o_ptr = &p_ptr->inventory[i];
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr) continue;
do_u16b(&i, flag);
do_item(o_ptr, flag);
}
@@ -1771,7 +1945,7 @@ static bool_ do_inventory(ls_flag_t flag)
do_u16b(&sent, ls_flag_t::SAVE);
}
/* Success */
- return (TRUE);
+ return true;
}
@@ -1813,28 +1987,22 @@ static void do_messages(ls_flag_t flag)
}
}
-/* Returns TRUE if we successfully load the dungeon */
-bool_ load_dungeon(char *ext)
+/* Returns true if we successfully load the dungeon */
+bool load_dungeon(std::string const &ext)
{
- char tmp[16];
- char name[1024];
byte old_dungeon_type = dungeon_type;
s16b old_dun = dun_level;
- /* Construct name */
- sprintf(tmp, "%s.%s", game->player_base.c_str(), ext);
- path_build(name, 1024, ANGBAND_DIR_SAVE, tmp);
-
/* Open the file */
- fff = my_fopen(name, "rb");
+ fff = my_fopen(name_file_dungeon_save(ext).c_str(), "rb");
- if (fff == NULL)
+ if (fff == nullptr)
{
dun_level = old_dun;
dungeon_type = old_dungeon_type;
my_fclose(fff);
- return (FALSE);
+ return false;
}
/* Read the dungeon */
@@ -1844,7 +2012,7 @@ bool_ load_dungeon(char *ext)
dungeon_type = old_dungeon_type;
my_fclose(fff);
- return (FALSE);
+ return false;
}
dun_level = old_dun;
@@ -1852,7 +2020,7 @@ bool_ load_dungeon(char *ext)
/* Done */
my_fclose(fff);
- return (TRUE);
+ return true;
}
/*
@@ -1925,7 +2093,7 @@ static bool do_monster_lore(ls_flag_t flag)
[](auto r_ptr, auto flag) -> void {
do_s16b(&r_ptr->r_pkills, flag);
do_s16b(&r_ptr->max_num, flag);
- do_bool(&r_ptr->on_saved, flag);
+ do_std_bool(&r_ptr->on_saved, flag);
}
);
@@ -1940,11 +2108,10 @@ static bool do_object_lore(ls_flag_t flag)
{
auto &k_info = game->edit_data.k_info;
- do_array("object kinds", flag, k_info, k_info.size(),
- [](auto k_ptr, auto flag) -> void {
- do_bool(&k_ptr->aware, flag);
- do_bool(&k_ptr->tried, flag);
- do_bool(&k_ptr->artifact, flag);
+ do_fixed_map(flag, k_info, do_int,
+ [](std::shared_ptr<object_kind> k_ptr, auto flag) -> void {
+ do_std_bool(&k_ptr->aware, flag);
+ do_std_bool(&k_ptr->artifact, flag);
}
);
@@ -1983,7 +2150,7 @@ static bool do_towns(ls_flag_t flag)
{
auto town = &town_info[i];
- do_bool(&town->destroyed, flag);
+ do_std_bool(&town->destroyed, flag);
if (i >= TOWN_RANDOM)
{
@@ -2045,7 +2212,7 @@ static bool do_quests(ls_flag_t flag)
do_s32b(&quest_data, flag);
}
// Initialize if necessary
- if ((flag == ls_flag_t::LOAD) && (q->init != NULL))
+ if ((flag == ls_flag_t::LOAD) && (q->init != nullptr))
{
q->init();
}
@@ -2062,8 +2229,8 @@ static bool do_wilderness(ls_flag_t flag)
// Player position and "mode" wrt. wilderness
do_s32b(&p_ptr->wilderness_x, flag);
do_s32b(&p_ptr->wilderness_y, flag);
- do_bool(&p_ptr->wild_mode, flag);
- do_bool(&p_ptr->old_wild_mode, flag);
+ do_std_bool(&p_ptr->wild_mode, flag);
+ do_std_bool(&p_ptr->old_wild_mode, flag);
// Size of the wilderness
u16b wild_x_size = wilderness.width();
@@ -2088,7 +2255,7 @@ static bool do_wilderness(ls_flag_t flag)
auto w = &wilderness(x, y);
do_seed(&w->seed, flag);
do_u16b(&w->entrance, flag);
- do_bool(&w->known, flag);
+ do_std_bool(&w->known, flag);
}
}
@@ -2139,7 +2306,7 @@ static bool do_fates(ls_flag_t flag)
do_s16b(&fate->r_idx, flag);
do_s16b(&fate->count, flag);
do_s16b(&fate->time, flag);
- do_bool(&fate->know, flag);
+ do_std_bool(&fate->know, flag);
}
);
@@ -2174,7 +2341,7 @@ static bool do_player_hd(ls_flag_t flag)
/*
* Actually read the savefile
*/
-static bool_ do_savefile_aux(ls_flag_t flag)
+static bool do_savefile_aux(ls_flag_t flag)
{
auto &class_info = game->edit_data.class_info;
auto const &race_info = game->edit_data.race_info;
@@ -2186,7 +2353,7 @@ static bool_ do_savefile_aux(ls_flag_t flag)
if (vernum != SAVEFILE_VERSION)
{
note("Incompatible save file version");
- return FALSE;
+ return false;
}
}
@@ -2222,7 +2389,7 @@ static bool_ do_savefile_aux(ls_flag_t flag)
note(fmt::format("Bad game module. Savefile was saved with module '{:s}' but game is '{:s}'.",
loaded_game_module,
game_module).c_str());
- return FALSE;
+ return false;
}
}
}
@@ -2234,7 +2401,7 @@ static bool_ do_savefile_aux(ls_flag_t flag)
do_randomizer(flag);
/* Automatizer state */
- do_bool(&automatizer_enabled, flag);
+ do_std_bool(&automatizer_enabled, flag);
/* Then the options */
do_options(flag);
@@ -2244,57 +2411,57 @@ static bool_ do_savefile_aux(ls_flag_t flag)
if (!do_monster_lore(flag))
{
- return FALSE;
+ return false;
}
if (!do_object_lore(flag))
{
- return FALSE;
+ return false;
}
if (!do_towns(flag))
{
- return FALSE;
+ return false;
}
if (!do_quests(flag))
{
- return FALSE;
+ return false;
}
if (!do_wilderness(flag))
{
- return FALSE;
+ return false;
}
if (!do_randarts(flag))
{
- return FALSE;
+ return false;
}
if (!do_artifacts(flag))
{
- return FALSE;
+ return false;
}
if (!do_fates(flag))
{
- return FALSE;
+ return false;
}
if (!do_floor_inscriptions(flag))
{
- return FALSE;
+ return false;
}
if (!do_extra(flag))
{
- return FALSE;
+ return false;
}
if (!do_player_hd(flag))
{
- return FALSE;
+ return false;
}
if (flag == ls_flag_t::LOAD)
@@ -2321,7 +2488,7 @@ static bool_ do_savefile_aux(ls_flag_t flag)
if (flag == ls_flag_t::LOAD)
{
note("Unable to read inventory");
- return FALSE;
+ return false;
}
}
@@ -2340,7 +2507,7 @@ static bool_ do_savefile_aux(ls_flag_t flag)
if ((flag == ls_flag_t::LOAD) && (!do_dungeon(ls_flag_t::LOAD, false)))
{
note("Error reading dungeon data");
- return FALSE;
+ return false;
}
if (flag == ls_flag_t::SAVE)
@@ -2350,7 +2517,7 @@ static bool_ do_savefile_aux(ls_flag_t flag)
}
/* Success */
- return TRUE;
+ return true;
}
@@ -2363,7 +2530,7 @@ static errr rd_savefile()
errr err = 0;
/* The savefile is a binary file */
- fff = my_fopen(savefile, "rb");
+ fff = my_fopen(name_file_save().c_str(), "rb");
/* Paranoia */
if (!fff) return ( -1);
@@ -2390,47 +2557,52 @@ static errr rd_savefile()
* the player loads a savefile belonging to someone else, and then is not
* allowed to save his game when he quits.
*
- * We return "TRUE" if the savefile was usable, and we set the global
+ * We return "true" if the savefile was usable, and we set the global
* flag "character_loaded" if a real, living, character was loaded.
*
* Note that we always try to load the "current" savefile, even if
* there is no such file, so we must check for "empty" savefile names.
*/
-bool_ load_player()
+bool load_player(program_args const &args)
{
errr err = 0;
- cptr what = "generic";
+ const char *what = "generic";
/* Paranoia */
turn = 0;
/* Paranoia */
- death = FALSE;
+ death = false;
+ /* Save file */
+ auto savefile = name_file_save();
/* Allow empty savefile name */
- if (!savefile[0]) return (TRUE);
+ if (savefile.empty())
+ {
+ return true;
+ }
/* XXX XXX XXX Fix this */
/* Verify the existance of the savefile */
- if (!boost::filesystem::exists(savefile))
+ if (!fs::exists(savefile))
{
/* Give a message */
- msg_format("Savefile does not exist: %s", savefile);
- msg_print(NULL);
+ msg_format("Savefile does not exist: %s", savefile.c_str());
+ msg_print(nullptr);
/* Allow this */
- return (TRUE);
+ return true;
}
/* Okay */
if (!err)
{
/* Open the savefile */
- int fd = fd_open(savefile, O_RDONLY);
+ int fd = fd_open(savefile.c_str(), O_RDONLY);
/* No file */
if (fd < 0) err = -1;
@@ -2446,7 +2618,7 @@ bool_ load_player()
if (!err)
{
/* Open the file XXX XXX XXX XXX Should use Angband file interface */
- fff = my_fopen(savefile, "rb");
+ fff = my_fopen(savefile.c_str(), "rb");
/* Read the first four bytes */
do_u32b(&vernum, ls_flag_t::LOAD);
@@ -2486,27 +2658,27 @@ bool_ load_player()
if (death)
{
/* Player is no longer "dead" */
- death = FALSE;
+ death = false;
/* Cheat death (unless the character retired) */
- if (arg_wizard && !total_winner)
+ if (args.wizard && !total_winner)
{
/* A character was loaded */
- character_loaded = TRUE;
+ character_loaded = true;
/* Done */
- return (TRUE);
+ return true;
}
/* Forget turns */
turn = old_turn = 0;
/* Done */
- return (TRUE);
+ return true;
}
/* A character was loaded */
- character_loaded = TRUE;
+ character_loaded = true;
/* Still alive */
if (p_ptr->chp >= 0)
@@ -2516,17 +2688,17 @@ bool_ load_player()
}
/* Success */
- return (TRUE);
+ return true;
}
/* Message */
- msg_format("Error (%s) reading savefile (version " FMTu32b ").",
- what, vernum);
- msg_print(NULL);
+ msg_print(fmt::format("Error ({}) reading savefile (version {}).",
+ what, vernum));
+ msg_print(nullptr);
/* Oops */
- return (FALSE);
+ return false;
}
@@ -2534,14 +2706,14 @@ bool_ load_player()
/*
* Medium level player saver
*/
-static bool_ save_player_aux(char *name)
+static bool save_player_aux(char const *name)
{
- bool_ ok = FALSE;
+ bool ok = false;
int fd = -1;
int mode = 0644;
/* No file yet */
- fff = NULL;
+ fff = nullptr;
/* Create the savefile */
fd = fd_make(name, mode);
@@ -2559,10 +2731,10 @@ static bool_ save_player_aux(char *name)
if (fff)
{
/* Write the savefile */
- if (do_savefile_aux(ls_flag_t::SAVE)) ok = TRUE;
+ if (do_savefile_aux(ls_flag_t::SAVE)) ok = true;
/* Attempt to close it */
- if (my_fclose(fff)) ok = FALSE;
+ if (my_fclose(fff)) ok = false;
}
/* "broken" savefile */
@@ -2574,53 +2746,50 @@ static bool_ save_player_aux(char *name)
}
/* Failure */
- if (!ok) return (FALSE);
+ if (!ok) return false;
/* Success */
- return (TRUE);
+ return true;
}
/*
* Attempt to save the player in a savefile
*/
-bool_ save_player()
+bool save_player()
{
- int result = FALSE;
- char safe[1024];
+ int result = false;
+
+ auto savefile = name_file_save();
/* New savefile */
- strcpy(safe, savefile);
- strcat(safe, ".new");
+ auto safe = savefile + ".new";
/* Remove it */
- fd_kill(safe);
+ fd_kill(safe.c_str());
/* Attempt to save the player */
- if (save_player_aux(safe))
+ if (save_player_aux(safe.c_str()))
{
- char temp[1024];
-
/* Old savefile */
- strcpy(temp, savefile);
- strcat(temp, ".old");
+ auto temp = savefile + ".old";
/* Remove it */
- fd_kill(temp);
+ fd_kill(temp.c_str());
/* Preserve old savefile */
- fd_move(savefile, temp);
+ fd_move(savefile.c_str(), temp.c_str());
/* Activate new savefile */
- fd_move(safe, savefile);
+ fd_move(safe.c_str(), savefile.c_str());
/* Remove preserved savefile */
- fd_kill(temp);
+ fd_kill(temp.c_str());
/* Hack -- Pretend the character was loaded */
- character_loaded = TRUE;
+ character_loaded = true;
/* Success */
- result = TRUE;
+ result = true;
}
save_savefile_names();
diff --git a/src/loadsave.h b/src/loadsave.h
deleted file mode 100644
index 52782dac..00000000
--- a/src/loadsave.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include "h-basic.h"
-
-// C linkage required for these functions since main-* code uses them.
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void save_dungeon();
-bool_ save_player();
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/src/loadsave.hpp b/src/loadsave.hpp
index d28d437e..ec0ae66f 100644
--- a/src/loadsave.hpp
+++ b/src/loadsave.hpp
@@ -1,6 +1,11 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
+#include "program_args.hpp"
-bool_ load_dungeon(char *ext);
-bool_ load_player();
+#include <string>
+
+bool load_dungeon(std::string const &ext);
+bool load_player(program_args const &);
+void save_dungeon();
+bool save_player();
diff --git a/src/lua_bind.cc b/src/lua_bind.cc
index 3ca43716..bc4f1eae 100644
--- a/src/lua_bind.cc
+++ b/src/lua_bind.cc
@@ -99,9 +99,9 @@ static s32b get_level_school_1(spell_type *spell, s32b max, s32b min)
{
// Delegate
s32b level;
- bool_ na;
+ bool na;
get_level_school(spell, max, min, &level, &na);
- // Note: It is tempting to add an assertion here for "na == FALSE" here,
+ // Note: It is tempting to add an assertion here for "na == false" here,
// but there are cases where we haven't actually checked if the spell is
// really castable before calling this function (indirectly). Thus we
// MUST NOT assert anything about "na" as the code currently stands.
@@ -215,19 +215,19 @@ void get_map_size(const char *name, int *ysize, int *xsize)
*xsize = 0;
*ysize = 0;
init_flags = INIT_GET_SIZE;
- process_dungeon_file(name, ysize, xsize, cur_hgt, cur_wid, TRUE, TRUE);
+ process_dungeon_file(name, ysize, xsize, cur_hgt, cur_wid, true, true);
}
void load_map(const char *name, int *y, int *x)
{
/* Set the correct monster hook */
- set_mon_num_hook();
+ reset_get_monster_hook();
/* Prepare allocation table */
get_mon_num_prep();
init_flags = INIT_CREATE_DUNGEON;
- process_dungeon_file(name, y, x, cur_hgt, cur_wid, TRUE, TRUE);
+ process_dungeon_file(name, y, x, cur_hgt, cur_wid, true, true);
}
void increase_mana(int delta)
diff --git a/src/lua_bind.hpp b/src/lua_bind.hpp
index 39fc2159..99837336 100644
--- a/src/lua_bind.hpp
+++ b/src/lua_bind.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "spell_type_fwd.hpp"
#include "timer_type_fwd.hpp"
@@ -16,7 +16,7 @@ int get_mana(s32b s);
s32b get_power(s32b s);
s32b get_level(s32b s, s32b max);
s32b get_level_s(int sp, int max);
-void get_level_school(struct spell_type *spell, s32b max, s32b min, s32b *level, bool_ *na);
+void get_level_school(struct spell_type *spell, s32b max, s32b min, s32b *level, bool *na);
extern s32b get_level_max_stick;
extern s32b get_level_use_stick;
diff --git a/src/magic_power.hpp b/src/magic_power.hpp
index b02c6c14..bf61f012 100644
--- a/src/magic_power.hpp
+++ b/src/magic_power.hpp
@@ -1,15 +1,13 @@
#pragma once
-#include "h-basic.h"
-
/**
* Powers, used by Mindcrafters and Necromancers
*/
struct magic_power
{
- int min_lev;
- int mana_cost;
- int fail;
- cptr name;
- cptr desc;
+ int min_lev;
+ int mana_cost;
+ int fail;
+ const char *name;
+ const char *desc;
};
diff --git a/src/main-gcu.c b/src/main-gcu.cc
index ac41272c..d27819db 100644
--- a/src/main-gcu.c
+++ b/src/main-gcu.cc
@@ -38,12 +38,16 @@
* Consider the use of "savetty()" and "resetty()". XXX XXX XXX
*/
-#include "main.h"
-#include "util.h"
-#include "variable.h"
+#include "main.hpp"
+#include "frontend.hpp"
+#include "variable.hpp"
+#include "z-util.hpp"
+#include <fcntl.h>
+#include <boost/algorithm/string/predicate.hpp>
+#include <climits>
-#include <limits.h>
+using boost::algorithm::starts_with;
/*
* Hack -- play games with "bool" and "term"
@@ -189,7 +193,7 @@ typedef struct term_data term_data;
struct term_data
{
- term t; /* All term info */
+ term *term_ptr; /* All term info */
WINDOW *win; /* Pointer to the curses window */
};
@@ -202,14 +206,6 @@ static term_data data[MAX_TERM_DATA];
/*
- * Hack -- Number of initialized "term" structures
- */
-static int active = 0;
-
-
-#ifdef A_COLOR
-
-/*
* Hack -- define "A_BRIGHT" to be "A_BOLD", because on many
* machines, "A_BRIGHT" produces ugly "inverse" video.
*/
@@ -220,26 +216,24 @@ static int active = 0;
/*
* Software flag -- we are allowed to use color
*/
-static int can_use_color = FALSE;
+static int can_use_color = false;
/*
* Software flag -- we are allowed to change the colors
*/
-static int can_fix_color = FALSE;
+static int can_fix_color = false;
/*
* Simple Angband to Curses color conversion table
*/
static int colortable[16];
-#endif
-
/*
* Place the "keymap" into its "normal" state
*/
-static void keymap_norm(void)
+static void keymap_norm()
{
#ifdef USE_TPOSIX
@@ -272,7 +266,7 @@ static void keymap_norm(void)
/*
* Place the "keymap" into the "game" state
*/
-static void keymap_game(void)
+static void keymap_game()
{
#ifdef USE_TPOSIX
@@ -305,7 +299,7 @@ static void keymap_game(void)
/*
* Save the normal keymap
*/
-static void keymap_norm_prepare(void)
+static void keymap_norm_prepare()
{
#ifdef USE_TPOSIX
@@ -338,7 +332,7 @@ static void keymap_norm_prepare(void)
/*
* Save the keymaps (normal and game)
*/
-static void keymap_game_prepare(void)
+static void keymap_game_prepare()
{
#ifdef USE_TPOSIX
@@ -431,303 +425,235 @@ static void keymap_game_prepare(void)
/*
- * Suspend/Resume
+ * React to changes
*/
-static errr Term_xtra_gcu_alive(int v)
+static void Term_xtra_gcu_react()
{
- int x, y;
+ int i;
- /* Suspend */
- if (!v)
+ /* Cannot handle color redefinition */
+ if (!can_fix_color)
{
- /* Go to normal keymap mode */
- keymap_norm();
-
- /* Restore modes */
- noraw();
- echo();
- nl();
-
- /* Hack -- make sure the cursor is visible */
- Term_xtra(TERM_XTRA_SHAPE, 1);
-
- /* Flush the curses buffer */
- (void)refresh();
-
- /* Get current cursor position */
- getyx(curscr, y, x);
-
- /* Move the cursor to bottom right corner */
- mvcur(y, x, LINES - 1, 0);
-
- /* Exit curses */
- endwin();
-
- /* Flush the output */
- (void)fflush(stdout);
+ return;
}
- /* Resume */
- else
+ /* Set the colors */
+ for (i = 0; i < 16; i++)
{
- /* Refresh */
- /* (void)touchwin(curscr); */
- /* (void)wrefresh(curscr); */
-
- /* Restore the settings */
- raw();
- noecho();
- nonl();
-
- /* Go to angband keymap mode */
- keymap_game();
+ /* Set one color (note scaling) */
+ init_color(i,
+ angband_color_table[i][1] * 1000 / 255,
+ angband_color_table[i][2] * 1000 / 255,
+ angband_color_table[i][3] * 1000 / 255);
}
- /* Success */
- return (0);
}
/*
- * Init the "curses" system
+ * User Interface for GCU.
*/
-static void Term_init_gcu(term *t)
-{
- term_data *td = (term_data *)(t->data);
-
- /* Count init's, handle first */
- if (active++ != 0) return;
+class CursesFrontend final : public Frontend {
- /* Erase the window */
- (void)wclear(td->win);
+ /*
+ * Hack -- Number of initialized "term" structures
+ */
+ static int m_active;
- /* Reset the cursor */
- (void)wmove(td->win, 0, 0);
+private:
+ term_data *m_term_data;
- /* Flush changes */
- (void)wrefresh(td->win);
-
- /* Game keymap */
- keymap_game();
-}
+ bool event_aux(bool wait)
+ {
+ int i, k;
+ char buf[2];
-/*
- * Nuke the "curses" system
- */
-static void Term_nuke_gcu(term *t)
-{
- int x, y;
- term_data *td = (term_data *)(t->data);
+ /* Wait */
+ if (wait)
+ {
+ /* Wait for one byte */
+ i = read(0, buf, 1);
- /* Delete this window */
- delwin(td->win);
+ /* Hack -- Handle bizarre "errors" */
+ if ((i <= 0) && (errno != EINTR)) abort();
+ }
- /* Count nuke's, handle last */
- if (--active != 0) return;
+ /* Do not wait */
+ else
+ {
+ /* Get the current flags for stdin */
+ k = fcntl(0, F_GETFL, 0);
- /* Hack -- make sure the cursor is visible */
- Term_xtra(TERM_XTRA_SHAPE, 1);
+ /* Oops */
+ if (k < 0)
+ {
+ return false;
+ }
-#ifdef A_COLOR
- /* Reset colors to defaults */
- start_color();
-#endif
+ /* Tell stdin not to block */
+ if (fcntl(0, F_SETFL, k | O_NDELAY) < 0)
+ {
+ return false;
+ }
- /* Get current cursor position */
- getyx(curscr, y, x);
+ /* Read one byte, if possible */
+ i = read(0, buf, 1);
- /* Move the cursor to bottom right corner */
- mvcur(y, x, LINES - 1, 0);
+ /* Replace the flags for stdin */
+ if (fcntl(0, F_SETFL, k))
+ {
+ return false;
+ }
+ }
- /* Flush the curses buffer */
- (void)refresh();
+ /* Ignore "invalid" keys */
+ if ((i != 1) || (!buf[0]))
+ {
+ return false;
+ }
- /* Exit curses */
- endwin();
+ /* Enqueue the keypress */
+ Term_keypress(buf[0]);
- /* Flush the output */
- (void)fflush(stdout);
+ /* Success */
+ return true;
+ }
- /* Normal keymap */
- keymap_norm();
-}
+public:
+ explicit CursesFrontend(term_data *term_data)
+ : m_term_data(term_data)
+ {
+ }
+ void init() final
+ {
+ /* Count init's, handle first */
+ if (m_active++ != 0) return;
-/*
-* Process events (with optional wait)
-*/
-static errr Term_xtra_gcu_event(int v)
-{
- int i, k;
+ /* Clear */
+ wclear(m_term_data->win);
+ wmove(m_term_data->win, 0, 0);
+ wrefresh(m_term_data->win);
- char buf[2];
+ /* Game keymap */
+ keymap_game();
+ };
- /* Wait */
- if (v)
+ bool icky_corner() const final
{
- /* Wait for one byte */
- i = read(0, buf, 1);
-
- /* Hack -- Handle bizarre "errors" */
- if ((i <= 0) && (errno != EINTR)) abort();
+ return true;
}
- /* Do not wait */
- else
+ bool soft_cursor() const final
{
- /* Get the current flags for stdin */
- k = fcntl(0, F_GETFL, 0);
-
- /* Oops */
- if (k < 0) return (1);
+ return false;
+ }
- /* Tell stdin not to block */
- if (fcntl(0, F_SETFL, k | O_NDELAY) < 0) return (1);
+ void nuke() final
+ {
+ /* Delete this window */
+ delwin(m_term_data->win);
- /* Read one byte, if possible */
- i = read(0, buf, 1);
+ /* Count nuke's, handle last */
+ if (--m_active != 0) return;
- /* Replace the flags for stdin */
- if (fcntl(0, F_SETFL, k)) return (1);
- }
+ /* Reset colors to defaults */
+ start_color();
- /* Ignore "invalid" keys */
- if ((i != 1) || (!buf[0])) return (1);
-
- /* Enqueue the keypress */
- Term_keypress(buf[0]);
+ /* Get current cursor position */
+ int x, y;
+ getyx(curscr, y, x);
- /* Success */
- return (0);
-}
+ /* Move the cursor to bottom right corner */
+ mvcur(y, x, LINES - 1, 0);
+ /* Flush the curses buffer */
+ refresh();
-/*
- * React to changes
- */
-static errr Term_xtra_gcu_react(void)
-{
+ /* Exit curses */
+ endwin();
-#ifdef A_COLOR
+ /* Flush the output */
+ fflush(stdout);
- int i;
+ /* Normal keymap */
+ keymap_norm();
+ }
- /* Cannot handle color redefinition */
- if (!can_fix_color) return (0);
+ void process_event(bool wait) final
+ {
+ event_aux(wait);
+ }
- /* Set the colors */
- for (i = 0; i < 16; i++)
+ void flush_events() final
{
- /* Set one color (note scaling) */
- init_color(i,
- angband_color_table[i][1] * 1000 / 255,
- angband_color_table[i][2] * 1000 / 255,
- angband_color_table[i][3] * 1000 / 255);
+ while (event_aux(false))
+ {
+ // Keep flushing
+ }
}
-#endif
+ void clear() final
+ {
+ touchwin(m_term_data->win);
+ wclear(m_term_data->win);
+ }
- /* Success */
- return (0);
-}
+ void flush_output() final
+ {
+ wrefresh(m_term_data->win);
+ }
+ void noise() final
+ {
+ write(1, "\007", 1);
+ }
-/*
- * Handle a "special request"
- */
-static errr Term_xtra_gcu(int n, int v)
-{
- term_data *td = (term_data *)(Term->data);
+ void process_queued_events() final
+ {
+ // No action necessary
+ }
- /* Analyze the request */
- switch (n)
+ void react() final
{
- /* Clear screen */
- case TERM_XTRA_CLEAR:
- touchwin(td->win);
- (void)wclear(td->win);
- return (0);
-
- /* Make a noise */
- case TERM_XTRA_NOISE:
- (void)write(1, "\007", 1);
- return (0);
-
- /* Flush the Curses buffer */
- case TERM_XTRA_FRESH:
- (void)wrefresh(td->win);
- return (0);
-
-
- /* Suspend/Resume curses */
- case TERM_XTRA_ALIVE:
- return (Term_xtra_gcu_alive(v));
-
- /* Process events */
- case TERM_XTRA_EVENT:
- return (Term_xtra_gcu_event(v));
-
- /* Flush events */
- case TERM_XTRA_FLUSH:
- while (!Term_xtra_gcu_event(FALSE));
- return (0);
-
- /* React to events */
- case TERM_XTRA_REACT:
Term_xtra_gcu_react();
- return (0);
}
- /* Unknown */
- return (1);
-}
-
-
-/*
- * Actually MOVE the hardware cursor
- */
-static errr Term_curs_gcu(int x, int y)
-{
- term_data *td = (term_data *)(Term->data);
-
- /* Literally move the cursor */
- wmove(td->win, y, x);
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Place some text on the screen using an attribute
- */
-static errr Term_text_gcu(int x, int y, int n, byte a, cptr s)
-{
- term_data *td = (term_data *)(Term->data);
+ void rename_main_window(std::string_view) final
+ {
+ // Don't have window titles
+ }
- int i;
+ void draw_cursor(int x, int y) final
+ {
+ wmove(m_term_data->win, y, x);
+ }
-#ifdef A_COLOR
- /* Set the color */
- if (can_use_color) wattrset(td->win, colortable[a & 0x0F]);
-#endif
+ void draw_text(int x, int y, int n, byte a, const char *s) final
+ {
+ /* Set the color */
+ if (can_use_color)
+ {
+ wattrset(m_term_data->win, colortable[a & 0x0F]);
+ }
- /* Move the cursor */
- wmove(td->win, y, x);
+ /* Move the cursor */
+ wmove(m_term_data->win, y, x);
- /* Draw each character */
- for (i = 0; i < n; i++)
- {
+ /* Draw each character */
+ for (int i = 0; i < n; i++)
+ {
- /* Draw a normal character */
- waddch(td->win, (byte)s[i]);
+ /* Draw a normal character */
+ waddch(m_term_data->win, (byte)s[i]);
+ }
}
- /* Success */
- return (0);
-}
+};
+
+int CursesFrontend::m_active = 0;
/*
@@ -737,8 +663,6 @@ static errr Term_text_gcu(int x, int y, int n, byte a, cptr s)
*/
static errr term_data_init_gcu(term_data *td, int rows, int cols, int y, int x)
{
- term *t = &td->t;
-
/* Create new window */
td->win = newwin(rows, cols, y, x);
@@ -750,37 +674,18 @@ static errr term_data_init_gcu(term_data *td, int rows, int cols, int y, int x)
}
/* Initialize the term */
- term_init(t, cols, rows, 256);
-
- /* Avoid bottom right corner */
- t->icky_corner = TRUE;
-
- /* Set some hooks */
- t->init_hook = Term_init_gcu;
- t->nuke_hook = Term_nuke_gcu;
-
- /* Set some more hooks */
- t->text_hook = Term_text_gcu;
- t->curs_hook = Term_curs_gcu;
- t->xtra_hook = Term_xtra_gcu;
-
- /* Save the data */
- t->data = td;
+ td->term_ptr = term_init(cols, rows, 256, std::make_shared<CursesFrontend>(td));
/* Activate it */
- Term_activate(t);
+ Term_activate(td->term_ptr);
/* Success */
return (0);
}
-static void hook_quit(cptr str)
+static void hook_quit(const char *)
{
- /* Unused */
- (void)str;
-
- /* Exit curses */
endwin();
}
@@ -799,15 +704,15 @@ int init_gcu(int argc, char **argv)
int num_term = MAX_TERM_DATA, next_win = 0;
- bool_ use_big_screen = FALSE;
+ bool use_big_screen = false;
/* Parse args */
for (i = 1; i < argc; i++)
{
- if (prefix(argv[i], "-b"))
+ if (starts_with(argv[i], "-b"))
{
- use_big_screen = TRUE;
+ use_big_screen = true;
continue;
}
@@ -833,8 +738,6 @@ int init_gcu(int argc, char **argv)
-#ifdef A_COLOR
-
/*** Init the Color-pairs and set up a translation table ***/
/* Do we have color, and enough color, available? */
@@ -905,8 +808,6 @@ int init_gcu(int argc, char **argv)
colortable[15] = (COLOR_PAIR(3) | A_NORMAL); /* Light Umber XXX */
}
-#endif
-
/*** Low level preparation ***/
@@ -929,7 +830,7 @@ int init_gcu(int argc, char **argv)
term_data_init_gcu(&data[0], LINES, COLS, 0, 0);
/* Remember the term */
- angband_term[0] = &data[0].t;
+ angband_term[0] = data[0].term_ptr;
}
/* No big screen -- create as many term windows as possible */
@@ -997,7 +898,7 @@ int init_gcu(int argc, char **argv)
term_data_init_gcu(&data[next_win], rows, cols, y, x);
/* Remember the term */
- angband_term[next_win] = &data[next_win].t;
+ angband_term[next_win] = data[next_win].term_ptr;
/* One more window */
next_win++;
@@ -1005,10 +906,10 @@ int init_gcu(int argc, char **argv)
}
/* Activate the "Angband" window screen */
- Term_activate(&data[0].t);
+ Term_activate(data[0].term_ptr);
/* Remember the active screen */
- term_screen = &data[0].t;
+ angband_term[0] = data[0].term_ptr;
/* Success */
return (0);
diff --git a/src/main-gtk2.c b/src/main-gtk2.cc
index 124802c3..f660048f 100644
--- a/src/main-gtk2.c
+++ b/src/main-gtk2.cc
@@ -30,10 +30,14 @@
* and reorganised the file a bit.
*/
-#include "files.h"
-#include "main.h"
-#include "util.h"
-#include "variable.h"
+#include "config.hpp"
+#include "files.hpp"
+#include "frontend.hpp"
+#include "main.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+#include "z-util.hpp"
+#include "z-form.hpp"
/* Force ANSI standard */
@@ -48,8 +52,12 @@
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
-#include <assert.h>
+#include <cassert>
+#include <boost/algorithm/string/predicate.hpp>
+
+using boost::algorithm::starts_with;
+using boost::algorithm::equals;
/*
* Number of pixels inserted between the menu bar and the main screen
@@ -80,7 +88,7 @@ typedef struct term_data term_data;
struct term_data
{
- term t;
+ term *term_ptr;
GtkWidget *window;
GtkWidget *drawing_area;
@@ -88,7 +96,7 @@ struct term_data
GdkFont *font;
GdkGC *gc;
- bool_ shown;
+ bool shown;
byte last_attr;
int font_wid;
@@ -139,9 +147,9 @@ static guint32 angband_colours[16];
/*
- * Set to TRUE when a game is in progress
+ * Set to true when a game is in progress
*/
-static bool_ game_in_progress = FALSE;
+static bool game_in_progress = false;
/*
@@ -151,7 +159,7 @@ static bool_ game_in_progress = FALSE;
* with the MIT Shm extention which is usually active if you run
* Angband locally, because it reduces amount of memory-to-memory copy.
*/
-static bool_ use_backing_store = TRUE;
+static bool use_backing_store = true;
@@ -161,10 +169,10 @@ static bool_ use_backing_store = TRUE;
/*
* Look up some environment variables to find font name for each window.
*/
-static cptr get_default_font(int term)
+static const char *get_default_font(int term)
{
char buf[64];
- cptr font_name;
+ const char *font_name;
/* Window specific font name */
strnfmt(buf, 64, "ANGBAND_X11_FONT_%s", angband_term_name[term]);
@@ -191,7 +199,7 @@ static cptr get_default_font(int term)
/*
* New global flag to indicate if it's safe to save now
*/
-#define can_save TRUE
+#define can_save true
@@ -209,7 +217,7 @@ static cptr get_default_font(int term)
* clever fashion. Ditto for the tile scaling code and the BMP loader
* below.
*/
-static void init_colours(void)
+static void init_colours()
{
int i;
@@ -254,44 +262,15 @@ static void term_data_set_fg(term_data *td, byte attr)
/*
- * Free data used by a term
- */
-static void Term_nuke_gtk(term *t)
-{
- term_data *td = t->data;
-
-
- /* Free name */
- if (td->name) free(td->name);
-
- /* Forget it */
- td->name = NULL;
-
- /* Free font */
- if (td->font) gdk_font_unref(td->font);
-
- /* Forget it */
- td->font = NULL;
-
- /* Free backing store */
- if (td->backing_store) gdk_pixmap_unref(td->backing_store);
-
- /* Forget it too */
- td->backing_store = NULL;
-
-}
-
-
-/*
* Erase the whole term.
*/
-static errr Term_clear_gtk(void)
+static void Term_clear_gtk(term_data *td)
{
- term_data *td = (term_data*)(Term->data);
-
-
/* Don't draw to hidden windows */
- if (!td->shown) return (0);
+ if (!td->shown)
+ {
+ return;
+ }
/* Paranoia */
g_assert(td->drawing_area->window != 0);
@@ -308,20 +287,14 @@ static errr Term_clear_gtk(void)
/* Copy image from backing store if present */
TERM_DATA_REFRESH(td, 0, 0, td->cols, td->rows);
-
- /* Success */
- return (0);
}
/*
* Erase some characters.
*/
-static errr Term_wipe_gtk(int x, int y, int n)
+static errr Term_wipe_gtk(term_data *td, int x, int y, int n)
{
- term_data *td = (term_data*)(Term->data);
-
-
/* Don't draw to hidden windows */
if (!td->shown) return (0);
@@ -332,7 +305,7 @@ static errr Term_wipe_gtk(int x, int y, int n)
gdk_draw_rectangle(
TERM_DATA_DRAWABLE(td),
td->drawing_area->style->black_gc,
- TRUE,
+ true,
x * td->font_wid,
y * td->font_hgt,
n * td->font_wid,
@@ -347,86 +320,10 @@ static errr Term_wipe_gtk(int x, int y, int n)
/*
- * Draw some textual characters.
- */
-static errr Term_text_gtk(int x, int y, int n, byte a, cptr s)
-{
- term_data *td = (term_data*)(Term->data);
-
-
- /* Don't draw to hidden windows */
- if (!td->shown) return (0);
-
- /* Paranoia */
- g_assert(td->drawing_area->window != 0);
-
- /* Set foreground colour */
- term_data_set_fg(td, a);
-
- /* Clear the line */
- Term_wipe_gtk(x, y, n);
-
- /* Draw the text to the window */
- gdk_draw_text(
- TERM_DATA_DRAWABLE(td),
- td->font,
- td->gc,
- x * td->font_wid,
- td->font->ascent + y * td->font_hgt,
- s,
- n);
-
- /* Copy image from backing store if present */
- TERM_DATA_REFRESH(td, x, y, n, 1);
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Draw software cursor at (x, y)
- */
-static errr Term_curs_gtk(int x, int y)
-{
- term_data *td = (term_data*)(Term->data);
- int cells = 1;
-
-
- /* Don't draw to hidden windows */
- if (!td->shown) return (0);
-
- /* Paranoia */
- g_assert(td->drawing_area->window != 0);
-
- /* Set foreground colour */
- term_data_set_fg(td, TERM_YELLOW);
-
- /* Draw the software cursor */
- gdk_draw_rectangle(
- TERM_DATA_DRAWABLE(td),
- td->gc,
- FALSE,
- x * td->font_wid,
- y * td->font_hgt,
- td->font_wid * cells - 1,
- td->font_hgt - 1);
-
- /* Copy image from backing store if present */
- TERM_DATA_REFRESH(td, x, y, cells, 1);
-
- /* Success */
- return (0);
-}
-
-
-
-
-/*
* Process an event, if there's none block when wait is set true,
* return immediately otherwise.
*/
-static void CheckEvent(bool_ wait)
+static void CheckEvent(bool wait)
{
/* Process an event */
(void)gtk_main_iteration_do(wait);
@@ -436,98 +333,167 @@ static void CheckEvent(bool_ wait)
/*
* Process all pending events (without blocking)
*/
-static void DrainEvents(void)
+static void DrainEvents()
{
while (gtk_events_pending())
gtk_main_iteration();
}
-/*
- * Handle a "special request"
+
+/**
+ * GTK2 implementation of a UserInterface
*/
-static errr Term_xtra_gtk(int n, int v)
-{
- /* Handle a subset of the legal requests */
- switch (n)
+class Gtk2Frontend final : public Frontend {
+
+private:
+ term_data *m_term_data;
+
+public:
+ Gtk2Frontend(term_data *term_data)
+ : m_term_data(term_data)
{
- /* Make a noise */
- case TERM_XTRA_NOISE:
- {
- /* Beep */
- gdk_beep();
+ }
- /* Success */
- return (0);
- }
+ void init() final
+ {
+ }
- /* Flush the output */
- case TERM_XTRA_FRESH:
+ void nuke() final
+ {
+ /* Free name */
+ if (m_term_data->name)
{
- /* Flush pending X requests - almost always no-op */
- gdk_flush();
-
- /* Success */
- return (0);
+ free(m_term_data->name);
}
+ m_term_data->name = NULL;
- /* Process random events */
- case TERM_XTRA_BORED:
+ /* Free font */
+ if (m_term_data->font)
{
- /* Process a pending event if there's one */
- CheckEvent(FALSE);
-
- /* Success */
- return (0);
+ gdk_font_unref(m_term_data->font);
}
+ m_term_data->font = NULL;
- /* Process Events */
- case TERM_XTRA_EVENT:
+ /* Free backing store */
+ if (m_term_data->backing_store)
{
- /* Process an event */
- CheckEvent(v);
-
- /* Success */
- return (0);
+ gdk_pixmap_unref(m_term_data->backing_store);
}
+ m_term_data->backing_store = NULL;
+ }
- /* Flush the events */
- case TERM_XTRA_FLUSH:
- {
- /* Process all pending events */
- DrainEvents();
+ void process_event(bool wait) final
+ {
+ CheckEvent(wait);
+ }
- /* Success */
- return (0);
- }
+ bool soft_cursor() const final
+ {
+ return true;
+ }
+
+ bool icky_corner() const final
+ {
+ return false;
+ }
- /* Handle change in the "level" */
- case TERM_XTRA_LEVEL:
- return (0);
+ void flush_events() final
+ {
+ DrainEvents();
+ }
- /* Clear the screen */
- case TERM_XTRA_CLEAR:
- return (Term_clear_gtk());
+ void process_queued_events() final
+ {
+ CheckEvent(false);
+ }
- /* Rename main window */
- case TERM_XTRA_RENAME_MAIN_WIN: gtk_window_set_title(GTK_WINDOW(data[0].window), angband_term_name[0]); return (0);
+ void clear() final
+ {
+ Term_clear_gtk(m_term_data);
+ }
- /* React to changes */
- case TERM_XTRA_REACT:
- {
- /* (re-)init colours */
- init_colours();
+ void flush_output() final
+ {
+ gdk_flush();
+ }
+
+ void noise() final
+ {
+ gdk_beep();
+ }
+ void react() final
+ {
+ init_colours();
+ }
- /* Success */
- return (0);
+ void rename_main_window(std::string_view name_sv) final
+ {
+ gtk_window_set_title(GTK_WINDOW(data[0].window), std::string(angband_term_name[0]).c_str());
+ }
+
+ void draw_cursor(int x, int y) final
+ {
+ int cells = 1;
+
+ /* Don't draw to hidden windows */
+ if (!m_term_data->shown)
+ {
+ return;
}
+
+ /* Paranoia */
+ g_assert(m_term_data->drawing_area->window != 0);
+
+ /* Set foreground colour */
+ term_data_set_fg(m_term_data, TERM_YELLOW);
+
+ /* Draw the software cursor */
+ gdk_draw_rectangle(
+ TERM_DATA_DRAWABLE(m_term_data),
+ m_term_data->gc,
+ false,
+ x * m_term_data->font_wid,
+ y * m_term_data->font_hgt,
+ m_term_data->font_wid * cells - 1,
+ m_term_data->font_hgt - 1);
+
+ /* Copy image from backing store if present */
+ TERM_DATA_REFRESH(m_term_data, x, y, cells, 1);
}
- /* Unknown */
- return (1);
-}
+ void draw_text(int x, int y, int n, byte a, const char *s) final
+ {
+ /* Don't draw to hidden windows */
+ if (!m_term_data->shown)
+ {
+ return;
+ }
+
+ /* Paranoia */
+ g_assert(m_term_data->drawing_area->window != 0);
+
+ /* Set foreground colour */
+ term_data_set_fg(m_term_data, a);
+
+ /* Clear the line */
+ Term_wipe_gtk(m_term_data, x, y, n);
+
+ /* Draw the text to the window */
+ gdk_draw_text(
+ TERM_DATA_DRAWABLE(m_term_data),
+ m_term_data->font,
+ m_term_data->gc,
+ x * m_term_data->font_wid,
+ m_term_data->font->ascent + y * m_term_data->font_hgt,
+ s,
+ n);
+ /* Copy image from backing store if present */
+ TERM_DATA_REFRESH(m_term_data, x, y, n, 1);
+ }
+};
@@ -596,8 +562,8 @@ static void term_data_set_geometry_hints(term_data *td)
/* Give the window a new set of resizing hints */
gtk_window_set_geometry_hints(GTK_WINDOW(td->window),
td->drawing_area, &geometry,
- GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE
- | GDK_HINT_BASE_SIZE | GDK_HINT_RESIZE_INC);
+ GdkWindowHints(GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE
+ | GDK_HINT_BASE_SIZE | GDK_HINT_RESIZE_INC));
}
@@ -646,7 +612,7 @@ static void term_data_set_backing_store(term_data *td)
gdk_draw_rectangle(
td->backing_store,
td->drawing_area->style->black_gc,
- TRUE,
+ true,
0,
0,
td->cols * td->font_wid,
@@ -658,7 +624,7 @@ static void term_data_set_backing_store(term_data *td)
/*
* Save game only when it's safe to do so
*/
-static void save_game_gtk(void)
+static void save_game_gtk()
{
/* We have nothing to save, yet */
if (!game_in_progress || !character_generated) return;
@@ -671,7 +637,7 @@ static void save_game_gtk(void)
}
/* Hack -- Forget messages */
- msg_flag = FALSE;
+ msg_flag = false;
/* Save the game */
do_cmd_save_game();
@@ -681,7 +647,7 @@ static void save_game_gtk(void)
/*
* Display message in a modal dialog
*/
-static void gtk_message(cptr msg)
+static void gtk_message(const char *msg)
{
GtkWidget *dialog, *label, *ok_button;
@@ -711,7 +677,7 @@ static void gtk_message(cptr msg)
label);
/* And make it modal */
- gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+ gtk_window_set_modal(GTK_WINDOW(dialog), true);
/* Show the dialog */
gtk_widget_show_all(dialog);
@@ -721,7 +687,7 @@ static void gtk_message(cptr msg)
/*
* Hook to tell the user something important
*/
-static void hook_plog(cptr str)
+static void hook_plog(const char *str)
{
/* Warning message */
gtk_message(str);
@@ -785,7 +751,7 @@ static void destroy_sub_event_handler(
* Load fond specified by an XLFD fontname and
* set up related term_data members
*/
-static void load_font(term_data *td, cptr fontname)
+static void load_font(term_data *td, const char *fontname)
{
GdkFont *old = td->font;
@@ -803,10 +769,22 @@ static void load_font(term_data *td, cptr fontname)
td->font = old;
}
+ /* Check that the font actually was loaded */
+ if (!td->font)
+ {
+ quit_fmt("Could not load font '%s'... quitting", fontname);
+ }
+
/* Calculate the size of the font XXX */
td->font_wid = gdk_char_width(td->font, '@');
td->font_hgt = td->font->ascent + td->font->descent;
+ // Fallback in case we can't calculate font width; it's not going to
+ // be pretty, but it should at least not fail catastrophically.
+ if (!td->font_wid)
+ {
+ td->font_wid = td->font_hgt;
+ }
}
@@ -887,7 +865,7 @@ static gboolean delete_event_handler(
save_game_gtk();
/* Don't prevent closure */
- return (FALSE);
+ return false;
}
@@ -905,17 +883,17 @@ static gboolean keypress_event_handler(
char msg[128];
/* Hack - do not do anything until the player picks from the menu */
- if (!game_in_progress) return (TRUE);
+ if (!game_in_progress) return true;
/* Hack - Ignore parameters */
(void) widget;
(void) user_data;
/* Extract four "modifier flags" */
- mc = (event->state & GDK_CONTROL_MASK) ? TRUE : FALSE;
- ms = (event->state & GDK_SHIFT_MASK) ? TRUE : FALSE;
- mo = (event->state & GDK_MOD1_MASK) ? TRUE : FALSE;
- mx = (event->state & GDK_MOD3_MASK) ? TRUE : FALSE;
+ mc = (event->state & GDK_CONTROL_MASK) ? true : false;
+ ms = (event->state & GDK_SHIFT_MASK) ? true : false;
+ mo = (event->state & GDK_MOD1_MASK) ? true : false;
+ mx = (event->state & GDK_MOD3_MASK) ? true : false;
/*
* Hack XXX
@@ -937,7 +915,7 @@ static gboolean keypress_event_handler(
macro_add(msg, event->string);
}
- return (TRUE);
+ return true;
}
/* Normal keys with no modifiers */
@@ -947,36 +925,36 @@ static gboolean keypress_event_handler(
for (i = 0; i < event->length; i++) Term_keypress(event->string[i]);
/* All done */
- return (TRUE);
+ return true;
}
/* Handle a few standard keys (bypass modifiers) XXX XXX XXX */
- switch ((uint) event->keyval)
+ switch ((unsigned int) event->keyval)
{
case GDK_Escape:
{
Term_keypress(ESCAPE);
- return (TRUE);
+ return true;
}
case GDK_Return:
{
Term_keypress('\r');
- return (TRUE);
+ return true;
}
case GDK_Tab:
{
Term_keypress('\t');
- return (TRUE);
+ return true;
}
case GDK_Delete:
case GDK_BackSpace:
{
Term_keypress('\010');
- return (TRUE);
+ return true;
}
case GDK_Shift_L:
@@ -995,7 +973,7 @@ static gboolean keypress_event_handler(
case GDK_Hyper_R:
{
/* Hack - do nothing to control characters */
- return (TRUE);
+ return true;
}
}
@@ -1015,7 +993,7 @@ static gboolean keypress_event_handler(
macro_add(msg, event->string);
}
- return (TRUE);
+ return true;
}
@@ -1048,7 +1026,7 @@ static void realize_event_handler(
gdk_draw_rectangle(
widget->window,
widget->style->black_gc,
- TRUE,
+ true,
0,
0,
td->cols * td->font_wid,
@@ -1066,7 +1044,7 @@ static void show_event_handler(
term_data *td = (term_data *)user_data;
/* Set the shown flag */
- td->shown = TRUE;
+ td->shown = true;
}
@@ -1080,7 +1058,7 @@ static void hide_event_handler(
term_data *td = (term_data *)user_data;
/* Set the shown flag */
- td->shown = FALSE;
+ td->shown = false;
}
@@ -1092,19 +1070,13 @@ static void size_allocate_event_handler(
GtkAllocation *allocation,
gpointer user_data)
{
- term_data *td = user_data;
- int old_rows, old_cols;
- term *old = Term;
+ term_data *td = (term_data *) user_data;
/* Paranoia */
g_return_if_fail(widget != NULL);
g_return_if_fail(allocation != NULL);
g_return_if_fail(td != NULL);
- /* Remember old values */
- old_cols = td->cols;
- old_rows = td->rows;
-
/* Update numbers of rows and columns */
td->cols = (allocation->width + td->font_wid - 1) / td->font_wid;
td->rows = (allocation->height + td->font_hgt - 1) / td->font_hgt;
@@ -1132,20 +1104,11 @@ static void size_allocate_event_handler(
allocation->height);
/* And in the term package */
- Term_activate(&td->t);
-
- /* Resize if necessary */
- if ((td->cols != old_cols) || (td->rows != old_rows))
- (void)Term_resize(td->cols, td->rows);
-
- /* Redraw its content */
- Term_redraw();
-
- /* Refresh */
- Term_fresh();
-
- /* Restore */
- Term_activate(old);
+ Term_with_active(td->term_ptr, [&td]() {
+ Term_resize(td->cols, td->rows);
+ Term_redraw();
+ Term_fresh();
+ });
}
}
@@ -1158,19 +1121,10 @@ static gboolean expose_event_handler(
GdkEventExpose *event,
gpointer user_data)
{
- term_data *td = user_data;
-
- term *old = Term;
-
-#ifndef NO_REDRAW_SECTION
-
- int x1, x2, y1, y2;
-
-#endif /* !NO_REDRAW_SECTION */
-
+ term_data *td = (term_data *) user_data;
/* Paranoia */
- if (td == NULL) return (TRUE);
+ if (td == NULL) return true;
/* The window has a backing store */
if (td->backing_store)
@@ -1191,50 +1145,47 @@ static gboolean expose_event_handler(
/* No backing store - use the game's code to redraw the area */
else
{
-
/* Activate the relevant term */
- Term_activate(&td->t);
+ Term_with_active(td->term_ptr, [&event, &td]() {
# ifdef NO_REDRAW_SECTION
- /* K.I.S.S. version */
+ /* K.I.S.S. version */
- /* Redraw */
- Term_redraw();
+ /* Redraw */
+ Term_redraw();
# else /* NO_REDRAW_SECTION */
- /*
- * Complex version - The above is enough, but since we have
- * Term_redraw_section... This might help if we had a graphics
- * mode.
- */
+ /*
+ * Complex version - The above is enough, but since we have
+ * Term_redraw_section... This might help if we had a graphics
+ * mode.
+ */
- /* Convert coordinate in pixels to character cells */
- x1 = event->area.x / td->font_wid;
- x2 = (event->area.x + event->area.width) / td->font_wid;
- y1 = event->area.y / td->font_hgt;
- y2 = (event->area.y + event->area.height) / td->font_hgt;
+ /* Convert coordinate in pixels to character cells */
+ int x1 = event->area.x / td->font_wid;
+ int x2 = (event->area.x + event->area.width) / td->font_wid;
+ int y1 = event->area.y / td->font_hgt;
+ int y2 = (event->area.y + event->area.height) / td->font_hgt;
- /*
- * No paranoia - boundary checking is done in
- * Term_redraw_section
- */
+ /*
+ * No paranoia - boundary checking is done in
+ * Term_redraw_section
+ */
- /* Redraw the area */
- Term_redraw_section(x1, y1, x2, y2);
+ /* Redraw the area */
+ Term_redraw_section(x1, y1, x2, y2);
# endif /* NO_REDRAW_SECTION */
- /* Refresh */
- Term_fresh();
-
- /* Restore */
- Term_activate(old);
+ /* Refresh */
+ Term_fresh();
+ });
}
/* We've processed the event ourselves */
- return (TRUE);
+ return true;
}
@@ -1245,16 +1196,15 @@ static gboolean expose_event_handler(
/*
* Initialise a term_data struct
*/
-static errr term_data_init(term_data *td, int i)
+static term *term_data_init(term_data *td, int i)
{
- term *t = &td->t;
char *p;
td->cols = 80;
td->rows = 24;
/* Initialize the term */
- term_init(t, td->cols, td->rows, 1024);
+ td->term_ptr = term_init(td->cols, td->rows, 1024, std::make_shared<Gtk2Frontend>(td));
/* Store the name of the term */
assert(angband_term_name[i] != NULL);
@@ -1263,25 +1213,83 @@ static errr term_data_init(term_data *td, int i)
/* Instance names should start with a lowercase letter XXX */
for (p = (char *)td->name; *p; p++) *p = tolower(*p);
- /* Use a "soft" cursor */
- t->soft_cursor = TRUE;
+ /* Activate (important) */
+ Term_activate(td->term_ptr);
+
+ /* Success */
+ return td->term_ptr;
+}
+
+/*
+ * Helper for menu declaration since we need a few casts in C++.
+ */
+namespace { // anonymous
- /* Hooks */
- t->xtra_hook = Term_xtra_gtk;
- t->text_hook = Term_text_gtk;
- t->curs_hook = Term_curs_gtk;
- t->nuke_hook = Term_nuke_gtk;
+using menu_callback = void(gpointer user_data, guint user_action, GtkWidget *widget);
- /* Save the data */
- t->data = td;
+auto make_menu_item(const char *path, const char *accel, menu_callback callback, guint action, const char *type)
+{
+ return GtkItemFactoryEntry {
+ (gchar *) path,
+ (gchar *) accel,
+ (GtkItemFactoryCallback) callback,
+ action,
+ (gchar *) type,
+ nullptr,
+ };
+}
- /* Activate (important) */
- Term_activate(t);
+auto menu_branch(const char *path)
+{
+ return make_menu_item(
+ path,
+ nullptr,
+ nullptr,
+ 0,
+ "<Branch>");
+}
- /* Success */
- return (0);
+auto menu_terminal(const char *accel, guint terminal_number)
+{
+ return make_menu_item(
+ nullptr /* Filled in by setup_menu_paths() */,
+ accel,
+ term_event_handler,
+ terminal_number,
+ "<CheckItem>");
+}
+
+auto menu_font(guint terminal_number)
+{
+ return make_menu_item(
+ nullptr /* Filled in by setup_menu_paths() */,
+ nullptr,
+ change_font_event_handler,
+ terminal_number,
+ nullptr);
}
+auto menu_action(const char *path, const char *accel, menu_callback callback)
+{
+ return make_menu_item(
+ path,
+ accel,
+ callback,
+ 0,
+ nullptr);
+}
+
+auto menu_check_item(const char *path, const char *accel, menu_callback callback)
+{
+ return make_menu_item(
+ path,
+ accel,
+ callback,
+ 0,
+ "<CheckItem>");
+}
+
+} // namespace (anonymous)
/*
* Neater menu code with GtkItemFactory.
@@ -1299,66 +1307,38 @@ static errr term_data_init(term_data *td, int i)
static GtkItemFactoryEntry main_menu_items[] =
{
/* "File" menu */
- { "/File", NULL,
- NULL, 0, "<Branch>", NULL
- },
- { "/File/Save", "<mod1>S",
- save_event_handler, 0, NULL, NULL },
- { "/File/Quit", "<mod1>Q",
- quit_event_handler, 0, NULL, NULL },
+ menu_branch("/File"),
+ menu_action("/File/Save", "<mod1>S", save_event_handler),
+ menu_action("/File/Quit", "<mod1>Q", quit_event_handler),
/* "Terms" menu */
- { "/Terms", NULL,
- NULL, 0, "<Branch>", NULL },
- /* XXX XXX XXX NULL's are replaced by the program */
- { NULL, "<mod1>0",
- term_event_handler, 0, "<CheckItem>", NULL },
- { NULL, "<mod1>1",
- term_event_handler, 1, "<CheckItem>", NULL },
- { NULL, "<mod1>2",
- term_event_handler, 2, "<CheckItem>", NULL },
- { NULL, "<mod1>3",
- term_event_handler, 3, "<CheckItem>", NULL },
- { NULL, "<mod1>4",
- term_event_handler, 4, "<CheckItem>", NULL },
- { NULL, "<mod1>5",
- term_event_handler, 5, "<CheckItem>", NULL },
- { NULL, "<mod1>6",
- term_event_handler, 6, "<CheckItem>", NULL },
- { NULL, "<mod1>7",
- term_event_handler, 7, "<CheckItem>", NULL },
+ menu_branch("/Terms"),
+ menu_terminal("<mod1>0", 0),
+ menu_terminal("<mod1>1", 1),
+ menu_terminal("<mod1>2", 2),
+ menu_terminal("<mod1>3", 3),
+ menu_terminal("<mod1>4", 4),
+ menu_terminal("<mod1>5", 5),
+ menu_terminal("<mod1>6", 6),
+ menu_terminal("<mod1>7", 7),
/* "Options" menu */
- { "/Options", NULL,
- NULL, 0, "<Branch>", NULL },
+ menu_branch("/Options"),
/* "Font" submenu */
- { "/Options/Font", NULL,
- NULL, 0, "<Branch>", NULL },
- /* XXX XXX XXX Again, NULL's are filled by the program */
- { NULL, NULL,
- change_font_event_handler, 0, NULL, NULL },
- { NULL, NULL,
- change_font_event_handler, 1, NULL, NULL },
- { NULL, NULL,
- change_font_event_handler, 2, NULL, NULL },
- { NULL, NULL,
- change_font_event_handler, 3, NULL, NULL },
- { NULL, NULL,
- change_font_event_handler, 4, NULL, NULL },
- { NULL, NULL,
- change_font_event_handler, 5, NULL, NULL },
- { NULL, NULL,
- change_font_event_handler, 6, NULL, NULL },
- { NULL, NULL,
- change_font_event_handler, 7, NULL, NULL },
-
+ menu_branch("/Options/Font"),
+ menu_font(0),
+ menu_font(1),
+ menu_font(2),
+ menu_font(3),
+ menu_font(4),
+ menu_font(5),
+ menu_font(6),
+ menu_font(7),
/* "Misc" submenu */
- { "/Options/Misc", NULL,
- NULL, 0, "<Branch>", NULL },
- { "/Options/Misc/Backing store", NULL,
- change_backing_store_event_handler, 0, "<CheckItem>", NULL },
+ menu_branch("/Options/Misc"),
+ menu_check_item("/Options/Misc/Backing store", nullptr, change_backing_store_event_handler),
};
@@ -1366,7 +1346,7 @@ static GtkItemFactoryEntry main_menu_items[] =
* XXX XXX Fill those NULL's in the menu definition with
* angband_term_name[] strings
*/
-static void setup_menu_paths(void)
+static void setup_menu_paths()
{
int i;
int nmenu_items = sizeof(main_menu_items) / sizeof(main_menu_items[0]);
@@ -1380,7 +1360,7 @@ static void setup_menu_paths(void)
if (main_menu_items[i].path == NULL) continue;
/* Find a match */
- if (streq(main_menu_items[i].path, "/Terms")) break;
+ if (equals(main_menu_items[i].path, "/Terms")) break;
}
g_assert(i < (nmenu_items - MAX_TERM_DATA));
@@ -1394,7 +1374,7 @@ static void setup_menu_paths(void)
if (main_menu_items[i].path == NULL) continue;
/* Find a match */
- if (streq(main_menu_items[i].path, "/Options/Font")) break;
+ if (equals(main_menu_items[i].path, "/Options/Font")) break;
}
g_assert(i < (nmenu_items - MAX_TERM_DATA));
@@ -1422,7 +1402,7 @@ static void setup_menu_paths(void)
/*
* XXX XXX Free strings allocated by setup_menu_paths()
*/
-static void free_menu_paths(void)
+static void free_menu_paths()
{
int i;
int nmenu_items = sizeof(main_menu_items) / sizeof(main_menu_items[0]);
@@ -1435,7 +1415,7 @@ static void free_menu_paths(void)
if (main_menu_items[i].path == NULL) continue;
/* Find a match */
- if (streq(main_menu_items[i].path, "/Terms")) break;
+ if (equals(main_menu_items[i].path, "/Terms")) break;
}
g_assert(i < (nmenu_items - MAX_TERM_DATA));
@@ -1449,7 +1429,7 @@ static void free_menu_paths(void)
if (main_menu_items[i].path == NULL) continue;
/* Find a match */
- if (streq(main_menu_items[i].path, "/Options/Font")) break;
+ if (equals(main_menu_items[i].path, "/Options/Font")) break;
}
g_assert(i < (nmenu_items - MAX_TERM_DATA));
@@ -1472,7 +1452,7 @@ static void free_menu_paths(void)
* Find widget corresponding to path name
* return NULL on error
*/
-static GtkWidget *get_widget_from_path(cptr path)
+static GtkWidget *get_widget_from_path(const char *path)
{
GtkItemFactory *item_factory;
GtkWidget *widget;
@@ -1497,7 +1477,7 @@ static GtkWidget *get_widget_from_path(cptr path)
/*
* Enable/disable a menu item
*/
-void enable_menu_item(cptr path, bool_ enabled)
+void enable_menu_item(const char *path, bool enabled)
{
GtkWidget *widget;
@@ -1519,7 +1499,7 @@ void enable_menu_item(cptr path, bool_ enabled)
/*
* Check/uncheck a menu item. The item should be of the GtkCheckMenuItem type
*/
-void check_menu_item(cptr path, bool_ checked)
+void check_menu_item(const char *path, bool checked)
{
GtkWidget *widget;
@@ -1550,18 +1530,18 @@ static void file_menu_update_handler(
GtkWidget *widget,
gpointer user_data)
{
- bool_ save_ok, quit_ok;
+ bool save_ok, quit_ok;
/* Cave we save/quit now? */
if (!character_generated || !game_in_progress)
{
- save_ok = FALSE;
- quit_ok = TRUE;
+ save_ok = false;
+ quit_ok = true;
}
else
{
- if (inkey_flag && can_save) save_ok = quit_ok = TRUE;
- else save_ok = quit_ok = FALSE;
+ if (inkey_flag && can_save) save_ok = quit_ok = true;
+ else save_ok = quit_ok = false;
}
/* Enable / disable menu items according to those conditions */
@@ -1745,9 +1725,9 @@ static void add_menu_update_callbacks()
static void init_gtk_window(term_data *td, int i)
{
GtkWidget *menu_bar = NULL, *box;
- cptr font;
+ const char *font;
- bool_ main_window = (i == 0) ? TRUE : FALSE;
+ bool main_window = (i == 0) ? true : false;
/* Create window */
@@ -1852,7 +1832,7 @@ static void init_gtk_window(term_data *td, int i)
/* Pack the menu bar together with the main window */
/* For vertical placement of the menu bar and the drawing area */
- box = gtk_vbox_new(FALSE, 0);
+ box = gtk_vbox_new(false, 0);
/* Let the window widget own it */
gtk_container_add(GTK_CONTAINER(td->window), box);
@@ -1862,8 +1842,8 @@ static void init_gtk_window(term_data *td, int i)
gtk_box_pack_start(
GTK_BOX(box),
menu_bar,
- FALSE,
- FALSE,
+ false,
+ false,
NO_PADDING);
/* And place the drawing area just beneath it */
@@ -1878,7 +1858,7 @@ static void init_gtk_window(term_data *td, int i)
/*
* To be hooked into quit(). See z-util.c
*/
-static void hook_quit(cptr str)
+static void hook_quit(const char *str)
{
/* Free menu paths dynamically allocated */
free_menu_paths();
@@ -1907,7 +1887,7 @@ int init_gtk2(int argc, char **argv)
for (i = 1; i < argc; i++)
{
/* Number of terminals displayed at start up */
- if (prefix(argv[i], "-n"))
+ if (starts_with(argv[i], "-n"))
{
num_term = atoi(&argv[i][2]);
if (num_term > MAX_TERM_DATA) num_term = MAX_TERM_DATA;
@@ -1916,9 +1896,9 @@ int init_gtk2(int argc, char **argv)
}
/* Disable use of pixmaps as backing store */
- if (streq(argv[i], "-b"))
+ if (equals(argv[i], "-b"))
{
- use_backing_store = FALSE;
+ use_backing_store = false;
continue;
}
@@ -1943,27 +1923,27 @@ int init_gtk2(int argc, char **argv)
term_data *td = &data[i];
/* Initialize the term_data */
- term_data_init(td, i);
+ term *t = term_data_init(td, i);
/* Hack - Set the shown flag, meaning "to be shown" XXX XXX */
- if (i < num_term) td->shown = TRUE;
- else td->shown = FALSE;
+ if (i < num_term) td->shown = true;
+ else td->shown = false;
/* Save global entry */
- angband_term[i] = Term;
+ angband_term[i] = t;
/* Init the window */
init_gtk_window(td, i);
}
/* Activate the "Angband" window screen */
- Term_activate(&data[0].t);
+ Term_activate(data[0].term_ptr);
/* Activate more hook */
plog_aux = hook_plog;
/* It's too early to set this, but cannot do so elsewhere XXX XXX */
- game_in_progress = TRUE;
+ game_in_progress = true;
/* Success */
return (0);
diff --git a/src/main-sdl.c b/src/main-sdl.c
deleted file mode 100644
index e9aec927..00000000
--- a/src/main-sdl.c
+++ /dev/null
@@ -1,2113 +0,0 @@
-/* Copyright (C) 2003-2004 Neil Stevens <neil@hakubi.us>
- // Copyright (C) 2004 Ethan Stump <estump@seas.upenn.edu>
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- // AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- // Except as contained in this notice, the name(s) of the author(s) shall not be
- // used in advertising or otherwise to promote the sale, use or other dealings
- // in this Software without prior written authorization from the author(s).
- */
-
-#include "loadsave.h"
-#include "main.h"
-#include "util.h"
-#include "variable.h"
-
-#include <SDL.h>
-#include <SDL_image.h>
-#include <SDL_ttf.h>
-
-#include <assert.h>
-#include <math.h>
-
-/*************************************************
- GLOBAL SDL-ToME PROPERTIES
- *************************************************/
-
-/* Default window properties - used if none are available
-from other places*/
-#define DEF_SCREEN_WIDTH 800
-#define DEF_SCREEN_HEIGHT 600
-#define DEF_SCREEN_BPP 16
-
-/*Main window properties that may be loaded at runtime from
-a preference file or environmental variables. However,
-default values (defined above) can be used. */
-static int arg_width = DEF_SCREEN_WIDTH;
-static int arg_height = DEF_SCREEN_HEIGHT;
-static int arg_bpp = DEF_SCREEN_BPP;
-
-/**************/
-
-/* Default font properties - used unless otherwise changed.
-These properties are the size and also default font to load. */
-#define DEF_FONT_SIZE 14
-#define DEF_FONT_FILE "VeraMono.ttf"
-
-/* The font properties that may perhaps be changed at runtime,
-due to environmental variables, preference files, or in-program
-commands.*/
-static int arg_font_size = DEF_FONT_SIZE;
-static char arg_font_name[64] = DEF_FONT_FILE;
-
-/**************/
-
-/* The number of term_data structures to set aside mem for */
-#define MAX_CONSOLE_COUNT 8
-
-/* The number of consoles that are actually being used.
-This number could be changed via preference files, environmental
-variables, command-line arguments, or possibly even in-game
-keypresses or menu-selections. */
-static int arg_console_count = 1;
-
-/* When rendering multiple terminals, each is drawn with a
-surrounding border. This value controls the width of this
-border */
-#define BORDER_THICKNESS 1
-
-/**************/
-
-/* flag signifying whether the game is in full screen */
-static bool_ arg_full_screen = FALSE;
-
-/* a flag to show whether window properties have been
-set or not... if so, the properties can be dumped
-upon quit*/
-static bool_ window_properties_set = FALSE;
-
-/*************************************************
- GLOBAL SDL-ToME VARIABLES
- *************************************************/
-
-/* the main screen to draw to */
-static SDL_Surface *screen;
-
-/* the video settings for the system */
-static const SDL_VideoInfo *videoInfo;
-
-/* a flag to suspend updating of the screen;
-this is in place so that when a large area is being
-redrawn -- like when doing a Term_redraw() or when
-redoing the entire screen -- all of the changes
-can be stored up before doing an update. This
-should cut down on screen flicker */
-static bool_ suspendUpdate = FALSE;
-
-/* some helper surfaces that are used for rendering
-characters */
-static SDL_Surface *worksurf;
-static SDL_Surface *crayon;
-
-/* the cursor surface */
-static SDL_Surface *cursor = NULL;
-
-/* the array of pre-rendered characters
-(see loadAndRenderFont() below) */
-SDL_Surface *text[128];
-
-/* the actual TTF_Font used (XXX should get rid of this)*/
-TTF_Font *font=0;
-
-/* the width and height of the uniformly-sized pre-rendered
-characters */
-int t_width = 0, t_height = 0;
-
-
-/*************************************************
- COLOR SETUP
- *************************************************/
-
-/* Simple black, mapped using the format of the main screen */
-int screen_black;
-
-/* The color to use for the cursor */
-static int cursor_color = 0;
-/* default cursor color is a semi-transparent yellow */
-#define DEF_CURSOR_COLOR 255,255,0,128
-
-/* The array of colors, mapped to the format of the crayon surface,
-since this is ultimately the surface that color is begin applied to */
-static int color_data[16];
-
-/* The following macro is for color defining...
- Note that the color is fully opaque... */
-#define COLOR(r,g,b) \
- SDL_MapRGBA(crayon->format,r,g,b,SDL_ALPHA_OPAQUE)
-
-/*These color macros will setup the colors to use, but must be called after
- the SDL video has been set. That way SDL can correct for any funky video
- setttings. */
-
-#define BLACK COLOR( 0, 0, 0) /* 0*/
-#define WHITE COLOR(255,255,255) /* 1*/
-#define MID_GREY COLOR(128,128,128) /* 2*/
-#define BRIGHT_ORANGE COLOR(255,128, 0) /* 3*/
-#define RED COLOR(192, 0, 0) /* 4*/
-#define GREEN COLOR( 0,128, 64) /* 5*/
-#define BRIGHT_BLUE COLOR( 0, 0,255) /* 6*/
-#define DARK_ORANGE COLOR(128, 64, 0) /* 7*/
-#define DARK_GREY COLOR( 64, 64, 64) /* 8*/
-#define BRIGHT_GREY COLOR(192,192,192) /* 9*/
-#define PURPLE COLOR(255, 0,255) /*10*/
-#define YELLOW COLOR(255,255, 0) /*11*/
-#define BRIGHT_RED COLOR(255, 0, 0) /*12*/
-#define BRIGHT_GREEN COLOR( 0,255, 0) /*13*/
-#define AQUAMARINE COLOR( 0,255,255) /*14*/
-#define BROWN COLOR(192,128, 64) /*15*/
-
-/*************************************************
- TERMINAL DATA STRUCTURE SETUP
- *************************************************/
-
-/* Forward declare */
-typedef struct _term_data term_data;
-
-/* A structure for each "term" */
-struct _term_data
-{
- term t; /* the term structure, defined in z-term.h */
- cptr name; /* name of this term sub-window */
-
- uint rows, cols; /* row/column count */
- SDL_Rect rect; /* the bounding rectangle for the entire box;
- includes border and empty space as well */
- /* this rectangle is in screen coordinates */
-
- int border_thick; /* thickness of border to draw around window */
- int border_color; /* current color of the border */
- uint cushion_x_top, cushion_x_bot, cushion_y_top, cushion_y_bot;
- /* empty space cushion between border and tiles */
-
- uint tile_width; /* the width of each tile (graphic or otherwise)*/
- uint tile_height; /* the height of each tile (graphic or otherwise)*/
-
- SDL_Surface *surf; /* the surface that graphics for this screen are
- rendered to before blitting to main screen */
- int black,white,purple; /* basic colors keyed to this terminal's surface */
-
-};
-
-/* The array of term data structures */
-static term_data data[MAX_CONSOLE_COUNT];
-
-/* Ordered array of pointers to term data structures, placed in order of
-priority: lowest is on top of all others, the higher the index, the further
-back into the screen that it is drawn */
-static term_data *term_order[MAX_CONSOLE_COUNT];
-
-/*************************************************
- FILE-SPECIFIC MACROS
- *************************************************/
-
-/* Debug macros! */
-#define DB(str) \
- printf("main-sdl: %s\n",str);
-
-/* Prints out the RGBA values of a given color */
-#define TYPECOLOR32(color) printf(" R:%d\tG:%d\tB:%d\tA:%d\t\n",\
- color>>24,(color&0x00ff0000)>>16,\
- (color&0x0000ff00)>>8,(color&0x000000ff))
-
-#define TYPECOLOR16(color) printf(" R:%d\tG:%d\tB:%d\tA:%d\t\n",\
- (color&0xf000)>>12,(color&0x0f00)>>8,\
- (color&0x00f0)>>4,(color&0x000f))
-
-/* SDL Surface locking and unlocking */
-#define SDL_LOCK(surf) \
- if (SDL_MUSTLOCK(surf) ){ \
- if (SDL_LockSurface(surf) < 0) { \
- printf("Can't lock the screen: %s\n", SDL_GetError()); \
- exit(1); \
- } \
- }
-
-#define SDL_UNLOCK(surf) \
- if (SDL_MUSTLOCK(surf) ){ \
- SDL_UnlockSurface(surf); \
- }
-
-/* Wrapped SDL_UpdateRects function, to take into
-account the fact that updates may be suspended by
-the suspendUpdate flag... this macro should be used
-whenever a rect needs updated */
-#define SDL_UPDATE(rect) \
- if (!suspendUpdate) \
- SDL_UpdateRects(screen,1,&rect)
-
-/* A complete screen redraw macro */
-#define SDL_REDRAW_SCREEN \
- SDL_UpdateRect(screen,0,0,arg_width,arg_height)
-
-/*************************************************
- QUITTING
- *************************************************/
-
-/* function prototype */
-void dumpWindowSettings(void);
-
-/* SDL Quitting function... declare a few functions first.*/
-void killFontAndAlphabet(void);
-static void sdl_quit(cptr string)
-{
- printf("sdl_quit called.\n");
- printf("message: %s\n",string);
- /* Need to take care of font and rendered characters */
- killFontAndAlphabet();
- if (TTF_WasInit())
- TTF_Quit();
- /* Then exit SDL */
- SDL_Quit();
-
- /* Dump the window properties, if available */
- if (window_properties_set)
- dumpWindowSettings();
-
- /* And now for the default quit behavior */
- quit_aux = 0;
- quit(string);
-}
-
-/*************************************************
- FONT SUPPORT FUNCTIONS
- *************************************************/
-
-/* function prototype for creating surfaces */
-SDL_Surface *createSurface(int width, int height);
-
-/* killFontAndAlphabet will effectively de-initialize the font system;
-it does this by closing the font and destroying any pre-rendered
-text in memory */
-void killFontAndAlphabet(void)
-{
- int i;
- /* need to close a font and free all of its corresponding pre-rendered
- surfaces */
- if (font)
- {
- TTF_CloseFont(font);
- font = 0;
- }
- for (i=0;i<128;i++)
- {
- if(text[i])
- {
- SDL_FreeSurface(text[i]);
- text[i] = NULL;
- }
- }
-}
-
-/* loadAndRenderFont is responsible for loading and initializing
-a font. First, SDL_ttf calls are made to load and set the style
-for the desired font. Next, a character alphabet is rendered and
-each character is placed onto a uniformly-sized surface within
-the text[] array. Whenever text is needed for displaying on-screen,
-this array is referenced and the desired character picture is used. */
-void loadAndRenderFont(char *fname, int size)
-{
- int minx,maxx,miny,maxy,advance,i,midline = 0;
- char filename[PATH_MAX + 1];
- char fontdir[PATH_MAX + 1];
- SDL_Color base_color = {255,255,255,255};
- SDL_Surface *temp_surf;
- SDL_Rect tgt = {0,0,0,0};
-
-
- /* Assuming that the filename is valid,open the font */
- path_build(fontdir, PATH_MAX, ANGBAND_DIR_XTRA, "font");
- path_build(filename, PATH_MAX, fontdir, fname);
- font = TTF_OpenFont(filename,size);
- if (font == NULL)
- sdl_quit("Error loading that font!");
- /* Set the font style to normal */
- TTF_SetFontStyle(font,TTF_STYLE_NORMAL);
-
- /* Collect some measurements on this font -
- arbitrarily choose the letter 'a' to get width*/
- TTF_GlyphMetrics(font,'a',&minx,&maxx,&miny,&maxy,&advance);
- /* the width of each character tile */
- t_width = advance;
- /* the height of each character tile */
- t_height = TTF_FontHeight(font);
- /* position of the y=0 line in each tile */
- midline = TTF_FontAscent(font);
-
- /* now... render each of the individual characters */
- for (i=0;i<128;i++)
- {
- /* make a pretty blended glyph */
- temp_surf=TTF_RenderGlyph_Blended(font,i,base_color);
- /* and make sure that we got it right! */
- if (temp_surf == NULL)
- sdl_quit("Glyph failed to render!");
- /* get the metrics of this particular glyph so we can position it */
- TTF_GlyphMetrics(font,i,&minx,&maxx,&miny,&maxy,&advance);
- /* copy rendered glyph into text queue, at the right position*/
- tgt.x = minx;
- tgt.y = midline-maxy;
- /* but first... we'll need a surface in the text queue to blit to! */
- text[i] = createSurface(t_width,t_height);
- /* turn OFF src-alpha... results in brute
- copy of the RGBA contents of surf */
- SDL_SetAlpha(temp_surf,0,0);
- SDL_BlitSurface(temp_surf,NULL,text[i],&tgt);
- /* turn OFF src-alpha since we'll be using worksurf for blitting */
- SDL_SetAlpha(text[i],0,0);
- /* kill the surface to patch up memory leaks */
- SDL_FreeSurface(temp_surf);
- }
-}
-
-/* KEYPRESS_STRING repeatedly sends characters to the terminal
-XXX - should implement routine from maim-sdl.c, it's sooo much
-cleaner */
-#define KEYPRESS_STRING(str) \
-strcpy(buf,str); \
-n = buf; \
-while (*n != '\0') { \
- Term_keypress((int)(*(n++))); \
-}
-
-/* function prototype */
-void manipulationMode(void);
-void redrawAllTerminals(void);
-/* This is the main event handling routine that will be called
-whenever an event is pulled off of the queue (in Term_xtra_sdl())*/
-void handleEvent(SDL_Event *event)
-{
- static char buf[24]; /* a buffer used when passing key names */
- char *n; /* and a pointer to manipulate this buffer */
-
- switch( event->type )
- {
- case SDL_KEYDOWN:
- {
- /* handle key presses */
-
- /* I'm reading that as long as the upper 9 bits of the unicode
- * value are zero, then the lower 7 bits are direct ASCII characters.
- * Furthermore, it seems that all basic keys return non-zero values
- * for the lower 7 bits, but function keys and other various things
- * return 0000000 for the lower 7 bits.
- * Basically, if the lower 7 bits are zero, do something special
- * (like start a macro), but otherwise just pass along the ASCII
- * code!
- */
- byte ascii_part = event->key.keysym.unicode & 0x00ff;
-
- /* gimme the key name */
- printf("Key is: %s\n",SDL_GetKeyName(event->key.keysym.sym));
-
- /* allow for full screen toggling! */
- if ((event->key.keysym.sym == SDLK_RETURN) && \
- (SDL_GetModState() & KMOD_ALT))
- {
- SDL_WM_ToggleFullScreen(screen);
- /* toggle the internal full screen flag */
- arg_full_screen = (arg_full_screen ? FALSE : TRUE);
- }
-
- /* entry into window manipulation mode */
- if ((event->key.keysym.sym == SDLK_RETURN) && \
- (SDL_GetModState() & KMOD_CTRL))
- {
- DB("Manipulation mode!");
- manipulationMode();
- }
-
- /*printf("ascii_part: %d\n",ascii_part);*/
- if (ascii_part)
- {
- /* We have now determined that the ASCII part is not '0', so
- we can safely pass along the ASCII value! */
- Term_keypress(ascii_part);
- }
- else
- {
- /* We want to ignore keypresses that are simply the modifier
- keys*/
- if (!( (event->key.keysym.sym == SDLK_RSHIFT) |
- (event->key.keysym.sym == SDLK_LSHIFT) |
- (event->key.keysym.sym == SDLK_RALT) |
- (event->key.keysym.sym == SDLK_LALT) |
- (event->key.keysym.sym == SDLK_RCTRL) |
- (event->key.keysym.sym == SDLK_LCTRL) ))
- {
-
- /* now build a macro string using the modifiers together
- with the key that was just pressed*/
-
- /* As for the formatting...
- * We pass the key press and modifiers as follows:
- * \[ctrl-alt-shift-"key name"]
- * following the previously established convention...
- *
- * All of the things that happen are defined in pref-sdl.prf
- */
-
- KEYPRESS_STRING("\["); /*Output the first part... */
- /* See if a control key is down */
- if (event->key.keysym.mod & KMOD_CTRL)
- {
- KEYPRESS_STRING("ctrl-");
- }
- /* See if an alt key is down */
- if (event->key.keysym.mod & KMOD_ALT)
- {
- KEYPRESS_STRING("alt-");
- }
- /* See if a shift key is down */
- if (event->key.keysym.mod & KMOD_SHIFT)
- {
- KEYPRESS_STRING("shift-");
- }
-
- /* Add in the name of whatever key was pressed */
- KEYPRESS_STRING(SDL_GetKeyName(event->key.keysym.sym));
-
- /* and end it... */
- KEYPRESS_STRING("]");
- }
- }
- break;
- }
- case SDL_QUIT:
- {
- /* handle quit requests */
- DB("Emergency Blit");
- redrawAllTerminals();
- /*sdl_quit("Quitting!\n");*/
- break;
- }
- default:
- {
- break;
- }
- }
-}
-
-/* declare the screen clearing function used below */
-void eraseTerminal();
-void drawTermStuff(term_data *td, SDL_Rect *rect);
-static errr Term_xtra_sdl(int n, int v)
-{
- static SDL_Event event;
- term_data *td;
-
-
- /* Analyze */
- switch (n)
- {
- case TERM_XTRA_EVENT:
- {
- if (v)
- {
- /* Perform event checking with blocking */
- SDL_WaitEvent( &event );
- handleEvent( &event );
- } else {
- /* Perform event checking without blocking */
- if (SDL_PollEvent(&event)){
- /* We found an event! */
- handleEvent(&event);
- }
- }
- return(0);
- }
-
- case TERM_XTRA_FLUSH:
- {
- /* Keep doing events until the queue is empty! */
- while (SDL_PollEvent(&event))
- {
- handleEvent(&event);
- }
- return (0);
- }
-
- case TERM_XTRA_CLEAR:
- {
- /* Clear the terminal */
- DB("TERM_XTRA_CLEAR");
- suspendUpdate = TRUE;
- eraseTerminal();
- return (0);
- }
-
- case TERM_XTRA_SHAPE:
- {
- /*
- * Set the cursor visibility XXX XXX XXX
- *
- * This action should change the visibility of the cursor,
- * if possible, to the requested value (0=off, 1=on)
- *
- * This action is optional, but can improve both the
- * efficiency (and attractiveness) of the program.
- */
-
- return (0);
- }
-
- case TERM_XTRA_FRESH:
- {
- /*
- * Flush output XXX XXX XXX
- *
- * This action should make sure that all "output" to the
- * window will actually appear on the window.
- *
- * This action is optional, assuming that "Term_text_xxx()"
- * (and similar functions) draw directly to the screen.
- */
-
- /* If terminal display has been held for any reason,
- then update the whole thing now!*/
- DB("TERM_XTRA_FRESH");
- if (suspendUpdate)
- {
- DB(" update WAS suspended... updating now");
- td = (term_data*)(Term->data);
- suspendUpdate = FALSE;
- drawTermStuff(td,NULL);
- }
- return (0);
- }
-
- case TERM_XTRA_NOISE:
- {
- /*
- * Make a noise XXX XXX XXX
- *
- * This action should produce a "beep" noise.
- *
- * This action is optional, but convenient.
- */
-
- return (1);
- }
-
- case TERM_XTRA_BORED:
- {
- /* Perform event checking without blocking */
- if (SDL_PollEvent(&event)){
- /* We found an event! */
- handleEvent(&event);
- }
- return(0);
- }
-
- case TERM_XTRA_REACT:
- {
- /*
- * React to global changes XXX XXX XXX
- *
- * For example, this action can be used to react to
- * changes in the global "color_table[256][4]" array.
- *
- * This action is optional, but can be very useful for
- * handling "color changes" and the "arg_sound" and/or
- * "arg_graphics" options.
- */
- return (1);
- }
-
- case TERM_XTRA_ALIVE:
- {
- /*
- * Change the "hard" level XXX XXX XXX
- *
- * This action is used if the program changes "aliveness"
- * by being either "suspended" (v=0) or "resumed" (v=1)
- * This action is optional, unless the computer uses the
- * same "physical screen" for multiple programs, in which
- * case this action should clean up to let other programs
- * use the screen, or resume from such a cleaned up state.
- *
- * This action is currently only used by "main-gcu.c",
- * on UNIX machines, to allow proper "suspending".
- */
-
- return (1);
- }
-
- case TERM_XTRA_LEVEL:
- {
- /*
- * Change the "soft" level XXX XXX XXX
- *
- * This action is used when the term window changes "activation"
- * either by becoming "inactive" (v=0) or "active" (v=1)
- *
- * This action can be used to do things like activate the proper
- * font / drawing mode for the newly active term window. This
- * action should NOT change which window has the "focus", which
- * window is "raised", or anything like that.
- *
- * This action is optional if all the other things which depend
- * on what term is active handle activation themself, or if only
- * one "term_data" structure is supported by this file.
- */
-
- return (1);
- }
-
- }
-
- /* Unknown or Unhandled action */
- return (1);
-}
-
-/*************************************************
- GRAPHICS ROUTINES
- *************************************************/
-
-/* wrapper routine for creating an RGB surface with given height and
- width that corresponds to desired color depth and respects the system
- pixel format */
-SDL_Surface *createSurface(int width, int height)
-{
- SDL_Surface *surf;
- int surface_type;
-
- if (videoInfo->hw_available)
- surface_type = SDL_HWSURFACE;
- else
- surface_type = SDL_SWSURFACE;
-
- /* XXX need to make RGBA masks correspond to system pixel format! */
- switch (arg_bpp)
- {
- case 8:
- {
- /* I really don't know if 8 bpp is even possible, but here it is */
- surf = SDL_CreateRGBSurface(surface_type,width,\
- height,8,0xc0,0x30,0x0c,0x03);
- break;
- }
- case 16:
- {
- surf = SDL_CreateRGBSurface(surface_type,width,\
- height,16,0xf000,0x0f00,0x00f0,0x000f);
- break;
- }
- case 24:
- {
- surf = SDL_CreateRGBSurface(surface_type,width,\
- height,24,0xfc0000,0x03f000,0x000fc0,0x000030);
- break;
- }
- case 32:
- {
- surf = SDL_CreateRGBSurface(surface_type,width,\
- height,32,0xff000000,0x00ff0000,0x0000ff00,0x000000ff);
- break;
- }
- default:
- {
- surf = NULL;
- break;
- }
- }
-
- if (surf == NULL)
- sdl_quit("Bad Surface Creation!");
-
- return surf;
-}
-
-/* Take a rectangle in terminal coordinates and then transform it into
-screen coordinates; td is the term_data that this rect belongs to */
-void term_to_screen(SDL_Rect *termrect, term_data *td)
-{
- termrect->x += td->rect.x;
- termrect->y += td->rect.y;
-}
-
-/* Do the opposite, take a rectangle in screen coordinates and transform
-it into the terminal coordinates of the given term_data */
-void screen_to_term(SDL_Rect *scrrect, term_data *td)
-{
- scrrect->x -= td->rect.x;
- scrrect->y -= td->rect.y;
-}
-
-/* A macro that determines if the 'top' rectangle completely occludes the
-'bottom' rectangle */
-#define BLOCKS(top,bottom) \
-( (top.x <= bottom.x) & ((top.x+top.w)>=(bottom.x+bottom.w)) & \
- (top.y <= bottom.y) & ((top.y+top.h)>=(bottom.y+bottom.h)) )
-
-#define INTERSECT(r1,r2) \
-!( ( (r1.x > (r2.x+r2.w)) | (r2.x > (r1.x+r1.w)) ) & \
- ( (r1.y > (r2.y+r2.h)) | (r2.y > (r1.y+r1.h)) ) )
-
-/* A function to calculate the intersection of two rectangles. Takes base
-rectangle and then updates it to include only the rectangles that intersect
-with the test rectangle. If there is an intersection, the function returns
-TRUE and base now contains the intersecting rectangle. If there is no
-intersection, then the function returns FALSE */
-bool_ intersectRects(SDL_Rect *base, SDL_Rect *test)
-{
- if (INTERSECT((*base),(*test)))
- {
- /* Scoot the x-coordinates for the left side*/
- if ( test->x > base->x )
- {
- base->w -= test->x - base->x;
- base->x = test->x;
- }
- /* Scoot the x-coordinates for the right side*/
- if ( (test->x + test->w) < (base->x + base->w) )
- {
- base->w = test->x + test->w - base->x;
- }
- /* Scoot the upper y-coordinates */
- if ( test->y > base->y )
- {
- base->h -= test->y - base->y;
- base->y = test->y;
- }
- /* Scoot the lower y-coordinates */
- if ( (test->y + test->h) < (base->y + base->h) )
- {
- base->h = test->y + test->h - base->y;
- }
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-/* A function to calculate the join of two rectangles; the first argument is
-changed to the joined rectangle */
-SDL_Rect joinRects(SDL_Rect *r1, SDL_Rect *r2)
-{
- SDL_Rect out = {0,0,0,0};
-
- if ( (r1 != NULL) & (r2 != NULL) )
- {
- /* Lower x-coordinate */
- if ( r2->x < r1->x )
- out.x = r2->x;
- else
- out.x = r1->x;
- /* Upper x-coordinate */
- if ( (r2->x+r2->w) > (r1->x+r1->w) )
- out.w = (r2->x+r2->w) - out.x;
- else
- out.w = (r1->x+r1->w) - out.x;
- /* Lower y-coordinate */
- if ( r2->y < r1->y )
- out.y = r2->y;
- else
- out.y = r1->y;
- if ( (r2->y+r2->h) > (r1->y+r1->h) )
- out.h = (r2->y+r2->h) - out.y;
- else
- out.h = (r1->y+r1->h) - out.y;
- }
- return out;
-}
-
-/* Given a term_data (and its associated screen) and a rectangle in terminal
-coordinates (with NULL signifying to take the whole terminal surface), blit
-graphics from the term_data surface to the screen, using the term_data's rect
-to indicate how terminal coordinates transform into screen coordinates.
-This is complicated, however, by the possibility that the indicated area may be
-occluded by overlaying terminals. In this case, if the target area is
-completely occluded, nothing will be done. If partially occluded, it will be
-drawn, but occluding terminals will then re-blit to re-cover the area. */
-void drawTermStuff(term_data *td, SDL_Rect *rect)
-{
- int n = 0, i;
- bool_ block = FALSE, cover = FALSE;
- SDL_Rect spot, isect_term, isect_scr;
-
- /* first of all, if updating is suspended, do nothing! */
- if (!suspendUpdate)
- {
- /* find out which number in the ordered stack of screens that this
- terminal is */
- while ((term_order[n] != td) & (n < MAX_CONSOLE_COUNT))
- {
- n++;
- }
- if (n == MAX_CONSOLE_COUNT)
- printf("Could not find terminal in display list...\n");
- /* now loop through and see if any terminals completely occlude
- the desired spot; if num=0, note that this will be skipped */
- if (rect == NULL)
- {
- /* Grab the whole terminal screen */
- spot.x = 0; spot.y = 0;
- spot.w = td->surf->w; spot.h = td->surf->h;
- }
- else
- {
- /* Just copy the given area */
- spot.x = rect->x; spot.y = rect->y;
- spot.w = rect->w; spot.h = rect->h;
- }
- term_to_screen(&spot,td);
- i = n;
- while (i--)
- {
- if (BLOCKS(term_order[i]->rect,spot))
- {
- /* Higher terminal completely occludes this spot */
- block = TRUE;
- DB(" Blocks!");
- }
- else if (INTERSECT(term_order[i]->rect,spot))
- {
- /* Partial occlusion */
- cover = TRUE;
- DB(" Covers!");
- }
- }
- /* If any of the higher terminals blocked, then don't do
- anything */
- if (!block)
- {
- /*printf("Blitting to %d %d %d %d\n",spot.x,spot.y,spot.w,spot.h);*/
- /* First of all, draw the graphics */
- SDL_BlitSurface(td->surf,rect,screen,&spot);
- if (cover)
- {
- printf("covering...");
- /* There are covering terminals, so go through and blit all
- partially occluding ones */
- while (n--)
- {
- /* copy spot to find the intersect */
- isect_scr.x = spot.x; isect_scr.y = spot.y;
- isect_scr.w = spot.w; isect_scr.h = spot.h;
- if (intersectRects(&isect_scr,&(term_order[n]->rect)))
- {
- /* this terminal intersects... re-blit */
- /* first, convert to term coordinates */
- isect_term.x = isect_scr.x; isect_term.y = isect_scr.y;
- isect_term.w = isect_scr.w; isect_term.h = isect_scr.h;
- screen_to_term(&isect_term,term_order[n]);
- /* blit from term coordinates to screen coordinates */
- SDL_BlitSurface(term_order[n]->surf,&isect_term,\
- screen,&isect_scr);
- }
- }
- }
- /* Now update what was drawn */
- DB("Update");
- SDL_UpdateRects(screen,1,&spot);
- }
- }
-}
-
-/* utility routine for creating and setting the color of the cursor;
-it could be useful for setting a new cursor color if desired.
-Could later be expanded to do other stuff with the cursor,
-like a hollow rectangle a la main-win.c or even a graphic */
-void createCursor(byte r, byte g, byte b, byte a)
-{
- /* free the cursor if it exists */
- if (cursor != NULL)
- SDL_FreeSurface(cursor);
-
- /* and create it anew! (or the first time) */
- cursor = createSurface(t_width,t_height);
-
- /* be sure to use alpha channel when blitting! */
- SDL_SetAlpha(cursor,SDL_SRCALPHA,0);
-
- /* just set the color for now - drawing rectangles
- needs surface locking for some setups */
- cursor_color = SDL_MapRGBA(cursor->format,r,g,b,a);
- SDL_LOCK(cursor);
- SDL_FillRect(cursor,NULL,cursor_color);
- SDL_UNLOCK(cursor);
-}
-
-/* Cursor Display routine - just blits the global cursor
-surface onto the correct location */
-static errr Term_curs_sdl(int x, int y)
-{
- term_data *td = (term_data*)(Term->data);
- static SDL_Rect base;
-
- /* calculate the position to place the cursor */
- base.x = td->surf->clip_rect.x + x*t_width;
- base.y = td->surf->clip_rect.y + y*t_height;
- base.w = t_width;
- base.h = t_height;
-
- /* blit the cursor over top of the given spot;
- note that surface should not be locked
- (see note in Term_text_sdl() below) */
- SDL_BlitSurface(cursor,NULL,td->surf,&base);
-
- /* Now draw to the main screen */
- drawTermStuff(td,&base);
- /* Success */
- return (0);
-}
-
-/* Perform a full clear of active terminal; redraw the borders.*/
-void eraseTerminal(void)
-{
- static SDL_Rect base;
- term_data *td = (term_data*)(Term->data);
-
- /* temporarily remove clipping rectangle */
- SDL_SetClipRect(td->surf,NULL);
-
- SDL_LOCK(td->surf);
- /* flood terminal with border color */
- SDL_FillRect(td->surf,NULL,td->border_color);
-
- /* get smaller rectangle to hollow out window */
- base.x = td->border_thick;
- base.y = td->border_thick;
- base.w = td->rect.w - 2*td->border_thick;
- base.h = td->rect.h - 2*td->border_thick;
-
- /* hollow out terminal */
- SDL_FillRect(td->surf,&base,td->black);
-
- SDL_UNLOCK(screen);
-
- /* reset clipping rectangle */
- base.x += td->cushion_x_top;
- base.y += td->cushion_y_top;
- base.w -= td->cushion_x_top + td->cushion_x_bot;
- base.h -= td->cushion_y_top + td->cushion_y_bot;
- SDL_SetClipRect(td->surf,&base);
- printf("Clip rect: %d %d %d %d\n",base.x,base.y,base.w,base.h);
- /* And... UPDATE the whole thing */
- drawTermStuff(td,NULL);
-
-}
-
-/*
- * Draw some text on the screen
- *
- * This function should actually display an array of characters
- * starting at the given location, using the given "attribute",
- * and using the given string of characters, which contains
- * exactly "n" characters and which is NOT null-terminated.
- *
- * You may assume "valid" input if the window is properly sized.
- *
- * You must be sure that the string, when written, erases anything
- * (including any visual cursor) that used to be where the text is
- * drawn. On many machines this happens automatically, on others,
- * you must first call "Term_wipe_xxx()" to clear the area.
- *
- * In color environments, you should activate the color contained
- * in "color_data[a & 0x0F]", if needed, before drawing anything.
- *
- * You may ignore the "attribute" if you are only supporting a
- * monochrome environment, since this routine is normally never
- * called to display "black" (invisible) text, including the
- * default "spaces", and all other colors should be drawn in
- * the "normal" color in a monochrome environment.
- *
- * Note that if you have changed the "attr_blank" to something
- * which is not black, then this function must be able to draw
- * the resulting "blank" correctly.
- *
- */
-static errr Term_text_sdl(int x, int y, int n, byte a, const char *cp)
-{
- term_data *td = (term_data*)(Term->data);
- static SDL_Rect base;
- SDL_Rect base_back;
- int i = n;
- char old = 0;
-
- /* calculate place to clear off and draw to */
- base.x = td->surf->clip_rect.x + x*td->tile_width;
- base.y = td->surf->clip_rect.y + y*td->tile_height;
- base.w = n*td->tile_width;
- base.h = td->tile_height;
-
- base_back = base;
-
- SDL_LOCK(screen);
-
- /* blank the drawing area */
- SDL_FillRect(td->surf, &base, td->black);
-
- SDL_UNLOCK(screen);
-
- /* Note that SDL docs specify that SDL_BlitSurface should not be called
- on locked surfaces... since the character printing routine below revolves
- around blitting, the surface has been unlocked first*/
-
- /* loop through the input string, drawing characters */
- i = n;
- old = 0;
- while (i--)
- {
- /* Output the character... */
- /* If character has not changed, then just blit the old surface into
- the new location to save effort*/
- if (*cp == old)
- {
- /* the desired character/color combo is already on the work surf */
- /* just blit it! */
- SDL_BlitSurface(worksurf,NULL,td->surf,&base);
- } else {
- /* copy the desired character onto working surface */
- assert(*cp >= 0); // Make sure cast is valid
- SDL_BlitSurface(text[(size_t)(*cp)],NULL,worksurf,NULL);
- /* color our crayon surface with the desired color */
- SDL_FillRect(crayon,NULL,color_data[a&0x0f]);
- /* apply the color to the character on the working surface */
- SDL_BlitSurface(crayon,NULL,worksurf,NULL);
- /* and blit it onto our screen! */
- SDL_BlitSurface(worksurf,NULL,td->surf,&base);
- }
- /* Move to the next position */
- base.x += t_width;
- /* Store the old character */
- old = *cp;
- /* Increment the character pointer */
- cp++;
- }
-
- /* And update */
- drawTermStuff(td,&base_back);
-
- /* Success */
- return (0);
-}
-
-/*************************************************
- SPECIAL TERMINAL WINDOW MANIPULATION ROUTINES
- *************************************************/
-
-/* macro for bounding a value between two given values */
-#define BOUND(val,low,high) \
-if (val < low) \
-{ \
- val = low; \
-} \
-else if (val > high) \
-{ \
- val = high; \
-}
-
-/* two macros to get the adjusted maximums for window
-positions... eg the screen width minus the width of the
-window is the maximum x-position that the window can
-be set at. */
-#define MAX_X(td) \
-( arg_width - td->rect.w )
-
-#define MAX_Y(td) \
-( arg_height - td->rect.h )
-
-/* another two macros that give maximum window widths
-based on screen size and current window position together
-width tile widths/heights */
-#define MAX_WIDTH(td) \
-( (int)floorf((arg_width - td->rect.x - 2*td->border_thick - \
- td->cushion_x_bot - td->cushion_x_top )/td->tile_width))
-
-#define MAX_HEIGHT(td) \
-( (int)floorf((arg_height - td->rect.y - 2*td->border_thick - \
- td->cushion_y_bot - td->cushion_y_top )/td->tile_height))
-
-/* update the width and height of given term's rectangle by simply
-multiplying the tile count by tile size and adding in cushions and
-borders */
-#define UPDATE_SIZE(td) \
- td->rect.w = (td->cols)*td->tile_width + td->cushion_x_top \
- + td->cushion_x_bot + 2*td->border_thick; \
- td->rect.h = (td->rows)*td->tile_height + td->cushion_y_top \
- + td->cushion_y_bot + 2*td->border_thick
-
-void recompose(void);
-
-/* Resize the active terminal with new width and height.
-Note that his involves a complicated sequence of events...
-Details to follow below! */
-void resizeTerminal(int width, int height)
-{
- term_data *td = (term_data*)(Term->data);
-
- /* First of all, bound the input width and height to satisfy
- these conditions:
- - The main ToME window should be at least 80 cols, 24 rows
- - no part of each window should be drawn off screen....
- I'm including borders in this restriction!
- But no bounds checking needs to take place if the input width
- and height are unchanged....
- */
-
- if (td == &data[0])
- {
- /* The active terminal is the main ToME window...
- don't let the width get below 80, don't let the heights below
- 24, and don't let it leak off of the edge! */
- if (width != td->cols)
- {
- BOUND(width,80,MAX_WIDTH(td));
- }
- if (height != td->rows)
- {
- BOUND(height,24,MAX_HEIGHT(td));
- }
- }
- else
- {
- /* This is not the main window... just make sure it
- doesn't shrink to nothing or go past the edge */
- if (width != td->cols)
- {
- BOUND(width,1,MAX_WIDTH(td));
- }
- if (height != td->rows)
- {
- BOUND(height,1,MAX_HEIGHT(td));
- }
- }
-
- /* Okay, now make sure that something has ACTUALLY changed
- before doing anything */
- if ((width != td->cols) || (height != td->rows))
- {
-
- /* Now, ask zterm to please resize the term structure! */
- Term_resize(width,height);
-
- /* Reactivate, since Term_resize seems to activate the
- main window again...*/
- Term_activate(&td->t);
-
- /* It might not have resized completely to the new
- size we wanted (some windows have size limits it seems,
- like the message window). So, update our structure with
- the size that were actually obtained.*/
- td->cols = Term->wid;
- td->rows = Term->hgt;
-
- /* And recalculate the sizes */
- UPDATE_SIZE(td);
-
- /* Create a new surface that can hold the updated size */
- SDL_FreeSurface(td->surf);
- td->surf = createSurface(td->rect.w,td->rect.h);
-
- /* Now we should be in business for a complete redraw! */
- Term_redraw();
-
- /* Re-blit everything so it looks good */
- recompose();
-
- /* That's it! */
- }
-}
-
-/* Move the terminal around... a much simpler action that involves
-just changing the pos_x/pos_y values and redrawing!*/
-void moveTerminal(int x, int y)
-{
- term_data *td = (term_data*)(Term->data);
-
- /* Now, the window is being shifted about... much simpler
- situation to handle! But of course, the window must not
- drift too far or else parts will be hanging off the screen
- and may lead to errors - bound the input positions to
- prevent this unfortunate situation... do nothing if the
- input is no different than the current */
- if (x != td->rect.x)
- {
- BOUND(x,0,MAX_X(td));
- }
- if (y != td->rect.y)
- {
- BOUND(y,0,MAX_Y(td));
- }
-
- /* Okay, now make sure that something changed before doing
- anything */
- if ((x != td->rect.x) || (y != td->rect.y))
- {
- /* Now update OUR structure */
- td->rect.x = x;
- td->rect.y = y;
-
- /* Then do a reblit to see the results */
- recompose();
-
- /* That's it! */
- }
-}
-
-/* Routine to bring a given term_data to the top of the drawing stack */
-void bringToTop(int current)
-{
- term_data *td;
- int n = 0;
- int i;
-
- /* Get the pointer to the desired term_data from the data structure */
- td = &data[current];
-
- printf("Current stack: \n");
- for (i=0;i<arg_console_count;i++)
- {
- printf(" %d: %p\n",i,term_order[i]);
- }
- printf("\n");
-
- /* Find the number in the term_order stack */
- while ((term_order[n] != td) & (n < MAX_CONSOLE_COUNT))
- {
- n++;
- }
- if (n == MAX_CONSOLE_COUNT)
- printf("Could not find terminal in display list...\n");
-
- printf("Order is %d\n",n);
-
- /* Now move all lower-indexed pointers up one index */
- while (n)
- {
- printf(" move %d to %d\n",n-1,n);
- printf(" %p\n",term_order[n-1]);
- printf(" %p\n",term_order[n]);
- term_order[n] = term_order[n-1];
- n--;
- }
- /* And stick this term_data pointer on top */
- term_order[0] = td;
-
- printf("Final stack: \n");
- for (i=0;i<arg_console_count;i++)
- {
- printf(" %d: %p\n",i,term_order[i]);
- }
- printf("\n");
-
-}
-
-/* This utility routine will cycle the active term to the
-next available in the data[] array. It will then do a
-redraw of this term so that it is ready to be manipulated.
-The input is the current active terminal, and the output is
-the new active terminal */
-int cycleTerminal(int current)
-{
- /* redraw the current term to get rid of its purple
- border */
- data[current].border_color = data[current].white;
- Term_redraw();
-
- /* increment the terminal number*/
- current++;
- /* now do a little modulo cycle action and
- activate the next term! */
- current %= arg_console_count;
- Term_activate(&(data[current].t));
-
- /* before redrawing, set the border color to purple to
- indicate that this terminal is being manipulated*/
- data[current].border_color = data[current].purple;
-
- /* then bring this terminal to the top of the order, so it is drawn on
- top during manipulation mode */
- bringToTop(current);
-
- /* and do a complete redraw */
- Term_redraw();
-
- /* return the current terminal... */
- return current;
-}
-
-/* This routine will simply re-blit all of the surfaces onto the main screen,
-respecting the current term_order */
-void recompose(void)
-{
- int i = arg_console_count;
- /* do a complete screen wipe */
- SDL_LOCK(screen);
- SDL_FillRect(screen,NULL,screen_black);
- SDL_UNLOCK(screen);
-
- /* cycle through the term_order */
- while (i--)
- {
- SDL_BlitSurface(term_order[i]->surf,NULL,screen,&(term_order[i]->rect));
- }
-
- /* Update everything */
- SDL_REDRAW_SCREEN;
-}
-
-/* This utility routine will completely blank the screen and
-then cycle through all terminals, performing a Term_redraw()
-on each and every term that is being used (according to
-arg_term_count that is). The terminals will be redrawn
-last-to-first, so that the main is over top of everything */
-void redrawAllTerminals(void)
-{
- int i = arg_console_count;
- DB("Total redraw");
- /* do a complete screen wipe */
- SDL_LOCK(screen);
- SDL_FillRect(screen,NULL,screen_black);
- SDL_UNLOCK(screen);
-
- while (i--)
- {
- /* Re-order the terminals */
- term_order[i] = &data[i];
- }
-
- i = arg_console_count;
- /* cycle down through each terminal */
- while (i--)
- {
- /* Activate this terminal */
- Term_activate(&(data[i].t));
-
- /* Make its border white since manipulation mode is over */
- data[i].border_color = data[i].white;
-
- /* And redraw it */
- Term_redraw();
- }
- /* Loop will end on i=0 ! */
-
- printf("Current stack: \n");
- for (i=0;i<arg_console_count;i++)
- {
- printf(" %d: %p\n",i,term_order[i]);
- }
- printf("\n");
-
- /* now update the screen completely, just in case*/
- SDL_REDRAW_SCREEN;
-}
-
-/* This is the special event handling function for doing
-terminal window manipulation! When special manipulation
-mode is activated, execution goes here. This special mode
-has its own keypresses. To begin with, the main terminal
-border is highlighted (in purple) to indicate that it is
-being manipulated. The following keypresses are accepted:
--Space: switches between editing modes. The system begins
- in position editing mode, and Enter will toggle size
- (row/col) editing mode.
--Arrows: increments/decrements the position/size in an
- intuitive way! ;) Some modifiers are accepted in order
- to speed things up on very high resolution screens:
- . with shift down, increment is five
- . with ctrl down, increment is ten
- . with both, increment is fifty!
- Of course, no movement or resize can cause the window
- to leave the confines of the screen, so using the big
- jump is safe.
--Enter: cycles to the next available terminal to edit.
--Escape: quits manipulation mode, performing one final
- redraw to take into account all changes.
-*/
-void manipulationMode(void)
-{
- term_data *td;
- SDL_Event event;
- bool_ done = FALSE, moveMode = TRUE;
- int mouse_x, mouse_y;
- int value = 0, delta_x = 0, delta_y = 0;
- int current_term;
-
- /* Begin by redrawing the main terminal with its
- purple border to signify that it is being edited*/
-
- /* start with the main terminal */
- current_term = 0;
-
- /* get the pointer */
- td = &data[0];
-
- /* before redrawing, set the border color to purple to
- indicate that this terminal is being manipulated*/
- td->border_color = td->purple;
-
- /* and do a complete redraw */
- DB("Term_redraw");
- Term_redraw();
-
- /* Now keep looping until Esc has been pressed. */
- while (!done)
- {
- /* Get the keypress event */
- SDL_WaitEvent(&event);
- /* Make sure that it is a keypress */
- if (event.type == SDL_KEYDOWN)
- {
- /* Act on the keypress! */
- switch (event.key.keysym.sym)
- {
- case SDLK_ESCAPE:
- {
- /* Escape has been pressed, so we're done!*/
- done = TRUE;
- break;
- }
- case SDLK_SPACE:
- {
- /* Space has been pressed: toggle move mode */
- moveMode = ( moveMode ? FALSE : TRUE );
- break;
- }
- case SDLK_RETURN:
- {
- /* Return... cycle the terminals!
- update the current_term appropriately*/
- current_term = cycleTerminal(current_term);
-
- /* Get the new term_data */
- td = &data[current_term];
-
- break;
- }
- case SDLK_RIGHT:
- case SDLK_LEFT:
- case SDLK_DOWN:
- case SDLK_UP:
- {
- /* Increase either the x-position or column
- width - multiply according to modifiers */
- value = 1;
- if (SDL_GetModState() & KMOD_SHIFT)
- {
- /* shift is down... a muliplier of 5 */
- value *= 5;
- }
- if (SDL_GetModState() & KMOD_CTRL)
- {
- /* control is down... multiply by 10 */
- value *= 10;
- }
-
- /* Now, behavior depends on which key was pressed
- and whether we are in moveMode resize mode... */
-
- /* First, set the delta_x/y based on key */
- if (event.key.keysym.sym == SDLK_RIGHT)
- {
- delta_x = 1;
- delta_y = 0;
- }
- if (event.key.keysym.sym == SDLK_LEFT)
- {
- delta_x = -1;
- delta_y = 0;
- }
- if (event.key.keysym.sym == SDLK_DOWN)
- {
- delta_x = 0;
- delta_y = 1;
- }
- if (event.key.keysym.sym == SDLK_UP)
- {
- delta_x = 0;
- delta_y = -1;
- }
-
- /* Now either moveTerminal() or
- resizeTerminal() based on value of
- moveMode! */
- if (moveMode)
- {
- moveTerminal(td->rect.x + value*delta_x,\
- td->rect.y + value*delta_y);
- }
- else
- {
- resizeTerminal(td->cols + value*delta_x,\
- td->rows + value*delta_y);
- }
- break;
- }
- default:
- {
- break;
- }
- }
- }
- else if (event.type == SDL_MOUSEBUTTONDOWN)
- {
- /* Store the coordinates where the button was pressed */
- mouse_x = event.button.x;
- mouse_y = event.button.y;
- }
- else if (event.type == SDL_MOUSEMOTION)
- {
- /* Mouse is moving... maybe move or resize the window, based
- on the state of the mouse buttons */
-
- /* To keep the motion quick, temporarily ignore all mouse motion
- events until window moving is complete */
- SDL_EventState(SDL_MOUSEMOTION,SDL_IGNORE);
-
- if(event.motion.state & SDL_BUTTON(1))
- {
- /* the left mouse button is down, move the window,
- do a differential based on where the button was pressed */
- moveTerminal(td->rect.x + (event.motion.x - mouse_x), \
- td->rect.y + (event.motion.y - mouse_y));
- /* save the most current mouse location */
- SDL_GetMouseState(&mouse_x,&mouse_y);
- }
-
- if(event.motion.state & SDL_BUTTON(3))
- {
- /* the right mouse button is down, so resize the window;
- do a differential, but divide the number by the tile sizes */
-
- /* see if at least one whole tile width/height has been
- reached */
- int delta_cols, delta_rows;
- delta_cols = (int)floorf(\
- (float)(event.motion.x - mouse_x)/td->tile_width);
- delta_rows = (int)floorf(\
- (float)(event.motion.y - mouse_y)/td->tile_height);
- if ( delta_cols || delta_rows )
- {
- /* something changed, so update */
- resizeTerminal(td->cols + delta_cols, \
- td->rows + delta_rows);
- /* save the most current mouse location */
- SDL_GetMouseState(&mouse_x,&mouse_y);
- }
- }
-
- /* Deal with mouse motion again */
- SDL_EventState(SDL_MOUSEMOTION,SDL_ENABLE);
-
- }
- }
- /* Perform the last redraw to take all changes
- into account */
- redrawAllTerminals();
-}
-
-/*************************************************
- INITIALIZATION ROUTINES
- *************************************************/
-
-static errr term_data_init(term_data *td, int i)
-{
- term *t = &(td->t);
- char env_var[80];
- cptr val;
-
-
- /***** load position, size information */
-
- int cols, rows, x, y;
-
- /* grab the column and row counts from
- environmental variables for now */
- sprintf(env_var,"TOME_NUM_COLS_%d",i);
- val = getenv(env_var);
- /* make sure it is valid */
- if (val != NULL)
- {
- cols = atoi(val);
- /* now make sure that the main window will
- have at least 80x24 */
- if (td == &data[0])
- {
- /* can't really pick an upper bound without
- knowing what the position is... oh well. */
- BOUND(cols,80,255);
- }
- }
- else
- {
- /* no environmental variable... have to guess
- something. If it's the main window, choose
- the minimum. */
- if (td == &data[0])
- cols = 80;
- else
- cols = 5;
- }
- /* do the rows */
- sprintf(env_var,"TOME_NUM_ROWS_%d",i);
- val = getenv(env_var);
- /* make sure it is valid */
- if (val != NULL)
- {
- rows = atoi(val);
- /* now make sure that the main window will
- have at least 80x24 */
- if (td == &data[0])
- {
- /* can't really pick an upper bound without
- knowing what the position is... oh well. */
- BOUND(rows,24,128);
- }
- }
- else
- {
- /* no environmental variable... have to guess
- something. If it's the main window, choose
- the minimum. */
- if (td == &data[0])
- rows = 24;
- else
- rows = 3;
- }
- /* store these values in the term_data structure */
- td->rows = rows;
- td->cols = cols;
-
- /* the position will be loaded from environmental
- variables as well - for the time being*/
- /* x-location */
- sprintf(env_var,"TOME_X_POS_%d",i);
- val = getenv(env_var);
- /* make sure it is valid */
- if (val != NULL)
- {
- x = atoi(val);
- /* now do intelligent position checking */
- BOUND(x,0,MAX_X(td));
- }
- else
- {
- /* no variable, choose something */
- x = 20*i;
- }
- /* y-location */
- sprintf(env_var,"TOME_Y_POS_%d",i);
- val = getenv(env_var);
- /* make sure it is valid */
- if (val != NULL)
- {
- y = atoi(val);
- /* position checking again */
- BOUND(y,0,MAX_Y(td));
- }
- else
- {
- /* no variable */
- y = 20*i;
- }
- /* and store these values into the structure */
- td->rect.x = x;
- td->rect.y = y;
-
- /*********** term structure initializing */
-
- /* Initialize the term
- gets: pointer to address, number of columns, number of rows, number
- of keypresses to queue up (guess 24?)*/
- term_init(t, cols, rows, 24);
-
- /* Use a "soft" cursor */
- t->soft_cursor = TRUE;
-
- /* Hooks */
- t->xtra_hook = Term_xtra_sdl;
- t->curs_hook = Term_curs_sdl;
- t->text_hook = Term_text_sdl;
-
- /* Save the data */
- t->data = td;
-
- /* Activate (important) */
- Term_activate(t);
-
- /************* finish term_data intializing */
-
- /* name of this term window */
- td->name = angband_term_name[i];
-
- /* For now, all font is the same size... use global t_width/height */
- td->tile_width = t_width;
- td->tile_height = t_height;
-
- td->cushion_x_top = 1;
- td->cushion_x_bot = 1;
- td->cushion_y_top = 1;
- td->cushion_y_bot = 1;
-
- /* Now calculate the total width and height*/
- UPDATE_SIZE(td);
-
- /* Create a surface to draw to */
- td->surf = createSurface(td->rect.w,td->rect.h);
- SDL_SetAlpha(td->surf,0,0);
-
- /* Key some colors to this surface */
- td->black = SDL_MapRGB(td->surf->format, 0, 0, 0);
- td->white = SDL_MapRGB(td->surf->format,255,255,255);
- td->purple = SDL_MapRGB(td->surf->format,255, 0,255);
-
- /* Turn on a border, thickness specified by BORDER_THICKNESS */
- td->border_thick = BORDER_THICKNESS;
-
- /* make the default terminal border color to be white */
- td->border_color = td->white;
-
-
- printf("Init-int term: %d\n",i);
-
- /* Success */
- return (0);
-}
-
-/* dumpWindowSettings is responsible for exporting all current
-values of the window positions, etc. to the screen, so that
-the user can see what the final values were after tweaking */
-void dumpWindowSettings(void)
-{
- char name[80];
- char value[8];
- int i;
-
- DB("Dumping settings");
- printf("---------------------------\n");
- /* cycle through each available terminal */
- for (i=0; i<arg_console_count; i++)
- {
- printf("Terminal %d:\n",i);
- /* get the name, and value of each value to dump */
- sprintf(name,"TOME_X_POS_%d",i);
- sprintf(value,"%d",data[i].rect.x);
- printf("%s=%s\n",name,value);
-
- sprintf(name,"TOME_Y_POS_%d",i);
- sprintf(value,"%d",data[i].rect.y);
- printf("%s=%s\n",name,value);
-
- sprintf(name,"TOME_NUM_COLS_%d",i);
- sprintf(value,"%d",data[i].cols);
- printf("%s=%s\n",name,value);
-
- sprintf(name,"TOME_NUM_ROWS_%d",i);
- sprintf(value,"%d",data[i].rows);
- printf("%s=%s\n",name,value);
-
- /* Simple! */
- printf("\n");
- }
-}
-
-/* The main-sdl initialization routine!
-This routine processes arguments, opens the SDL
-window, loads fonts, etc. */
-int init_sdl(int argc, char **argv)
-{
- int i;
- char filename[PATH_MAX + 1];
- const char file_sep = '.';
- /* Flags to pass to SDL_SetVideoMode */
- int videoFlags;
-
- /* Before sdl_quit could possible be called, need to make sure that the text
- array is zeroed, so that sdl_quit->killFontAndAlphabet() doesn't try to free
- SDL_Surfaces that don't exist ! */
- memset(text,0,sizeof(text));
-
- /* Also, clear out the term order array */
- memset(term_order,0,sizeof(term_order));
-
- /* initialize SDL */
- if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
- {
- sdl_quit("Video initialization failed!");
- }
- DB("SDL Initialized!");
-
- /* get video info, to be used for determining if hardware acceleration is
- available, pixel format, etc.... */
- videoInfo = SDL_GetVideoInfo();
-
- /* Environment calls to retrieve specific settings...
- Note that these can be overridden by the command-line
- arguments that are handled below */
- if(getenv("TOME_CONSOLE_COUNT"))
- arg_console_count = atoi(getenv("TOME_CONSOLE_COUNT"));
- if(getenv("TOME_SCREEN_WIDTH"))
- arg_width = atoi(getenv("TOME_SCREEN_WIDTH"));
- if(getenv("TOME_SCREEN_HEIGHT"))
- arg_height = atoi(getenv("TOME_SCREEN_HEIGHT"));
- if(getenv("TOME_SCREEN_BPP"))
- arg_bpp = atoi(getenv("TOME_SCREEN_BPP"));
- if(getenv("TOME_FONT_SIZE"))
- arg_font_size = atoi(getenv("TOME_FONT_SIZE"));
-
- /* Argument handling routine;
- the argv pointer is already pointing at the '--'
- argument, so just start from there, parsing each
- option as it comes along */
- for (i=1; i < argc ; i++)
- {
- /* Set the number of consoles to handle
- (ie the number of windows) */
- if (0 == strcmp(argv[i], "-n"))
- {
- if (++i == argc)
- {
- printf("Argument missing for option -n\n");
- return -1;
- }
-
- arg_console_count = atoi(argv[i]);
- if (arg_console_count <= 0 || \
- arg_console_count > MAX_CONSOLE_COUNT)
- {
- printf("Invalid console count given.\n");
- arg_console_count = 1;
- }
- }
- /* Set the SDL window/screen width in pixels */
- else if (0 == strcmp(argv[i], "-w"))
- {
- if (++i == argc)
- {
- printf("Argument missing for option -w\n");
- return -1;
- }
-
- arg_width = atoi(argv[i]);
- }
- /* Set the SDL window/screen height in pixels */
- else if (0 == strcmp(argv[i], "-h"))
- {
- if (++i == argc)
- {
- printf("Argument missing for option -h\n");
- return -1;
- }
-
- arg_height = atoi(argv[i]);
- }
- /* Set the SDL window/screen color depth
- (in bits per pixel -- only 8,16,32 are okay) */
- else if (0 == strcmp(argv[i], "-bpp"))
- {
- if (++i == argc)
- {
- printf("Argument missing for option -bpp\n");
- return -1;
- }
-
- arg_bpp = atoi(argv[i]);
- if ( (arg_bpp != 8) && (arg_bpp != 16) \
- && (arg_bpp != 24) && (arg_bpp != 32) )
- {
- printf("Invalid color depth. Must be either 8, 16, or 32 bpp!\n");
- return -1;
- }
- }
- /* switch into full-screen at startup */
- else if (0 == strcmp(argv[i], "-fs"))
- {
- DB("Full-screen enabled!");
- arg_full_screen = TRUE;
- }
- /* change the font size */
- else if (0 == strcmp(argv[i], "-s"))
- {
- if (++i == argc)
- {
- printf("Argument missing for option -s\n");
- printf("Please specify font size!\n");
- return -1;
- }
-
- arg_font_size = atoi(argv[i]);
- }
- /* change the font to use */
- else if (0 == strcmp(argv[i], "-f"))
- {
- /* Can we please not be so MS Windows-specific? One of the main goals
- of SDL in ToME was to be more portable. These file name hacks are
- only the idiom of that one OS, though. -- Neil */
- DB("Getting font name");
- if (++i == argc)
- {
- printf("Argument missing for option -f\n");
- printf("Please specify a true-type font found in /lib/xtra/font!\n");
- return -1;
- }
-
- /* tokenize the font name so that no .ttf extension
- is required */
- strcpy(arg_font_name,\
- strtok(argv[i],&file_sep));
-
- /* and append the extension */
- strcat(arg_font_name,".ttf");
-
- /* print a little debug message, so
- user sees what font was actually selected */
- printf("\tUsing font: %s\n",arg_font_name);
-
- /* maybe check to see if file is even
- existant in /lib/xtra/font */
- }
-
- } /* end argument handling */
-
- /* Make sure that the engine will shutdown SDL properly*/
- quit_aux = sdl_quit;
-
- /* Use the ToME logo and set the window name */
- filename[PATH_MAX] = 0;
- path_build(filename, PATH_MAX, ANGBAND_DIR_XTRA, "graf/icon.png");
- SDL_WM_SetIcon(IMG_Load(filename), 0);
- SDL_WM_SetCaption("ToME", "tome");
-
- /* SDL video settings, dependent on whether hardware is available */
- if (videoInfo->hw_available)
- videoFlags = SDL_HWSURFACE;
- else
- videoFlags = SDL_SWSURFACE;
-
- /* now set the video mode that has been configured */
- screen = SDL_SetVideoMode( arg_width, arg_height, arg_bpp, videoFlags );
-
- /* Verify there is a surface */
- if ( !screen )
- {
- DB("No screen!");
- sdl_quit("Failed to set SDL Surface.");
- }
-
- DB("Video Mode Set!");
-
- /* now switch into full screen if asked for */
- if (arg_full_screen)
- SDL_WM_ToggleFullScreen(screen);
-
- DB("SDL Window Created!");
-
- /* Now ready the fonts! */
-
- DB("initializing SDL_ttf");
- if(TTF_Init()==-1) {
- printf("TTF_Init: %s\n", TTF_GetError());
- sdl_quit("Bah");
- }
-
- DB("loading font...");
-
- /* load and render the font */
- loadAndRenderFont(arg_font_name,arg_font_size);
-
- /* Initialize the working surface and crayon surface used for rendering
- text in different colors. */
-
- worksurf = createSurface(t_width,t_height);
- crayon = createSurface(t_width,t_height);
-
- /* The working surface will blit using alpha values... */
- SDL_SetAlpha(worksurf,SDL_SRCALPHA,0);
-
- /* Set up the colors using the great little color macros! */
- color_data[0] = BLACK;
- color_data[1] = WHITE;
- color_data[2] = MID_GREY;
- color_data[3] = BRIGHT_ORANGE;
- color_data[4] = RED;
- color_data[5] = GREEN;
- color_data[6] = BRIGHT_BLUE;
- color_data[7] = DARK_ORANGE;
- color_data[8] = DARK_GREY;
- color_data[9] = BRIGHT_GREY;
- color_data[10] = PURPLE;
- color_data[11] = YELLOW;
- color_data[12] = BRIGHT_RED;
- color_data[13] = BRIGHT_GREEN;
- color_data[14] = AQUAMARINE;
- color_data[15] = BROWN;
-
- /* And setup the cursor, using the default color...
- XXX - in the future, this should (and will) be loaded from prefs */
- createCursor(DEF_CURSOR_COLOR);
-
- /* Initialize the windows, or whatever that means in this case.
- Do this in reverse order so that the main window is on top.*/
- suspendUpdate = TRUE; /* draw everything at the end */
- i = arg_console_count;
- while (i--)
- {
- term_data *td = &data[i];
-
- /* Initialize the term_data */
- term_data_init(td, i);
-
- /* Save global entry */
- angband_term[i] = Term;
-
- /* Add into term_order */
- term_order[i] = td;
-
- }
-
- /* And setup the basic screen colors -- these are keyed to the format of
- the main terminal surface */
- screen_black = SDL_MapRGB(screen->format, 0, 0, 0);
-
- suspendUpdate = FALSE; /* now draw everything */
- redrawAllTerminals();
- /*SDL_REDRAW_SCREEN;*/
-
- /* now that the windows have been set, their settings can
- be dumped upon quit! */
- window_properties_set = TRUE;
-
- /* Enable UNICODE keysyms - needed for current eventHandling routine */
- SDL_EnableUNICODE(1);
-
- /* Enable key repeat! */
- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL);
-
- /* main-sdl initialized! */
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- return main_real(
- argc,
- argv,
- "sdl",
- init_sdl,
- " -- -n # Number of virtual consoles to use\n"
- " -- -w # Request screen width in pixels\n"
- " -- -h # Request screen height in pixels\n"
- " -- -bpp # Request screen color depth in bits\n"
- " -- -fs Start with full-screen display\n"
- " -- -s # Request font size\n"
- " -- -f <font> Request true-type font by name\n");
-}
diff --git a/src/main-win.c b/src/main-win.cc
index 54336a37..0bfcfcab 100644
--- a/src/main-win.c
+++ b/src/main-win.cc
@@ -68,11 +68,31 @@
#include "angband.h"
-#include "dungeon.h"
+#include "config.h"
+#include "defines.h"
#include "files.h"
-#include "init2.h"
+#include "h-basic.hpp"
#include "util.h"
#include "variable.h"
+#include "z-form.h"
+#include "z-term.hpp"
+#include "z-util.h"
+
+/*
+ * Determine if string "t" is a suffix of string "s"
+ */
+static bool suffix(const char *s, const char *t)
+{
+ int tlen = strlen(t);
+ int slen = strlen(s);
+
+ /* Check for incompatible lengths */
+ if (tlen > slen) return false;
+
+ /* Compare "t" to the end of "s" */
+ return !strcmp(s + slen - tlen, t);
+}
+
/*
* Extract the "WIN32" flag from the compiler
@@ -316,48 +336,48 @@ typedef struct _term_data term_data;
*/
struct _term_data
{
- term t;
+ term *term_ptr;
- cptr s;
+ const char *s;
HWND w;
DWORD dwStyle;
DWORD dwExStyle;
- uint keys;
+ unsigned int keys;
- uint rows;
- uint cols;
+ unsigned int rows;
+ unsigned int cols;
- uint pos_x;
- uint pos_y;
- uint size_wid;
- uint size_hgt;
- uint size_ow1;
- uint size_oh1;
- uint size_ow2;
- uint size_oh2;
+ unsigned int pos_x;
+ unsigned int pos_y;
+ unsigned int size_wid;
+ unsigned int size_hgt;
+ unsigned int size_ow1;
+ unsigned int size_oh1;
+ unsigned int size_ow2;
+ unsigned int size_oh2;
- bool_ size_hack;
+ bool size_hack;
- bool_ xtra_hack;
+ bool xtra_hack;
- bool_ visible;
+ bool visible;
- bool_ bizarre;
+ bool bizarre;
- cptr font_want;
+ const char *font_want;
- cptr font_file;
+ const char *font_file;
HFONT font_id;
- uint font_wid;
- uint font_hgt;
+ unsigned int font_wid;
+ unsigned int font_hgt;
- uint tile_wid;
- uint tile_hgt;
+ unsigned int tile_wid;
+ unsigned int tile_hgt;
};
@@ -379,22 +399,22 @@ static term_data *my_td;
/*
* game in progress
*/
-bool_ game_in_progress = FALSE;
+bool game_in_progress = false;
/*
* note when "open"/"new" become valid
*/
-bool_ initialized = FALSE;
+bool initialized = false;
/*
* screen paletted, i.e. 256 colors
*/
-bool_ paletted = FALSE;
+bool paletted = false;
/*
* 16 colors screen, don't use RGB()
*/
-bool_ colors16 = FALSE;
+bool colors16 = false;
/*
* Saved instance handle
@@ -434,24 +454,24 @@ static HWND hwndSaver;
/*
* Full path to ANGBAND.INI
*/
-static cptr ini_file = NULL;
+static const char *ini_file = NULL;
/*
* Name of application
*/
-static cptr AppName = "ANGBAND";
+static const char *AppName = "ANGBAND";
/*
* Name of sub-window type
*/
-static cptr AngList = "AngList";
+static const char *AngList = "AngList";
/*
* Directory names
*/
-static cptr ANGBAND_DIR_XTRA_FONT;
-static cptr ANGBAND_DIR_XTRA_GRAF;
-static cptr ANGBAND_DIR_XTRA_HELP;
+static const char *ANGBAND_DIR_XTRA_FONT;
+static const char *ANGBAND_DIR_XTRA_GRAF;
+static const char *ANGBAND_DIR_XTRA_HELP;
/*
@@ -493,8 +513,8 @@ static BYTE win_pal[256] =
/*
* Hack -- define which keys are "special"
*/
-static bool_ special_key[256];
-static bool_ ignore_key[256];
+static bool special_key[256];
+static bool ignore_key[256];
/*
* Hack -- initialization list for "special_key"
@@ -525,9 +545,9 @@ static byte ignore_key_list[] = {
/*
* Hack -- given a pathname, point at the filename
*/
-static cptr extract_file_name(cptr s)
+static const char *extract_file_name(const char *s)
{
- cptr p;
+ const char *p;
/* Start at the end */
p = s + strlen(s) - 1;
@@ -588,7 +608,7 @@ static char *analyze_font(char *path, int *wp, int *hp)
/*
* Check for existance of a file
*/
-static bool_ check_file(cptr s)
+static bool check_file(const char *s)
{
char path[1024];
@@ -611,33 +631,33 @@ static bool_ check_file(cptr s)
attrib = GetFileAttributes(path);
/* Require valid filename */
- if (attrib == INVALID_FILE_NAME) return (FALSE);
+ if (attrib == INVALID_FILE_NAME) return false;
/* Prohibit directory */
- if (attrib & FILE_ATTRIBUTE_DIRECTORY) return (FALSE);
+ if (attrib & FILE_ATTRIBUTE_DIRECTORY) return false;
#else /* WIN32 */
/* Examine and verify */
- if (_dos_getfileattr(path, &attrib)) return (FALSE);
+ if (_dos_getfileattr(path, &attrib)) return false;
/* Prohibit something */
- if (attrib & FA_LABEL) return (FALSE);
+ if (attrib & FA_LABEL) return false;
/* Prohibit directory */
- if (attrib & FA_DIREC) return (FALSE);
+ if (attrib & FA_DIREC) return false;
#endif /* WIN32 */
/* Success */
- return (TRUE);
+ return true;
}
/*
* Check for existance of a directory
*/
-static bool_ check_dir(cptr s)
+static bool check_dir(const char *s)
{
int i;
@@ -668,33 +688,33 @@ static bool_ check_dir(cptr s)
attrib = GetFileAttributes(path);
/* Require valid filename */
- if (attrib == INVALID_FILE_NAME) return (FALSE);
+ if (attrib == INVALID_FILE_NAME) return false;
/* Require directory */
- if (!(attrib & FILE_ATTRIBUTE_DIRECTORY)) return (FALSE);
+ if (!(attrib & FILE_ATTRIBUTE_DIRECTORY)) return false;
#else /* WIN32 */
/* Examine and verify */
- if (_dos_getfileattr(path, &attrib)) return (FALSE);
+ if (_dos_getfileattr(path, &attrib)) return false;
/* Prohibit something */
- if (attrib & FA_LABEL) return (FALSE);
+ if (attrib & FA_LABEL) return false;
/* Require directory */
- if (!(attrib & FA_DIREC)) return (FALSE);
+ if (!(attrib & FA_DIREC)) return false;
#endif /* WIN32 */
/* Success */
- return (TRUE);
+ return true;
}
/*
* Validate a file
*/
-static void validate_file(cptr s)
+static void validate_file(const char *s)
{
/* Verify or fail */
if (!check_file(s))
@@ -707,7 +727,7 @@ static void validate_file(cptr s)
/*
* Validate a directory
*/
-static void validate_dir(cptr s)
+static void validate_dir(const char *s)
{
/* Verify or fail */
if (!check_dir(s))
@@ -763,7 +783,7 @@ static void term_getsize(term_data *td)
/* rc.bottom += 1; */
/* Adjust */
- AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);
+ AdjustWindowRectEx(&rc, td->dwStyle, true, td->dwExStyle);
/* Total size */
td->size_wid = rc.right - rc.left;
@@ -784,7 +804,7 @@ static void term_getsize(term_data *td)
/*
* Write the "prefs" for a single term
*/
-static void save_prefs_aux(term_data *td, cptr sec_name)
+static void save_prefs_aux(term_data *td, const char *sec_name)
{
char buf[1024];
@@ -860,7 +880,7 @@ static void save_prefs(void)
/*
* Load the "prefs" for a single term
*/
-static void load_prefs_aux(term_data *td, cptr sec_name)
+static void load_prefs_aux(term_data *td, const char *sec_name)
{
char tmp[1024];
@@ -920,7 +940,7 @@ static void load_prefs(void)
*
* This function is never called before all windows are ready.
*
- * This function returns FALSE if the new palette could not be
+ * This function returns false if the new palette could not be
* prepared, which should normally be a fatal error. XXX XXX
*
* Note that only some machines actually use a "palette".
@@ -940,7 +960,7 @@ static int new_palette(void)
/* This makes no sense */
- if (!paletted) return (TRUE);
+ if (!paletted) return true;
/* No palette */
@@ -1033,7 +1053,7 @@ static int new_palette(void)
hPal = hNewPal;
/* Success */
- return (TRUE);
+ return true;
}
@@ -1052,7 +1072,7 @@ static void term_window_resize(term_data *td)
SWP_NOMOVE | SWP_NOZORDER);
/* Redraw later */
- InvalidateRect(td->w, NULL, TRUE);
+ InvalidateRect(td->w, NULL, true);
}
@@ -1066,7 +1086,7 @@ static void term_window_resize(term_data *td)
*
* Note that the "font name" must be capitalized!!!
*/
-static errr term_force_font(term_data *td, cptr path)
+static errr term_force_font(term_data *td, const char *path)
{
int i;
@@ -1083,7 +1103,7 @@ static errr term_force_font(term_data *td, cptr path)
/* Forget old font */
if (td->font_file)
{
- bool_ used = FALSE;
+ bool used = false;
/* Scan windows */
for (i = 0; i < MAX_TERM_DATA; i++)
@@ -1091,9 +1111,9 @@ static errr term_force_font(term_data *td, cptr path)
/* Check "screen" */
if ((td != &data[i]) &&
(data[i].font_file) &&
- (streq(data[i].font_file, td->font_file)))
+ (strcmp(data[i].font_file, td->font_file) == 0))
{
- used = TRUE;
+ used = true;
}
}
@@ -1204,7 +1224,7 @@ static void term_change_font(term_data *td)
}
/* Assume not bizarre */
- td->bizarre = FALSE;
+ td->bizarre = false;
/* Reset the tile info */
td->tile_wid = td->font_wid;
@@ -1226,13 +1246,13 @@ static void term_change_font(term_data *td)
static void term_data_redraw(term_data *td)
{
/* Activate the term */
- Term_activate(&td->t);
+ Term_activate(td->term_ptr);
/* Redraw the contents */
Term_redraw();
/* Restore the term */
- Term_activate(term_screen);
+ Term_activate(angband_term[0]);
}
@@ -1245,7 +1265,7 @@ static void term_data_redraw(term_data *td)
/*
* React to global changes
*/
-static errr Term_xtra_win_react(void)
+static void Term_xtra_win_react(void)
{
int i;
@@ -1268,7 +1288,7 @@ static errr Term_xtra_win_react(void)
byte rv, gv, bv;
- bool_ change = FALSE;
+ bool change = false;
/* Save the default colors */
for (i = 0; i < 256; i++)
@@ -1285,7 +1305,7 @@ static errr Term_xtra_win_react(void)
if (win_clr[i] != code)
{
/* Note the change */
- change = TRUE;
+ change = true;
/* Apply the desired color */
win_clr[i] = code;
@@ -1308,11 +1328,15 @@ static errr Term_xtra_win_react(void)
term_data *td = &data[i];
+ int wid;
+ int hgt;
+ term_get_size(td->term_ptr, &wid, &hgt);
+
/* Update resized windows */
- if ((td->cols != td->t.wid) || (td->rows != td->t.hgt))
+ if ((td->cols != wid) || (td->rows != hgt))
{
/* Activate */
- Term_activate(&td->t);
+ Term_activate(&td->term_ptr);
/* Hack -- Resize the term */
Term_resize(td->cols, td->rows);
@@ -1324,17 +1348,13 @@ static errr Term_xtra_win_react(void)
Term_activate(old);
}
}
-
-
- /* Success */
- return (0);
}
/*
* Process at least one event
*/
-static errr Term_xtra_win_event(int v)
+static void Term_xtra_win_event(int v)
{
MSG msg;
@@ -1359,16 +1379,13 @@ static errr Term_xtra_win_event(int v)
DispatchMessage(&msg);
}
}
-
- /* Success */
- return 0;
}
/*
* Process all pending events
*/
-static errr Term_xtra_win_flush(void)
+static void Term_xtra_win_flush(void)
{
MSG msg;
@@ -1378,9 +1395,6 @@ static errr Term_xtra_win_flush(void)
TranslateMessage(&msg);
DispatchMessage(&msg);
}
-
- /* Success */
- return (0);
}
@@ -1389,10 +1403,8 @@ static errr Term_xtra_win_flush(void)
*
* Make this more efficient XXX XXX XXX
*/
-static errr Term_xtra_win_clear(void)
+static void Term_xtra_win_clear(term_data *td, void)
{
- term_data *td = (term_data*)(Term->data);
-
HDC hdc;
RECT rc;
@@ -1408,26 +1420,22 @@ static errr Term_xtra_win_clear(void)
SelectObject(hdc, td->font_id);
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
ReleaseDC(td->w, hdc);
-
- /* Success */
- return 0;
}
/*
* Hack -- make a noise
*/
-static errr Term_xtra_win_noise(void)
+static void Term_xtra_win_noise(void)
{
MessageBeep(MB_ICONASTERISK);
- return (0);
}
/*
* Delay for "x" milliseconds
*/
-static int Term_xtra_win_delay(int v)
+static void Term_xtra_win_delay(int v)
{
#ifdef WIN32
@@ -1455,9 +1463,6 @@ static int Term_xtra_win_delay(int v)
}
#endif /* WIN32 */
-
- /* Success */
- return (0);
}
/*
@@ -1471,60 +1476,69 @@ HWND get_main_hwnd()
/*
* Do a "special thing"
*/
-static errr Term_xtra_win(int n, int v)
+static void Term_xtra_win(void *data, int n, int v)
{
+ term_data *td = (term_data*) data;
+
/* Handle a subset of the legal requests */
switch (n)
{
/* Make a bell sound */
case TERM_XTRA_NOISE:
{
- return (Term_xtra_win_noise());
+ Term_xtra_win_noise();
+ return;
}
/* Process random events */
case TERM_XTRA_BORED:
{
- return (Term_xtra_win_event(0));
+ Term_xtra_win_event(0);
+ return;
}
/* Process an event */
case TERM_XTRA_EVENT:
{
- return (Term_xtra_win_event(v));
+ Term_xtra_win_event(v);
+ return;
}
/* Flush all events */
case TERM_XTRA_FLUSH:
{
- return (Term_xtra_win_flush());
+ Term_xtra_win_flush();
+ return;
}
/* Clear the screen */
case TERM_XTRA_CLEAR:
{
- return (Term_xtra_win_clear());
+ Term_xtra_win_clear(td);
+ return;
}
/* React to global changes */
case TERM_XTRA_REACT:
{
- return (Term_xtra_win_react());
+ Term_xtra_win_react();
+ return;
}
/* Delay for some milliseconds */
case TERM_XTRA_DELAY:
{
- return (Term_xtra_win_delay(v));
+ Term_xtra_win_delay(v);
+ return;
}
/* Rename main window */
case TERM_XTRA_RENAME_MAIN_WIN:
- SetWindowText(get_main_hwnd(), angband_term_name[0]); return (0);
+ {
+ SetWindowText(get_main_hwnd(), angband_term_name[0]);
+ return;
+ }
}
-
- /* Oops */
- return 1;
}
@@ -1534,9 +1548,9 @@ static errr Term_xtra_win(int n, int v)
*
* Draw a "cursor" at (x,y), using a "yellow box".
*/
-static errr Term_curs_win(int x, int y)
+static void Term_curs_win(void *data, int x, int y)
{
- term_data *td = (term_data*)(Term->data);
+ term_data *td = (term_data*) data;
RECT rc;
HDC hdc;
@@ -1551,9 +1565,6 @@ static errr Term_curs_win(int x, int y)
hdc = GetDC(data[0].w);
FrameRect(hdc, &rc, hbrYellow);
ReleaseDC(data[0].w, hdc);
-
- /* Success */
- return 0;
}
@@ -1568,9 +1579,9 @@ static errr Term_curs_win(int x, int y)
* what color it should be using to draw with, but perhaps simply changing
* it every time is not too inefficient. XXX XXX XXX
*/
-static errr Term_text_win(int x, int y, int n, byte a, const char *s)
+static void Term_text_win(void *data, int x, int y, int n, byte a, const char *s)
{
- term_data *td = (term_data*)(Term->data);
+ term_data *td = (term_data*) data;
RECT rc;
HDC hdc;
@@ -1643,9 +1654,6 @@ static errr Term_text_win(int x, int y, int n, byte a, const char *s)
/* Release DC */
ReleaseDC(td->w, hdc);
-
- /* Success */
- return 0;
}
@@ -1658,21 +1666,19 @@ static errr Term_text_win(int x, int y, int n, byte a, const char *s)
*/
static void term_data_link(term_data *td)
{
- term *t = &td->t;
+ /* Hooks */
+ struct term_ui_hooks_t ui_hooks = {
+ NULL /* init */,
+ NULL /* nuke */,
+ Term_xtra_win,
+ Term_curs_win,
+ Term_text_win,
+ };
/* Initialize the term */
- term_init(t, td->cols, td->rows, td->keys);
-
- /* Use a "software" cursor */
- t->soft_cursor = TRUE;
-
- /* Prepare the template hooks */
- t->xtra_hook = Term_xtra_win;
- t->curs_hook = Term_curs_win;
- t->text_hook = Term_text_win;
-
- /* Remember where we came from */
- t->data = (vptr)(td);
+ td->term_ptr = term_init(td, td->cols, td->rows, td->keys);
+ term_init_soft_cursor(td->term_ptr);
+ term_init_ui_hooks(td->term_ptr, ui_hooks);
}
@@ -1701,7 +1707,7 @@ static void init_windows(void)
td->keys = 1024;
td->rows = 24;
td->cols = 80;
- td->visible = TRUE;
+ td->visible = true;
td->size_ow1 = 2;
td->size_ow2 = 2;
td->size_oh1 = 2;
@@ -1718,7 +1724,7 @@ static void init_windows(void)
td->keys = 16;
td->rows = 24;
td->cols = 80;
- td->visible = FALSE;
+ td->visible = false;
td->size_ow1 = 1;
td->size_ow2 = 1;
td->size_oh1 = 1;
@@ -1738,7 +1744,7 @@ static void init_windows(void)
WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION |
WS_VISIBLE);
td->dwExStyle = 0;
- td->visible = TRUE;
+ td->visible = true;
/* Sub windows (need these before term_getsize gets called) */
for (i = 1; i < MAX_TERM_DATA; i++)
@@ -1771,7 +1777,7 @@ static void init_windows(void)
td->tile_hgt = 13;
/* Assume not bizarre */
- td->bizarre = FALSE;
+ td->bizarre = false;
}
/* Analyze the font */
@@ -1798,13 +1804,13 @@ static void init_windows(void)
if (td->visible)
{
- td->size_hack = TRUE;
+ td->size_hack = true;
ShowWindow(td->w, SW_SHOW);
- td->size_hack = FALSE;
+ td->size_hack = false;
}
term_data_link(td);
- angband_term[i] = &td->t;
+ angband_term[i] = td->term_ptr;
if (td->visible)
{
@@ -1831,7 +1837,7 @@ static void init_windows(void)
if (!td->w) quit("Failed to create Angband window");
term_data_link(td);
- angband_term[0] = &td->t;
+ angband_term[0] = td->term_ptr;
/* Activate the main window */
SetActiveWindow(td->w);
@@ -2060,7 +2066,7 @@ static void check_for_save_file(LPSTR cmd_line)
validate_file(savefile);
/* Game in progress */
- game_in_progress = TRUE;
+ game_in_progress = true;
/* Play game */
play_game();
@@ -2094,7 +2100,7 @@ static void process_menus(WORD wCmd)
}
else
{
- game_in_progress = TRUE;
+ game_in_progress = true;
Term_flush();
play_game();
quit(NULL);
@@ -2133,7 +2139,7 @@ ofn.lStructSize = sizeof(OPENFILENAME);
{
/* Load 'savefile' */
validate_file(savefile);
- game_in_progress = TRUE;
+ game_in_progress = true;
Term_flush();
play_game();
quit(NULL);
@@ -2155,7 +2161,7 @@ ofn.lStructSize = sizeof(OPENFILENAME);
}
/* Hack -- Forget messages */
- msg_flag = FALSE;
+ msg_flag = false;
/* Save the game */
do_cmd_save_game();
@@ -2180,7 +2186,7 @@ ofn.lStructSize = sizeof(OPENFILENAME);
}
/* Hack -- Forget messages */
- msg_flag = FALSE;
+ msg_flag = false;
/* Save the game */
do_cmd_save_game();
@@ -2222,13 +2228,13 @@ ofn.lStructSize = sizeof(OPENFILENAME);
if (!td->visible)
{
- td->visible = TRUE;
+ td->visible = true;
ShowWindow(td->w, SW_SHOW);
term_data_redraw(td);
}
else
{
- td->visible = FALSE;
+ td->visible = false;
ShowWindow(td->w, SW_HIDE);
}
@@ -2469,7 +2475,7 @@ LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
rc.bottom = rc.top + 2 * td->tile_hgt + td->size_oh1 + td->size_oh2 + 1;
/* Adjust */
- AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);
+ AdjustWindowRectEx(&rc, td->dwStyle, true, td->dwExStyle);
/* Save minimum size */
lpmmi->ptMinTrackSize.x = rc.right - rc.left;
@@ -2485,7 +2491,7 @@ LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
rc.bottom += (td->tile_hgt - 1);
/* Adjust */
- AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);
+ AdjustWindowRectEx(&rc, td->dwStyle, true, td->dwExStyle);
/* Save maximum size */
lpmmi->ptMaxSize.x = rc.right - rc.left;
@@ -2513,14 +2519,14 @@ LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
/* Unused */
/* BYTE KeyState = 0x00; */
- bool_ mc = FALSE;
- bool_ ms = FALSE;
- bool_ ma = FALSE;
+ bool mc = false;
+ bool ms = false;
+ bool ma = false;
/* Extract the modifiers */
- if (GetKeyState(VK_CONTROL) & 0x8000) mc = TRUE;
- if (GetKeyState(VK_SHIFT) & 0x8000) ms = TRUE;
- if (GetKeyState(VK_MENU) & 0x8000) ma = TRUE;
+ if (GetKeyState(VK_CONTROL) & 0x8000) mc = true;
+ if (GetKeyState(VK_SHIFT) & 0x8000) ms = true;
+ if (GetKeyState(VK_MENU) & 0x8000) ma = true;
/* Handle "special" keys */
if (special_key[(byte)(wParam)] || (ma && !ignore_key[(byte)(wParam)]) )
@@ -2569,7 +2575,7 @@ LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
if (game_in_progress && character_generated)
{
/* Hack -- Forget messages */
- msg_flag = FALSE;
+ msg_flag = false;
/* Save the game */
do_cmd_save_game();
@@ -2620,8 +2626,8 @@ LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
case SIZE_RESTORED:
{
- uint cols = (LOWORD(lParam) - td->size_ow1 - td->size_ow2) / td->tile_wid;
- uint rows = (HIWORD(lParam) - td->size_oh1 - td->size_oh2) / td->tile_hgt;
+ unsigned int cols = (LOWORD(lParam) - td->size_ow1 - td->size_ow2) / td->tile_wid;
+ unsigned int rows = (HIWORD(lParam) - td->size_oh1 - td->size_oh2) / td->tile_hgt;
/* New size */
if ((td->cols != cols) || (td->rows != rows))
@@ -2631,16 +2637,16 @@ LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
td->rows = rows;
/* Activate */
- Term_activate(&td->t);
+ Term_activate(td->term_ptr);
/* Resize the term */
Term_resize(td->cols, td->rows);
/* Redraw later */
- InvalidateRect(td->w, NULL, TRUE);
+ InvalidateRect(td->w, NULL, true);
}
- td->size_hack = TRUE;
+ td->size_hack = true;
/* Restore sub-windows */
for (i = 1; i < MAX_TERM_DATA; i++)
@@ -2648,7 +2654,7 @@ LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
if (data[i].visible) ShowWindow(data[i].w, SW_SHOWNOACTIVATE);
}
- td->size_hack = FALSE;
+ td->size_hack = false;
return 0;
}
@@ -2670,12 +2676,12 @@ LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
hdc = GetDC(hWnd);
- SelectPalette(hdc, hPal, FALSE);
+ SelectPalette(hdc, hPal, false);
i = RealizePalette(hdc);
/* if any palette entries changed, repaint the window. */
- if (i) InvalidateRect(hWnd, NULL, TRUE);
+ if (i) InvalidateRect(hWnd, NULL, true);
ReleaseDC(hWnd, hdc);
@@ -2750,7 +2756,7 @@ LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
rc.bottom = rc.top + 2 * td->tile_hgt + td->size_oh1 + td->size_oh2;
/* Adjust */
- AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);
+ AdjustWindowRectEx(&rc, td->dwStyle, true, td->dwExStyle);
/* Save the minimum size */
lpmmi->ptMinTrackSize.x = rc.right - rc.left;
@@ -2766,7 +2772,7 @@ LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
rc.bottom += (td->tile_hgt - 1);
/* Adjust */
- AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);
+ AdjustWindowRectEx(&rc, td->dwStyle, true, td->dwExStyle);
/* Save maximum size */
lpmmi->ptMaxSize.x = rc.right - rc.left;
@@ -2790,16 +2796,16 @@ LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
/* was sent from inside WM_SIZE */
if (td->size_hack) return 1;
- td->size_hack = TRUE;
+ td->size_hack = true;
td->cols = (LOWORD(lParam) - td->size_ow1 - td->size_ow2) / td->tile_wid;
td->rows = (HIWORD(lParam) - td->size_oh1 - td->size_oh2) / td->tile_hgt;
term_getsize(td);
- MoveWindow(hWnd, td->pos_x, td->pos_y, td->size_wid, td->size_hgt, TRUE);
+ MoveWindow(hWnd, td->pos_x, td->pos_y, td->size_wid, td->size_hgt, true);
- td->size_hack = FALSE;
+ td->size_hack = false;
return 0;
}
@@ -2818,14 +2824,14 @@ LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
/* Unused */
/* BYTE KeyState = 0x00; */
- bool_ mc = FALSE;
- bool_ ms = FALSE;
- bool_ ma = FALSE;
+ bool mc = false;
+ bool ms = false;
+ bool ma = false;
/* Extract the modifiers */
- if (GetKeyState(VK_CONTROL) & 0x8000) mc = TRUE;
- if (GetKeyState(VK_SHIFT) & 0x8000) ms = TRUE;
- if (GetKeyState(VK_MENU) & 0x8000) ma = TRUE;
+ if (GetKeyState(VK_CONTROL) & 0x8000) mc = true;
+ if (GetKeyState(VK_SHIFT) & 0x8000) ms = true;
+ if (GetKeyState(VK_MENU) & 0x8000) ma = true;
/* Handle "special" keys */
if (special_key[(byte)(wParam)] || (ma && !ignore_key[(byte)(wParam)]) )
@@ -2866,7 +2872,7 @@ LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
case WM_PALETTECHANGED:
{
/* ignore if palette change caused by itself */
- if ((HWND)wParam == hWnd) return FALSE;
+ if ((HWND)wParam == hWnd) return false;
/* otherwise, fall through!!! */
}
@@ -2874,10 +2880,10 @@ LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
{
if (!paletted) return 0;
hdc = GetDC(hWnd);
- SelectPalette(hdc, hPal, FALSE);
+ SelectPalette(hdc, hPal, false);
i = RealizePalette(hdc);
/* if any palette entries changed, repaint the window. */
- if (i) InvalidateRect(hWnd, NULL, TRUE);
+ if (i) InvalidateRect(hWnd, NULL, true);
ReleaseDC(hWnd, hdc);
return 0;
}
@@ -2893,7 +2899,7 @@ LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
{
if (td->visible)
{
- td->visible = FALSE;
+ td->visible = false;
ShowWindow(td->w, SW_HIDE);
}
@@ -2994,7 +3000,7 @@ WPARAM wParam, LPARAM lParam)
/*
* Display warning message (see "z-util.c")
*/
-static void hack_plog(cptr str)
+static void hack_plog(const char *str)
{
/* Give a warning */
if (str)
@@ -3008,7 +3014,7 @@ static void hack_plog(cptr str)
/*
* Display error message and quit (see "z-util.c")
*/
-static void hack_quit(cptr str)
+static void hack_quit(const char *str)
{
/* Give a warning */
if (str)
@@ -3035,7 +3041,7 @@ static void hack_quit(cptr str)
/*
* Display warning message (see "z-util.c")
*/
-static void hook_plog(cptr str)
+static void hook_plog(const char *str)
{
/* Warning */
if (str)
@@ -3049,7 +3055,7 @@ static void hook_plog(cptr str)
/*
* Display error message and quit (see "z-util.c")
*/
-static void hook_quit(cptr str)
+static void hook_quit(const char *str)
{
int i;
@@ -3245,13 +3251,13 @@ int FAR PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
/* Initialize the keypress analyzer */
for (i = 0; special_key_list[i]; ++i)
{
- special_key[special_key_list[i]] = TRUE;
+ special_key[special_key_list[i]] = true;
}
/* Determine if display is 16/256/true color */
hdc = GetDC(NULL);
colors16 = (GetDeviceCaps(hdc, BITSPIXEL) == 4);
- paletted = ((GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) ? TRUE : FALSE);
+ paletted = ((GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) ? true : false);
ReleaseDC(NULL, hdc);
/* Initialize the colors */
@@ -3317,12 +3323,12 @@ int FAR PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
inkey();
/* We are now initialized */
- initialized = TRUE;
+ initialized = true;
/* Did the user double click on a save file? */
check_for_save_file(lpCmdLine);
- game_in_progress = TRUE;
+ game_in_progress = true;
play_game();
/* Prompt the user */
@@ -3337,7 +3343,7 @@ int FAR PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
/* Initialize the keypress analyzer */
for (i = 0; ignore_key_list[i]; ++i)
{
- ignore_key[ignore_key_list[i]] = TRUE;
+ ignore_key[ignore_key_list[i]] = true;
}
/* Paranoia */
diff --git a/src/main-x11.c b/src/main-x11.cc
index 19d2ac94..4650923e 100644
--- a/src/main-x11.c
+++ b/src/main-x11.cc
@@ -92,10 +92,15 @@
*
*/
-#include "loadsave.h"
-#include "main.h"
-#include "util.h"
-#include "variable.h"
+#include "config.hpp"
+#include "defines.hpp"
+#include "frontend.hpp"
+#include "loadsave.hpp"
+#include "main.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+#include "z-form.hpp"
+#include "z-util.hpp"
#ifndef __MAKEDEPEND__
#include <X11/Xlib.h>
@@ -109,10 +114,15 @@
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
-#include <limits.h>
+#include <climits>
#include <sys/time.h>
+#include <boost/algorithm/string/predicate.hpp>
+using boost::algorithm::equals;
+using boost::algorithm::starts_with;
+
+#define FORCELOWER(A) ((isupper((A))) ? tolower((A)) : (A))
/*
* This file is designed to be "included" by "main-x11.c" or "main-xaw.c",
@@ -270,9 +280,9 @@ struct metadpy
int fd;
- uint width;
- uint height;
- uint depth;
+ unsigned int width;
+ unsigned int height;
+ unsigned int depth;
Pixell black;
Pixell white;
@@ -281,11 +291,11 @@ struct metadpy
Pixell fg;
Pixell zg;
-uint mono:
+unsigned int mono:
1;
-uint color:
+unsigned int color:
1;
-uint nuke:
+unsigned int nuke:
1;
};
@@ -330,23 +340,23 @@ struct infowin
byte byte1;
-uint mapped:
+unsigned int mapped:
1;
-uint redraw:
+unsigned int redraw:
1;
-uint resize:
+unsigned int resize:
1;
-uint nuke:
+unsigned int nuke:
1;
-uint flag1:
+unsigned int flag1:
1;
-uint flag2:
+unsigned int flag2:
1;
-uint flag3:
+unsigned int flag3:
1;
-uint flag4:
+unsigned int flag4:
1;
};
@@ -374,12 +384,8 @@ struct infoclr
Pixell fg;
Pixell bg;
-uint code:
- 4;
-uint stip:
- 1;
-uint nuke:
- 1;
+ unsigned int code: 4;
+ unsigned int nuke: 1;
};
@@ -404,7 +410,7 @@ struct infofnt
{
XFontStruct *info;
- cptr name;
+ const char *name;
s16b wid;
s16b twid;
@@ -413,85 +419,14 @@ struct infofnt
byte off;
-uint mono:
+unsigned int mono:
1;
-uint nuke:
+unsigned int nuke:
1;
};
-
-/**** Generic Macros ****/
-
-
-
-/* Set current metadpy (Metadpy) to 'M' */
-#define Metadpy_set(M) \
-Metadpy = M
-
-
-/* Initialize 'M' using Display 'D' */
-#define Metadpy_init_dpy(D) \
-Metadpy_init_2(D,cNULL)
-
-/* Initialize 'M' using a Display named 'N' */
-#define Metadpy_init_name(N) \
-Metadpy_init_2((Display*)(NULL),N)
-
-/* Initialize 'M' using the standard Display */
-#define Metadpy_init() \
-Metadpy_init_name("")
-
-
-/* Init an infowin by giving father as an (info_win*) (or NULL), and data */
-#define Infowin_init_dad(D,X,Y,W,H,B,FG,BG) \
-Infowin_init_data(((D) ? ((D)->win) : (Window)(None)), \
-X,Y,W,H,B,FG,BG)
-
-
-/* Init a top level infowin by pos,size,bord,Colors */
-#define Infowin_init_top(X,Y,W,H,B,FG,BG) \
-Infowin_init_data(None,X,Y,W,H,B,FG,BG)
-
-
-/* Request a new standard window by giving Dad infowin and X,Y,W,H */
-#define Infowin_init_std(D,X,Y,W,H,B) \
-Infowin_init_dad(D,X,Y,W,H,B,Metadpy->fg,Metadpy->bg)
-
-
-/* Set the current Infowin */
-#define Infowin_set(I) \
-(Infowin = (I))
-
-
-/* Set the current Infoclr */
-#define Infoclr_set(C) \
-(Infoclr = (C))
-
-
-#define Infoclr_init_ppo(F,B,O,M) \
-Infoclr_init_data(F,B,O,M)
-
-#define Infoclr_init_ppn(F,B,O,M) \
-Infoclr_init_ppo(F,B,Infoclr_Opcode(O),M)
-
-
-/* Set the current infofnt */
-#define Infofnt_set(I) \
-(Infofnt = (I))
-
-
-/* Errr: Expose Infowin */
-#define Infowin_expose() \
-(!(Infowin->redraw = 1))
-
-/* Errr: Unxpose Infowin */
-#define Infowin_unexpose() \
-(Infowin->redraw = 0)
-
-
-
/**** Generic Globals ****/
@@ -505,9 +440,6 @@ static metadpy metadpy_default;
* The "current" variables
*/
static metadpy *Metadpy = &metadpy_default;
-static infowin *Infowin = (infowin*)(NULL);
-static infoclr *Infoclr = (infoclr*)(NULL);
-static infofnt *Infofnt = (infofnt*)(NULL);
/**** Generic code ****/
@@ -529,105 +461,28 @@ int x_io_error_handler(Display *d)
}
/*
- * Calculate how much space there is in the key queue for the current term.
- */
-int Term_queue_space(void)
-{
- /* Find the gap if the tail is before the head. */
- int space = Term->key_tail - Term->key_head;
-
- /* Otherwise, add in the extra for looping. */
- if (space <= 0) space = Term->key_size - space;
-
- /* The last space is never used as that would be interpreted as leaving
- * no pending keypresses. */
- return space -1;
-}
-
-
-/*
- * Add a series of keypresses to the "queue".
- *
- * Return any errors generated by Term_keypress() in doing so, or SUCCESS
- * if there are none.
- *
- * Catch the "out of space" error before anything is printed.
- *
- * NB: The keys added here will be interpreted by any macros or keymaps.
- */
-static errr type_string(char *str, uint len)
-{
- char *s;
-
- term *old = Term;
-
- /* Paranoia - no string. */
- if (!str) return 5;
-
- /* Hack - calculate the string length here if none given. */
- if (!len) len = strlen(str);
-
- /* Activate the main window, as all pastes go there. */
- Term_activate(term_screen);
-
- /* Not enough space for the string. */
- if (Term_queue_space() <= (int)len)
- return 7;
-
- for (s = str; s < str + len; s++)
- {
- errr err = Term_keypress(*s);
-
- /* Catch errors other than "str[i] == 0", which is ignored. */
- if (err && err != -1) return err;
- }
-
- /* Activate the original window. */
- Term_activate(old);
-
- return 0;
-}
-
-
-/*
- * Init the current metadpy, with various initialization stuff.
+ * Create a new metadpy and initialize it.
*
* Inputs:
- * dpy: The Display* to use (if NULL, create it)
- * name: The name of the Display (if NULL, the current)
+ * name: The name of the Display
*
* Notes:
* If 'name' is NULL, but 'dpy' is set, extract name from dpy
* If 'dpy' is NULL, then Create the named Display
* If 'name' is NULL, and so is 'dpy', use current Display
*
- * Return -1 if no Display given, and none can be opened.
+ * Return -1 on error.
*/
-static errr Metadpy_init_2(Display *dpy, cptr name)
+static errr Metadpy_new(const char *name)
{
metadpy *m = Metadpy;
- /*** Open the display if needed ***/
+ /*** Create the display ***/
- /* If no Display given, attempt to Create one */
- if (!dpy)
- {
- /* Attempt to open the display */
- dpy = XOpenDisplay(name);
-
- /* Failure */
- if (!dpy) return ( -1);
+ Display *dpy = XOpenDisplay(name);
+ if (!dpy) return ( -1);
- /* We will have to nuke it when done */
- m->nuke = 1;
- }
-
- /* Since the Display was given, use it */
- else
- {
- /* We will not have to nuke it when done */
- m->nuke = 0;
- }
+ m->nuke = 1;
XSetIOErrorHandler(x_io_error_handler);
@@ -677,57 +532,37 @@ static errr Metadpy_init_2(Display *dpy, cptr name)
/*
- * General Flush/ Sync/ Discard routine
- */
-static errr Metadpy_update(int flush, int sync, int discard)
-{
- /* Flush if desired */
- if (flush) XFlush(Metadpy->dpy);
-
- /* Sync if desired, using 'discard' */
- if (sync) XSync(Metadpy->dpy, discard);
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Make a simple beep
+ * Set the name (in the title bar) of Infowin
*/
-static errr Metadpy_do_beep(void)
+static void Infowin_set_name(infowin *iwin, std::string_view name_sv)
{
- /* Make a simple beep */
- XBell(Metadpy->dpy, 100);
+ char buf[128];
- return (0);
-}
+ // Trim to the size of the buffer - 1 so that
+ // strncpy is guaranteed to NUL-terminate.
+ auto name = name_sv.substr(0, sizeof(buf) - 1);
+ // Copy
+ strncpy(buf, name.begin(), name.size());
+ buf[name.size()] = '\0';
+ char *bp = buf;
-/*
- * Set the name (in the title bar) of Infowin
- */
-static errr Infowin_set_name(cptr name)
-{
- Status st;
+ // Set
XTextProperty tp;
- char buf[128];
- char *bp = buf;
- strcpy(buf, name);
- st = XStringListToTextProperty(&bp, 1, &tp);
- if (st) XSetWMName(Metadpy->dpy, Infowin->win, &tp);
- return (0);
+ Status st = XStringListToTextProperty(&bp, 1, &tp);
+ if (st)
+ {
+ XSetWMName(Metadpy->dpy, iwin->win, &tp);
+ }
}
/*
* Prepare a new 'infowin'.
*/
-static errr Infowin_prepare(Window xid)
+static errr Infowin_prepare(infowin *iwin, Window xid)
{
- infowin *iwin = Infowin;
-
Window tmp_win;
XWindowAttributes xwa;
int x, y;
@@ -773,13 +608,13 @@ static errr Infowin_prepare(Window xid)
* Notes:
* If 'dad == None' assume 'dad == root'
*/
-static errr Infowin_init_data(Window dad, int x, int y, int w, int h,
+static errr Infowin_init_data(infowin *iwin, Window dad, int x, int y, int w, int h,
int b, Pixell fg, Pixell bg)
{
Window xid;
/* Wipe it clean */
- memset(Infowin, 0, sizeof(struct infowin));
+ memset(iwin, 0, sizeof(struct infowin));
/*** Error Check XXX ***/
@@ -815,10 +650,10 @@ static errr Infowin_init_data(Window dad, int x, int y, int w, int h,
/*** Prepare the new infowin ***/
/* Mark it as nukable */
- Infowin->nuke = 1;
+ iwin->nuke = 1;
/* Attempt to Initialize the infowin */
- return (Infowin_prepare(xid));
+ return Infowin_prepare(iwin, xid);
}
@@ -826,132 +661,58 @@ static errr Infowin_init_data(Window dad, int x, int y, int w, int h,
/*
* Modify the event mask of an Infowin
*/
-static errr Infowin_set_mask(long mask)
+static void Infowin_set_mask(infowin *iwin, long mask)
{
/* Save the new setting */
- Infowin->mask = mask;
+ iwin->mask = mask;
/* Execute the Mapping */
- XSelectInput(Metadpy->dpy, Infowin->win, Infowin->mask);
-
- /* Success */
- return (0);
+ XSelectInput(Metadpy->dpy, iwin->win, iwin->mask);
}
/*
* Request that Infowin be mapped
*/
-static errr Infowin_map(void)
+static void Infowin_map(infowin *iwin)
{
/* Execute the Mapping */
- XMapWindow(Metadpy->dpy, Infowin->win);
-
- /* Success */
- return (0);
+ XMapWindow(Metadpy->dpy, iwin->win);
}
/*
* Request that Infowin be raised
*/
-static errr Infowin_raise(void)
+static void Infowin_raise(infowin *iwin)
{
/* Raise towards visibility */
- XRaiseWindow(Metadpy->dpy, Infowin->win);
-
- /* Success */
- return (0);
+ XRaiseWindow(Metadpy->dpy, iwin->win);
}
/*
* Request that Infowin be moved to a new location
*/
-static errr Infowin_impell(int x, int y)
+static void Infowin_impell(infowin *iwin, int x, int y)
{
- /* Execute the request */
- XMoveWindow(Metadpy->dpy, Infowin->win, x, y);
-
- /* Success */
- return (0);
+ XMoveWindow(Metadpy->dpy, iwin->win, x, y);
}
/*
* Visually clear Infowin
*/
-static errr Infowin_wipe(void)
+static void Infowin_wipe(infowin *iwin)
{
- /* Execute the request */
- XClearWindow(Metadpy->dpy, Infowin->win);
-
- /* Success */
- return (0);
+ XClearWindow(Metadpy->dpy, iwin->win);
}
-
/*
- * A NULL terminated pair list of legal "operation names"
- *
- * Pairs of values, first is texttual name, second is the string
- * holding the decimal value that the operation corresponds to.
+ * Opcodes for Infoclr_init_data().
*/
-static cptr opcode_pairs[] =
-{
- "cpy", "3",
- "xor", "6",
- "and", "1",
- "ior", "7",
- "nor", "8",
- "inv", "10",
- "clr", "0",
- "set", "15",
-
- "src", "3",
- "dst", "5",
-
- "+andReverse", "2",
- "+andInverted", "4",
- "+noop", "5",
- "+equiv", "9",
- "+orReverse", "11",
- "+copyInverted", "12",
- "+orInverted", "13",
- "+nand", "14",
- NULL
-};
-
-
-/*
- * Parse a word into an operation "code"
- *
- * Inputs:
- * str: A string, hopefully representing an Operation
- *
- * Output:
- * 0-15: if 'str' is a valid Operation
- * -1: if 'str' could not be parsed
- */
-static int Infoclr_Opcode(cptr str)
-{
- register int i;
-
- /* Scan through all legal operation names */
- for (i = 0; opcode_pairs[i*2]; ++i)
- {
- /* Is this the right oprname? */
- if (streq(opcode_pairs[i*2], str))
- {
- /* Convert the second element in the pair into a Code */
- return (atoi(opcode_pairs[i*2 + 1]));
- }
- }
-
- /* The code was not found, return -1 */
- return ( -1);
-}
-
+static constexpr int Infoclr_Opcode_CPY = 3;
+static constexpr int Infoclr_Opcode_XOR = 6;
/*
* Initialize an infoclr with some data
@@ -962,10 +723,8 @@ static int Infoclr_Opcode(cptr str)
* op: The Opcode for the requested Operation (see above)
* stip: The stipple mode
*/
-static errr Infoclr_init_data(Pixell fg, Pixell bg, int op, int stip)
+static errr Infoclr_init_data(infoclr *iclr, Pixell fg, Pixell bg, int op)
{
- infoclr *iclr = Infoclr;
-
GC gc;
XGCValues gcv;
unsigned long gc_mask;
@@ -994,11 +753,14 @@ static errr Infoclr_init_data(Pixell fg, Pixell bg, int op, int stip)
gcv.foreground = fg;
/* Hack -- Handle XOR (xor is code 6) by hacking bg and fg */
- if (op == 6) gcv.background = 0;
- if (op == 6) gcv.foreground = (bg ^ fg);
+ if (op == Infoclr_Opcode_XOR)
+ {
+ gcv.background = 0;
+ gcv.foreground = (bg ^ fg);
+ }
/* Assign the proper GC Fill Style */
- gcv.fill_style = (stip ? FillStippled : FillSolid);
+ gcv.fill_style = FillSolid;
/* Turn off 'Give exposure events for pixmap copying' */
gcv.graphics_exposures = False;
@@ -1026,7 +788,6 @@ static errr Infoclr_init_data(Pixell fg, Pixell bg, int op, int stip)
iclr->fg = fg;
iclr->bg = bg;
iclr->code = op;
- iclr->stip = stip ? 1 : 0;
/* Success */
return (0);
@@ -1040,11 +801,8 @@ static errr Infoclr_init_data(Pixell fg, Pixell bg, int op, int stip)
* Inputs:
* fg: The Pixell for the requested Foreground (see above)
*/
-static errr Infoclr_change_fg(Pixell fg)
+static errr Infoclr_change_fg(infoclr *iclr, Pixell fg)
{
- infoclr *iclr = Infoclr;
-
-
/*** Simple error checking of opr and clr ***/
/* Check the 'Pixells' for realism */
@@ -1065,17 +823,13 @@ static errr Infoclr_change_fg(Pixell fg)
/*
* Prepare a new 'infofnt'
*/
-static errr Infofnt_prepare(XFontStruct *info)
+static errr Infofnt_prepare(infofnt *ifnt, XFontStruct *info)
{
- infofnt *ifnt = Infofnt;
-
- XCharStruct *cs;
-
/* Assign the struct */
ifnt->info = info;
/* Jump into the max bouonds thing */
- cs = &(info->max_bounds);
+ auto cs = &(info->max_bounds);
/* Extract default sizing info */
ifnt->asc = info->ascent;
@@ -1094,7 +848,7 @@ static errr Infofnt_prepare(XFontStruct *info)
* Inputs:
* name: The name of the requested Font
*/
-static errr Infofnt_init_data(cptr name)
+static errr Infofnt_init_data(infofnt *ifnt, const char *name)
{
XFontStruct *info;
@@ -1114,10 +868,10 @@ static errr Infofnt_init_data(cptr name)
/*** Init the font ***/
/* Wipe the thing */
- memset(Infofnt, 0, sizeof(struct infofnt));
+ memset(ifnt, 0, sizeof(struct infofnt));
/* Attempt to prepare it */
- if (Infofnt_prepare(info))
+ if (Infofnt_prepare(ifnt, info))
{
/* Free the font */
XFreeFont(Metadpy->dpy, info);
@@ -1127,10 +881,10 @@ static errr Infofnt_init_data(cptr name)
}
/* Save a copy of the font name */
- Infofnt->name = strdup(name);
+ ifnt->name = strdup(name);
/* Mark it as nukable */
- Infofnt->nuke = 1;
+ ifnt->nuke = 1;
/* Success */
return (0);
@@ -1140,15 +894,15 @@ static errr Infofnt_init_data(cptr name)
/*
* Standard Text
*/
-static errr Infofnt_text_std(int x, int y, cptr str, int len)
+static void Infofnt_text_std(infowin *iwin, infoclr *iclr, infofnt *ifnt, int x, int y, const char *str, int len)
{
- int i;
-
-
/*** Do a brief info analysis ***/
/* Do nothing if the string is null */
- if (!str || !*str) return ( -1);
+ if (!str || !*str)
+ {
+ return;
+ }
/* Get the length of the string */
if (len < 0) len = strlen(str);
@@ -1157,32 +911,32 @@ static errr Infofnt_text_std(int x, int y, cptr str, int len)
/*** Decide where to place the string, vertically ***/
/* Ignore Vertical Justifications */
- y = (y * Infofnt->hgt) + Infofnt->asc + Infowin->oy;
+ y = (y * ifnt->hgt) + ifnt->asc + iwin->oy;
/*** Decide where to place the string, horizontally ***/
/* Line up with x at left edge of column 'x' */
- x = (x * Infofnt->wid) + Infowin->ox;
+ x = (x * ifnt->wid) + iwin->ox;
/*** Actually draw 'str' onto the infowin ***/
/* Be sure the correct font is ready */
- XSetFont(Metadpy->dpy, Infoclr->gc, Infofnt->info->fid);
+ XSetFont(Metadpy->dpy, iclr->gc, ifnt->info->fid);
/*** Handle the fake mono we can enforce on fonts ***/
/* Monotize the font */
- if (Infofnt->mono)
+ if (ifnt->mono)
{
/* Do each character */
- for (i = 0; i < len; ++i)
+ for (int i = 0; i < len; ++i)
{
/* Note that the Infoclr is set up to contain the Infofnt */
- XDrawImageString(Metadpy->dpy, Infowin->win, Infoclr->gc,
- x + i * Infofnt->wid + Infofnt->off, y, str + i, 1);
+ XDrawImageString(Metadpy->dpy, iwin->win, iclr->gc,
+ x + i * ifnt->wid + ifnt->off, y, str + i, 1);
}
}
@@ -1190,55 +944,45 @@ static errr Infofnt_text_std(int x, int y, cptr str, int len)
else
{
/* Note that the Infoclr is set up to contain the Infofnt */
- XDrawImageString(Metadpy->dpy, Infowin->win, Infoclr->gc,
+ XDrawImageString(Metadpy->dpy, iwin->win, iclr->gc,
x, y, str, len);
}
-
-
- /* Success */
- return (0);
}
/*
* Painting where text would be
*/
-static errr Infofnt_text_non(int x, int y, cptr str, int len)
+static void Infofnt_text_non(infowin *iwin, infoclr *iclr, infofnt *ifnt, int x, int y, const char *str, int len)
{
- int w, h;
-
-
/*** Find the width ***/
/* Negative length is a flag to count the characters in str */
if (len < 0) len = strlen(str);
/* The total width will be 'len' chars * standard width */
- w = len * Infofnt->wid;
+ int const w = len * ifnt->wid;
/*** Find the X dimensions ***/
/* Line up with x at left edge of column 'x' */
- x = x * Infofnt->wid + Infowin->ox;
+ x = x * ifnt->wid + iwin->ox;
/*** Find other dimensions ***/
/* Simply do 'Infofnt->hgt' (a single row) high */
- h = Infofnt->hgt;
+ int const h = ifnt->hgt;
/* Simply do "at top" in row 'y' */
- y = y * h + Infowin->oy;
+ y = y * h + iwin->oy;
/*** Actually 'paint' the area ***/
/* Just do a Fill Rectangle */
- XFillRectangle(Metadpy->dpy, Infowin->win, Infoclr->gc, x, y, w, h);
-
- /* Success */
- return (0);
+ XFillRectangle(Metadpy->dpy, iwin->win, iclr->gc, x, y, w, h);
}
@@ -1254,7 +998,7 @@ static errr Infofnt_text_non(int x, int y, cptr str, int len)
/*
* Hack -- cursor color
*/
-static infoclr *xor;
+static infoclr *cursor_clr;
/*
* Actual color table
@@ -1276,7 +1020,7 @@ typedef struct term_data term_data;
*/
struct term_data
{
- term t;
+ term *term_ptr;
infofnt *fnt;
@@ -1296,40 +1040,6 @@ struct term_data
*/
static term_data data[MAX_TERM_DATA];
-/* Use short names for the most commonly used elements of various structures. */
-#define DPY (Metadpy->dpy)
-#define WIN (Infowin->win)
-
-/*
- * Simply push a set of co-ordinates around.
- */
-typedef struct co_ord co_ord;
-struct co_ord
-{
- int x;
- int y;
-};
-
-/*
- * A special structure to store information about the text currently
- * selected.
- */
-typedef struct x11_selection_type x11_selection_type;
-struct x11_selection_type
-{
- bool_ select; /* The selection is currently in use. */
- bool_ drawn; /* The selection is currently displayed. */
- term *t; /* The window where the selection is found. */
- co_ord init; /* The starting co-ordinates. */
- co_ord cur; /* The end co-ordinates (the current ones if still copying). */
- co_ord old; /* The previous end co-ordinates. */
- Time time; /* The time at which the selection was finalised. */
-};
-
-static x11_selection_type s_ptr[1];
-
-
-
/*
* Process a keypress event
*
@@ -1339,7 +1049,7 @@ static void react_keypress(XKeyEvent *xev)
{
int i, n, mc, ms, mo, mx;
- uint ks1;
+ unsigned int ks1;
XKeyEvent *ev = (XKeyEvent*)(xev);
@@ -1361,13 +1071,13 @@ static void react_keypress(XKeyEvent *xev)
/* Hack -- convert into an unsigned int */
- ks1 = (uint)(ks);
+ ks1 = (unsigned int)(ks);
/* Extract four "modifier flags" */
- mc = (ev->state & ControlMask) ? TRUE : FALSE;
- ms = (ev->state & ShiftMask) ? TRUE : FALSE;
- mo = (ev->state & Mod1Mask) ? TRUE : FALSE;
- mx = (ev->state & Mod2Mask) ? TRUE : FALSE;
+ mc = (ev->state & ControlMask) ? true : false;
+ ms = (ev->state & ShiftMask) ? true : false;
+ mo = (ev->state & Mod1Mask) ? true : false;
+ mx = (ev->state & Mod2Mask) ? true : false;
/* Normal keys with no modifiers */
@@ -1441,398 +1151,11 @@ static void react_keypress(XKeyEvent *xev)
}
}
-
-/*
- * Find the square a particular pixel is part of.
- */
-static void pixel_to_square(int * const x, int * const y,
- const int ox, const int oy)
-{
- (*x) = (ox - Infowin->ox) / Infofnt->wid;
- (*y) = (oy - Infowin->oy) / Infofnt->hgt;
-}
-
-/*
- * Find the pixel at the top-left corner of a square.
- */
-static void square_to_pixel(int * const x, int * const y,
- const int ox, const int oy)
-{
- (*x) = ox * Infofnt->wid + Infowin->ox;
- (*y) = oy * Infofnt->hgt + Infowin->oy;
-}
-
-/*
- * Convert co-ordinates from starting corner/opposite corner to minimum/maximum.
- */
-static void sort_co_ord(co_ord *min, co_ord *max,
- const co_ord *b, const co_ord *a)
-{
- min->x = MIN(a->x, b->x);
- min->y = MIN(a->y, b->y);
- max->x = MAX(a->x, b->x);
- max->y = MAX(a->y, b->y);
-}
-
-/*
- * Remove the selection by redrawing it.
- */
-static void mark_selection_clear(int x1, int y1, int x2, int y2)
-{
- Term_redraw_section(x1, y1, x2, y2);
-}
-
-/*
- * Select an area by drawing a grey box around it.
- * NB. These two functions can cause flicker as the selection is modified,
- * as the game redraws the entire marked section.
- */
-static void mark_selection_mark(int x1, int y1, int x2, int y2)
-{
- square_to_pixel(&x1, &y1, x1, y1);
- square_to_pixel(&x2, &y2, x2, y2);
- XDrawRectangle(Metadpy->dpy, Infowin->win, clr[2]->gc, x1, y1,
- x2 - x1 + Infofnt->wid - 1, y2 - y1 + Infofnt->hgt - 1);
-}
-
-/*
- * Mark a selection by drawing boxes around it (for now).
- */
-static void mark_selection(void)
-{
- co_ord min, max;
- term *old = Term;
- bool_ draw = s_ptr->select;
- bool_ clear = s_ptr->drawn;
-
- /* Open the correct term if necessary. */
- if (s_ptr->t != old) Term_activate(s_ptr->t);
-
- if (clear)
- {
- sort_co_ord(&min, &max, &s_ptr->init, &s_ptr->old);
- mark_selection_clear(min.x, min.y, max.x, max.y);
- }
- if (draw)
- {
- sort_co_ord(&min, &max, &s_ptr->init, &s_ptr->cur);
- mark_selection_mark(min.x, min.y, max.x, max.y);
- }
-
- /* Finish on the current term. */
- if (s_ptr->t != old) Term_activate(old);
-
- s_ptr->old.x = s_ptr->cur.x;
- s_ptr->old.y = s_ptr->cur.y;
- s_ptr->drawn = s_ptr->select;
-}
-
-/*
- * Forget a selection for one reason or another.
- */
-static void copy_x11_release(void)
-{
- /* Deselect the current selection. */
- s_ptr->select = FALSE;
-
- /* Remove its graphical represesntation. */
- mark_selection();
-}
-
-/*
- * Start to select some text on the screen.
- */
-static void copy_x11_start(int x, int y)
-{
- if (s_ptr->select) copy_x11_release();
-
- /* Remember where the selection started. */
- s_ptr->t = Term;
- s_ptr->init.x = s_ptr->cur.x = s_ptr->old.x = x;
- s_ptr->init.y = s_ptr->cur.y = s_ptr->old.y = y;
-}
-
-/*
- * Respond to movement of the mouse when selecting text.
- */
-static void copy_x11_cont(int x, int y, unsigned int buttons)
-{
- /* Use the nearest square within bounds if the mouse is outside. */
- x = MIN(MAX(x, 0), Term->wid - 1);
- y = MIN(MAX(y, 0), Term->hgt - 1);
-
- /* The left mouse button isn't pressed. */
- if (~buttons & Button1Mask) return;
-
- /* Not a selection in this window. */
- if (s_ptr->t != Term) return;
-
- /* Not enough movement. */
- if (x == s_ptr->old.x && y == s_ptr->old.y && s_ptr->select) return;
-
- /* Something is being selected. */
- s_ptr->select = TRUE;
-
- /* Track the selection. */
- s_ptr->cur.x = x;
- s_ptr->cur.y = y;
-
- /* Hack - display it inefficiently. */
- mark_selection();
-}
-
-/*
- * Respond to release of the left mouse button by putting the selected text in
- * the primary buffer.
- */
-static void copy_x11_end(const Time time)
-{
- /* No selection. */
- if (!s_ptr->select) return;
-
- /* Not a selection in this window. */
- if (s_ptr->t != Term) return;
-
- /* Remember when the selection was finalised. */
- s_ptr->time = time;
-
- /* Acquire the primary selection. */
- XSetSelectionOwner(Metadpy->dpy, XA_PRIMARY, Infowin->win, time);
- if (XGetSelectionOwner(Metadpy->dpy, XA_PRIMARY) != Infowin->win)
- {
- /* Failed to acquire the selection, so forget it. */
- bell();
- s_ptr->select = FALSE;
- mark_selection();
- }
-}
-
-/*
- * Send a message to request that the PRIMARY buffer be sent here.
- */
-static void paste_x11_request(const Time time)
-{
- XEvent event[1];
- XSelectionRequestEvent *ptr = &(event->xselectionrequest);
-
- /* Set various things. */
- ptr->type = SelectionRequest;
- ptr->display = Metadpy->dpy;
- ptr->owner = XGetSelectionOwner(Metadpy->dpy, XA_PRIMARY);
- ptr->requestor = Infowin->win;
- ptr->selection = XA_PRIMARY;
- ptr->target = XA_STRING;
- ptr->property = XA_STRING; /* Unused */
- ptr->time = time;
-
- /* Check the owner. */
- if (ptr->owner == None)
- {
- /* No selection. */
- bell();
- return;
- }
-
- /* Send the SelectionRequest event. */
- XSendEvent(Metadpy->dpy, ptr->owner, False, NoEventMask, event);
-}
-
-/*
- * Add a character to a string in preparation for sending it to another
- * client as a STRING.
- * This doesn't change anything, as clients tend not to have difficulty in
- * receiving this format (although the standard specifies a restricted set).
- * Strings do not have a colour.
- */
-static int add_char_string(char *buf, byte a, char c)
-{
- *buf = c;
- return 1;
-}
-
-/*
- * Send some text requested by another X client.
- */
-static void paste_x11_send(XSelectionRequestEvent *rq)
-{
- XEvent event;
- XSelectionEvent *ptr = &(event.xselection);
- int (*add)(char *, byte, char) = 0;
-
- /* Set the event parameters. */
- ptr->type = SelectionNotify;
- ptr->property = rq->property;
- ptr->display = rq->display;
- ptr->requestor = rq->requestor;
- ptr->selection = rq->selection;
- ptr->target = rq->target;
- ptr->time = rq->time;
-
- /* Determine the correct "add a character" function.
- * As Term->wid is at most 255, these can add up to 4 characters of
- * output per character of input without problem.
- * The mechanism will need to change if much more than this is needed.
- */
- switch (rq->target)
- {
- case XA_STRING:
- add = add_char_string;
- break;
- default:
- goto error;
- }
-
- /* Reply to a known target received recently with data. */
- if (rq->time >= s_ptr->time && add)
- {
- char buf[1024];
- co_ord max, min;
- int x, y, l;
- byte a;
- char c;
-
- /* Work out which way around to paste. */
- sort_co_ord(&min, &max, &s_ptr->init, &s_ptr->cur);
-
- /* Paranoia. */
- if (XGetSelectionOwner(DPY, XA_PRIMARY) != WIN)
- {
- bell();
- goto error;
- }
-
- /* Delete the old value of the property. */
- XDeleteProperty(DPY, rq->requestor, rq->property);
-
- for (y = 0; y < Term->hgt; y++)
- {
- if (y < min.y) continue;
- if (y > max.y) break;
-
- for (x = l = 0; x < Term->wid; x++)
- {
- if (x < min.x) continue;
- if (x > max.x) break;
-
- /* Find the character. */
- Term_what(x, y, &a, &c);
-
- /* Add it. */
- l += (*add)(buf + l, a, c);
- }
-
- /* Terminate all but the last line in an appropriate way. */
- if (y != max.y) l += (*add)(buf + l, TERM_WHITE, '\n');
-
- /* Send the (non-empty) string. */
- XChangeProperty(DPY, rq->requestor, rq->property, rq->target, 8,
- PropModeAppend, (unsigned char*)buf, l);
- }
- }
- else
- {
- /* Respond to all bad requests with property None. */
-error:
- ptr->property = None;
- }
-
- /* Send whatever event we're left with. */
- XSendEvent(DPY, rq->requestor, FALSE, NoEventMask, &event);
-}
-
-/*
- * Add the contents of the PRIMARY buffer to the input queue.
- *
- * Hack - This doesn't use the "time" of the event, and so accepts anything a
- * client tries to send it.
- */
-static void paste_x11_accept(const XSelectionEvent *ptr)
-{
- long offset;
- unsigned long left;
-
- /* Failure. */
- if (ptr->property == None)
- {
- bell();
- return;
- }
-
- if (ptr->selection != XA_PRIMARY)
- {
- bell();
- return;
- }
- if (ptr->target != XA_STRING)
- {
- bell();
- return;
- }
-
- for (offset = 0; ; offset += left)
- {
- errr err;
-
- /* A pointer for the pasted information. */
- unsigned char *data;
-
- Atom type;
- int fmt;
- unsigned long nitems;
-
- /* Set data to the string, and catch errors. */
- if (XGetWindowProperty(Metadpy->dpy, Infowin->win, XA_STRING, offset,
- 32767, TRUE, XA_STRING, &type, &fmt, &nitems, &left, &data)
- != Success) break;
-
- /* Paste the text. */
- err = type_string((char*)data, (uint)nitems);
-
- /* Free the data pasted. */
- XFree(data);
-
- /* No room. */
- if (err == 7)
- {
- bell();
- break;
- }
- /* Paranoia? - strange errors. */
- else if (err)
- {
- break;
- }
-
- /* Pasted everything. */
- if (!left) return;
- }
-
- /* An error has occurred, so free the last bit of data before returning. */
- XFree(data);
-}
-
-/*
- * Handle various events conditional on presses of a mouse button.
- */
-static void handle_button(Time time, int x, int y, int button,
- bool_ press)
-{
- /* The co-ordinates are only used in Angband format. */
- pixel_to_square(&x, &y, x, y);
-
- if (press && button == 1) copy_x11_start(x, y);
- if (!press && button == 1) copy_x11_end(time);
- if (!press && button == 2) paste_x11_request(time);
-}
-
-
/*
* Process events
*/
-static errr CheckEvent(bool_ wait)
+static errr CheckEvent(term_data *old_td, bool wait)
{
- term_data *old_td = (term_data*)(Term->data);
-
XEvent xev_body, *xev = &xev_body;
term_data *td = NULL;
@@ -1844,12 +1167,6 @@ static errr CheckEvent(bool_ wait)
/* Do not wait unless requested */
if (!wait && !XPending(Metadpy->dpy)) return (1);
- /* Hack - redraw the selection, if needed.
- * This doesn't actually check that one of its squares was drawn to,
- * only that this may have happened.
- */
- if (s_ptr->select && !s_ptr->drawn) mark_selection();
-
/* Load the Event */
XNextEvent(Metadpy->dpy, xev);
@@ -1878,100 +1195,16 @@ static errr CheckEvent(bool_ wait)
/* Hack -- activate the Term */
- Term_activate(&td->t);
-
- /* Hack -- activate the window */
- Infowin_set(iwin);
-
+ Term_activate(td->term_ptr);
/* Switch on the Type */
switch (xev->type)
{
- case ButtonPress:
- case ButtonRelease:
- {
- bool_ press = (xev->type == ButtonPress);
-
- /* Where is the mouse */
- int x = xev->xbutton.x;
- int y = xev->xbutton.y;
-
- int z;
-
- /* Which button is involved */
- if (xev->xbutton.button == Button1) z = 1;
- else if (xev->xbutton.button == Button2) z = 2;
- else if (xev->xbutton.button == Button3) z = 3;
- else if (xev->xbutton.button == Button4) z = 4;
- else if (xev->xbutton.button == Button5) z = 5;
- else z = 0;
-
- /* Where is the mouse */
- x = xev->xbutton.x;
- y = xev->xbutton.y;
-
- /* XXX Handle */
- handle_button(xev->xbutton.time, x, y, z, press);
-
- break;
- }
-
- case EnterNotify:
- case LeaveNotify:
- {
- /* Where is the mouse */
- /* XXX Handle */
-
- break;
- }
-
- case MotionNotify:
- {
- int x = xev->xmotion.x;
- int y = xev->xmotion.y;
- unsigned int z = xev->xmotion.state;
-
- /* Convert to co-ordinates Angband understands. */
- pixel_to_square(&x, &y, x, y);
-
- /* Alter the selection if appropriate. */
- copy_x11_cont(x, y, z);
-
- /* XXX Handle */
-
- break;
- }
-
- case SelectionNotify:
- {
- paste_x11_accept(&(xev->xselection));
- break;
- }
-
- case SelectionRequest:
- {
- paste_x11_send(&(xev->xselectionrequest));
- break;
- }
-
- case SelectionClear:
- {
- s_ptr->select = FALSE;
- mark_selection();
- break;
- }
-
- case KeyRelease:
- {
- /* Nothing */
- break;
- }
-
case KeyPress:
{
/* Hack -- use "old" term */
- Term_activate(&old_td->t);
+ Term_activate(old_td->term_ptr);
/* Process the key */
react_keypress(&(xev->xkey));
@@ -1985,7 +1218,7 @@ static errr CheckEvent(bool_ wait)
if (xev->xexpose.count) break;
/* Clear the window */
- Infowin_wipe();
+ Infowin_wipe(iwin);
/* Redraw */
Term_redraw();
@@ -1995,15 +1228,15 @@ static errr CheckEvent(bool_ wait)
case MapNotify:
{
- Infowin->mapped = 1;
- Term->mapped_flag = TRUE;
+ iwin->mapped = 1;
+ Term_mapped();
break;
}
case UnmapNotify:
{
- Infowin->mapped = 0;
- Term->mapped_flag = FALSE;
+ iwin->mapped = 0;
+ Term_unmapped();
break;
}
@@ -2012,18 +1245,18 @@ static errr CheckEvent(bool_ wait)
{
int cols, rows;
- int ox = Infowin->ox;
- int oy = Infowin->oy;
+ int ox = iwin->ox;
+ int oy = iwin->oy;
/* Save the new Window Parms */
- Infowin->x = xev->xconfigure.x;
- Infowin->y = xev->xconfigure.y;
- Infowin->w = xev->xconfigure.width;
- Infowin->h = xev->xconfigure.height;
+ iwin->x = xev->xconfigure.x;
+ iwin->y = xev->xconfigure.y;
+ iwin->w = xev->xconfigure.width;
+ iwin->h = xev->xconfigure.height;
/* Determine "proper" number of rows/cols */
- cols = ((Infowin->w - (ox + ox)) / td->fnt->wid);
- rows = ((Infowin->h - (oy + oy)) / td->fnt->hgt);
+ cols = ((iwin->w - (ox + ox)) / td->fnt->wid);
+ rows = ((iwin->h - (oy + oy)) / td->fnt->hgt);
/* Hack -- minimal size */
if (td == &data[0])
@@ -2050,180 +1283,138 @@ static errr CheckEvent(bool_ wait)
/* Hack -- Activate the old term */
- Term_activate(&old_td->t);
-
- /* Hack -- Activate the proper window */
- Infowin_set(old_td->win);
-
+ Term_activate(old_td->term_ptr);
/* Success */
return (0);
}
-/*
- * Handle "activation" of a term
+/**
+ * UserInterace for X11
*/
-static errr Term_xtra_x11_level(int v)
-{
- term_data *td = (term_data*)(Term->data);
+class X11Frontend final : public Frontend {
+
+private:
+ term_data *m_term_data;
- /* Handle "activate" */
- if (v)
+public:
+ explicit X11Frontend(term_data *term_data)
+ : m_term_data(term_data)
{
- /* Activate the window */
- Infowin_set(td->win);
+ }
- /* Activate the font */
- Infofnt_set(td->fnt);
+ void init() final
+ {
+ // No action necessary
}
- /* Success */
- return (0);
-}
+ bool soft_cursor() const final
+ {
+ return true;
+ }
+ bool icky_corner() const final
+ {
+ return false;
+ }
-/*
- * React to changes
- */
-static errr Term_xtra_x11_react(void)
-{
- int i;
+ void nuke() final
+ {
+ // No action necessary
+ }
- if (Metadpy->color)
+ void process_event(bool wait) final
{
- /* Check the colors */
- for (i = 0; i < 256; i++)
+ CheckEvent(m_term_data, wait);
+ }
+
+ void flush_events() final
+ {
+ while (!CheckEvent(m_term_data, false))
{
- if ((color_table[i][0] != angband_color_table[i][0]) ||
- (color_table[i][1] != angband_color_table[i][1]) ||
- (color_table[i][2] != angband_color_table[i][2]) ||
- (color_table[i][3] != angband_color_table[i][3]))
- {
- Pixell pixel;
-
- /* Save new values */
- color_table[i][0] = angband_color_table[i][0];
- color_table[i][1] = angband_color_table[i][1];
- color_table[i][2] = angband_color_table[i][2];
- color_table[i][3] = angband_color_table[i][3];
-
- /* Create pixel */
- pixel = create_pixel(Metadpy->dpy,
- color_table[i][1],
- color_table[i][2],
- color_table[i][3]);
-
- /* Change the foreground */
- Infoclr_set(clr[i]);
- Infoclr_change_fg(pixel);
- }
+ // Keep flushing
}
}
- /* Success */
- return (0);
-}
-
+ void clear() final
+ {
+ Infowin_wipe(m_term_data->win);
+ }
-/*
- * Handle a "special request"
- */
-static errr Term_xtra_x11(int n, int v)
-{
- /* Handle a subset of the legal requests */
- switch (n)
+ void flush_output() final
{
- /* Make a noise */
- case TERM_XTRA_NOISE:
- Metadpy_do_beep(); return (0);
+ XFlush(Metadpy->dpy);
+ }
- /* Flush the output XXX XXX */
- case TERM_XTRA_FRESH: Metadpy_update(1, 0, 0); return (0);
+ void noise() final
+ {
+ XBell(Metadpy->dpy, 100);
+ }
- /* Process random events XXX */
- case TERM_XTRA_BORED:
- {
- return (CheckEvent(0));
- }
+ void process_queued_events() final
+ {
+ CheckEvent(m_term_data, false);
+ }
- /* Process Events XXX */
- case TERM_XTRA_EVENT:
+ void react() final
+ {
+ if (Metadpy->color)
{
- return (CheckEvent(v));
+ /* Check the colors */
+ for (int i = 0; i < 256; i++)
+ {
+ if ((color_table[i][0] != angband_color_table[i][0]) ||
+ (color_table[i][1] != angband_color_table[i][1]) ||
+ (color_table[i][2] != angband_color_table[i][2]) ||
+ (color_table[i][3] != angband_color_table[i][3]))
+ {
+ Pixell pixel;
+
+ /* Save new values */
+ color_table[i][0] = angband_color_table[i][0];
+ color_table[i][1] = angband_color_table[i][1];
+ color_table[i][2] = angband_color_table[i][2];
+ color_table[i][3] = angband_color_table[i][3];
+
+ /* Create pixel */
+ pixel = create_pixel(Metadpy->dpy,
+ color_table[i][1],
+ color_table[i][2],
+ color_table[i][3]);
+
+ /* Change the foreground */
+ Infoclr_change_fg(clr[i], pixel);
+ }
+ }
}
-
- /* Flush the events XXX */
- case TERM_XTRA_FLUSH: while (!CheckEvent(FALSE)); return (0);
-
- /* Handle change in the "level" */
- case TERM_XTRA_LEVEL: return (Term_xtra_x11_level(v));
-
- /* Clear the screen, and redraw any selection later. */
- case TERM_XTRA_CLEAR: Infowin_wipe(); s_ptr->drawn = FALSE; return (0);
-
- /* React to changes */
- case TERM_XTRA_REACT: return (Term_xtra_x11_react());
-
- /* Rename main window */
- case TERM_XTRA_RENAME_MAIN_WIN: Infowin_set_name(angband_term_name[0]); return (0);
}
- /* Unknown */
- return (1);
-}
-
-
-/*
- * Draw the cursor as an inverted rectangle.
- *
- * Consider a rectangular outline like "main-mac.c". XXX XXX
- */
-static errr Term_curs_x11(int x, int y)
-{
- /* Draw the cursor */
- Infoclr_set(xor);
-
- /* Hilite the cursor character */
- Infofnt_text_non(x, y, " ", 1);
-
- /* Redraw the selection if any, as it may have been obscured. (later) */
- s_ptr->drawn = FALSE;
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Draw some textual characters.
- */
-static errr Term_text_x11(int x, int y, int n, byte a, cptr s)
-{
- /* Draw the text */
- Infoclr_set(clr[a]);
-
- /* Draw the text */
- Infofnt_text_std(x, y, s, n);
-
- /* Success */
- return (0);
-}
-
+ void rename_main_window(std::string_view sv) final
+ {
+ Infowin_set_name(m_term_data->win, sv);
+ }
+ void draw_cursor(int x, int y) final
+ {
+ Infofnt_text_non(m_term_data->win, cursor_clr, m_term_data->fnt, x, y, " ", 1);
+ }
+ void draw_text(int x, int y, int n, byte a, const char *s) final
+ {
+ Infofnt_text_std(m_term_data->win, clr[a], m_term_data->fnt, x, y, s, n);
+ }
+};
/*
* Initialize a term_data
*/
-static errr term_data_init(term_data *td, int i)
+static term *term_data_init(term_data *td, int i)
{
- term *t = &td->t;
-
- cptr name = angband_term_name[i];
+ const char *name = angband_term_name[i];
- cptr font;
+ const char *font;
int x = 0;
int y = 0;
@@ -2238,7 +1429,7 @@ static errr term_data_init(term_data *td, int i)
char buf[80];
- cptr str;
+ const char *str;
int val;
@@ -2349,13 +1540,12 @@ static errr term_data_init(term_data *td, int i)
/* Prepare the standard font */
- td->fnt = calloc(1, sizeof(struct infofnt));
+ td->fnt = (infofnt *) calloc(1, sizeof(struct infofnt));
if (td->fnt == NULL)
{
abort();
}
- Infofnt_set(td->fnt);
- Infofnt_init_data(font);
+ Infofnt_init_data(td->fnt, font);
/* Hack -- key buffer size */
num = (i == 0 ? 1024 : 16);
@@ -2365,25 +1555,26 @@ static errr term_data_init(term_data *td, int i)
hgt = rows * td->fnt->hgt + (oy + oy);
/* Create a top-window */
- td->win = calloc(1, sizeof(struct infowin));
+ td->win = (infowin *) calloc(1, sizeof(struct infowin));
if (td->win == NULL)
{
abort();
}
- Infowin_set(td->win);
- Infowin_init_top(x, y, wid, hgt, 0,
+
+ Infowin_init_data(td->win, None, x, y, wid, hgt, 0,
Metadpy->fg, Metadpy->bg);
/* Ask for certain events */
- Infowin_set_mask(ExposureMask | StructureNotifyMask | KeyPressMask |
- PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
+ Infowin_set_mask(td->win,
+ ExposureMask | StructureNotifyMask | KeyPressMask |
+ PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
/* Set the window name */
- Infowin_set_name(name);
+ Infowin_set_name(td->win, name);
/* Save the inner border */
- Infowin->ox = ox;
- Infowin->oy = oy;
+ td->win->ox = ox;
+ td->win->oy = oy;
/* Make Class Hints */
ch = XAllocClassHint();
@@ -2397,7 +1588,7 @@ static errr term_data_init(term_data *td, int i)
strcpy(res_class, "Angband");
ch->res_class = res_class;
- XSetClassHint(Metadpy->dpy, Infowin->win, ch);
+ XSetClassHint(Metadpy->dpy, td->win->win, ch);
/* Make Size Hints */
sh = XAllocSizeHints();
@@ -2438,35 +1629,26 @@ static errr term_data_init(term_data *td, int i)
sh->base_height = (oy + oy);
/* Use the size hints */
- XSetWMNormalHints(Metadpy->dpy, Infowin->win, sh);
+ XSetWMNormalHints(Metadpy->dpy, td->win->win, sh);
/* Map the window */
- Infowin_map();
+ Infowin_map(td->win);
/* Move the window to requested location */
- if ((x >= 0) && (y >= 0)) Infowin_impell(x, y);
-
+ if ((x >= 0) && (y >= 0))
+ {
+ Infowin_impell(td->win, x, y);
+ }
/* Initialize the term */
- term_init(t, cols, rows, num);
-
- /* Use a "soft" cursor */
- t->soft_cursor = TRUE;
-
- /* Hooks */
- t->xtra_hook = Term_xtra_x11;
- t->curs_hook = Term_curs_x11;
- t->text_hook = Term_text_x11;
-
- /* Save the data */
- t->data = td;
+ td->term_ptr = term_init(cols, rows, num, std::make_shared<X11Frontend>(td));
/* Activate (important) */
- Term_activate(t);
+ Term_activate(td->term_ptr);
/* Success */
- return (0);
+ return td->term_ptr;
}
@@ -2477,7 +1659,7 @@ errr init_x11(int argc, char *argv[])
{
int i;
- cptr dpy_name = "";
+ const char *dpy_name = "";
int num_term = 1;
@@ -2486,14 +1668,14 @@ errr init_x11(int argc, char *argv[])
/* Parse args */
for (i = 1; i < argc; i++)
{
- if (prefix(argv[i], "-d"))
+ if (starts_with(argv[i], "-d"))
{
dpy_name = &argv[i][2];
continue;
}
- if (prefix(argv[i], "-n"))
+ if (starts_with(argv[i], "-n"))
{
num_term = atoi(&argv[i][2]);
if (num_term > MAX_TERM_DATA) num_term = MAX_TERM_DATA;
@@ -2506,17 +1688,16 @@ errr init_x11(int argc, char *argv[])
/* Init the Metadpy if possible */
- if (Metadpy_init_name(dpy_name)) return ( -1);
+ if (Metadpy_new(dpy_name)) return ( -1);
/* Prepare cursor color */
- xor = calloc(1, sizeof(struct infoclr));
- if (xor == NULL)
+ cursor_clr = (infoclr *) calloc(1, sizeof(struct infoclr));
+ if (cursor_clr == NULL)
{
abort();
}
- Infoclr_set(xor);
- Infoclr_init_ppn(Metadpy->fg, Metadpy->bg, "xor", 0);
+ Infoclr_init_data(cursor_clr, Metadpy->fg, Metadpy->bg, Infoclr_Opcode_XOR);
/* Prepare normal colors */
@@ -2524,12 +1705,11 @@ errr init_x11(int argc, char *argv[])
{
Pixell pixel;
- clr[i] = calloc(1, sizeof(struct infoclr));
+ clr[i] = (infoclr *) calloc(1, sizeof(struct infoclr));
if (clr[i] == NULL)
{
abort();
}
- Infoclr_set(clr[i]);
/* Acquire Angband colors */
color_table[i][0] = angband_color_table[i][0];
@@ -2551,7 +1731,7 @@ errr init_x11(int argc, char *argv[])
}
/* Initialize the color */
- Infoclr_init_ppn(pixel, Metadpy->bg, "cpy", 0);
+ Infoclr_init_data(clr[i], pixel, Metadpy->bg, Infoclr_Opcode_CPY);
}
@@ -2561,18 +1741,17 @@ errr init_x11(int argc, char *argv[])
term_data *td = &data[i];
/* Initialize the term_data */
- term_data_init(td, i);
+ term *t = term_data_init(td, i);
/* Save global entry */
- angband_term[i] = Term;
+ angband_term[i] = t;
}
/* Raise the "Angband" window */
- Infowin_set(data[0].win);
- Infowin_raise();
+ Infowin_raise(data[0].win);
/* Activate the "Angband" window screen */
- Term_activate(&data[0].t);
+ Term_activate(data[0].term_ptr);
diff --git a/src/main.cc b/src/main.cc
index c0ac3826..d397ca5c 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -6,31 +6,35 @@
* are included in all such copies.
*/
-#include "main.h"
+#include "main.hpp"
#include "birth.hpp"
-#include "dungeon.h"
+#include "config.hpp"
+#include "dungeon.hpp"
#include "files.hpp"
#include "game.hpp"
-#include "init2.h"
+#include "init2.hpp"
#include "modules.hpp"
-#include "util.h"
+#include "program_args.hpp"
#include "util.hpp"
-#include "variable.h"
#include "variable.hpp"
+#include "z-form.hpp"
+#include "z-util.hpp"
+#include <boost/algorithm/string/predicate.hpp>
+
+using boost::algorithm::equals;
+using boost::algorithm::ends_with;
/*
* A hook for "quit()".
*
* Close down, then fall back into "quit()".
*/
-static void quit_hook(cptr s)
+static void quit_hook(const char *s)
{
- int j;
-
/* Scan windows */
- for (j = 8 - 1; j >= 0; j--)
+ for (int j = ANGBAND_TERM_MAX - 1; j >= 0; j--)
{
/* Unused */
if (!angband_term[j]) continue;
@@ -45,7 +49,7 @@ static void quit_hook(cptr s)
/*
* Check existence of ".ToME/" directory in the user's
* home directory or try to create it if it doesn't exist.
- * Returns FALSE if all the attempts fail.
+ * Returns false if all the attempts fail.
*/
static void init_save_dir()
{
@@ -96,13 +100,13 @@ static void init_file_paths_with_env()
char path[1024];
/* Get the environment variable */
- cptr tail = getenv("TOME_PATH");
+ const char *tail = getenv("TOME_PATH");
/* Use the angband_path, or a default */
strcpy(path, tail ? tail : DEFAULT_PATH);
/* Hack -- Add a path separator (only if needed) */
- if (!suffix(path, PATH_SEP)) strcat(path, PATH_SEP);
+ if (!ends_with(path, PATH_SEP)) strcat(path, PATH_SEP);
/* Initialize */
init_file_paths(path);
@@ -120,8 +124,6 @@ int main_real(int argc, char *argv[], char const *platform_sys, int (*init_platf
{
int i;
- bool_ args = TRUE;
-
// Initialize game structure
game = new Game();
@@ -134,12 +136,18 @@ int main_real(int argc, char *argv[], char const *platform_sys, int (*init_platf
/* Make sure save directory exists */
init_save_dir();
+ /* Program arguments */
+ program_args program_args;
/* Process the command line arguments */
+ bool args = true;
for (i = 1; args && (i < argc); i++)
{
/* Require proper options */
- if (argv[i][0] != '-') goto usage;
+ if (argv[i][0] != '-')
+ {
+ goto usage;
+ }
/* Analyze option */
switch (argv[i][1])
@@ -147,38 +155,42 @@ int main_real(int argc, char *argv[], char const *platform_sys, int (*init_platf
case 'W':
case 'w':
{
- arg_wizard = TRUE;
+ program_args.wizard = true;
break;
}
case 'R':
case 'r':
{
- arg_force_roguelike = TRUE;
+ program_args.force_key_set = 'r';
break;
}
case 'O':
case 'o':
{
- arg_force_original = TRUE;
+ program_args.force_key_set = 'o';
break;
}
case 'u':
case 'U':
{
- if (!argv[i][2]) goto usage;
- game->player_name = &argv[i][2];
- game->player_base = &argv[i][2];
- no_begin_screen = TRUE;
+ if (!argv[i][2])
+ {
+ goto usage;
+ }
+ program_args.player_name = &argv[i][2];
break;
}
case 'M':
{
- if (!argv[i][2]) goto usage;
- force_module = &argv[i][2];
+ if (!argv[i][2])
+ {
+ goto usage;
+ }
+ program_args.module = &argv[i][2];
break;
}
@@ -189,7 +201,7 @@ int main_real(int argc, char *argv[], char const *platform_sys, int (*init_platf
case '-':
{
- if (argv[i][2] == 'h' && !strcmp((argv[i] + 2), "help"))
+ if (argv[i][2] == 'h' && equals(argv[i] + 2, "help"))
{
goto usage;
}
@@ -198,7 +210,7 @@ int main_real(int argc, char *argv[], char const *platform_sys, int (*init_platf
argv[i] = argv[0];
argc = argc - i;
argv = argv + i;
- args = FALSE;
+ args = false;
break;
}
}
@@ -235,9 +247,15 @@ usage:
argv[1] = NULL;
}
+ /* If player name specified... */
+ if (!program_args.player_name.empty())
+ {
+ game->player_name = program_args.player_name;
+ no_begin_screen = true;
+ }
/* Process the player name */
- process_player_name(TRUE);
+ set_player_base(game->player_name);
/* Install "quit" hook */
@@ -253,13 +271,13 @@ usage:
ANGBAND_SYS = platform_sys;
/* Initialize */
- init_angband();
+ init_angband(program_args);
/* Wait for response */
pause_line(23);
/* Play the game */
- play_game();
+ play_game(program_args);
/* Quit */
quit(NULL);
diff --git a/src/main.h b/src/main.hpp
index edc590b3..d1e9441e 100644
--- a/src/main.h
+++ b/src/main.hpp
@@ -1,11 +1,3 @@
#pragma once
-#ifdef __cplusplus
-extern "C" {
-#endif
-
int main_real(int argc, char *argv[], char const *platform_sys, int (*init_platform)(int, char *[]), char const *platform_usage);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/src/martial_arts.hpp b/src/martial_arts.hpp
index 1f2f0cbe..998f9c22 100644
--- a/src/martial_arts.hpp
+++ b/src/martial_arts.hpp
@@ -1,18 +1,18 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* Martial arts descriptors
*/
struct martial_arts
{
- cptr desc; /* A verbose attack description */
- int min_level; /* Minimum level to use */
- int chance; /* Chance of 'success' */
- int dd; /* Damage dice */
- int ds; /* Damage sides */
- s16b effect; /* Special effects */
- s16b power; /* Special effects power */
+ const char *desc; /* A verbose attack description */
+ int min_level; /* Minimum level to use */
+ int chance; /* Chance of 'success' */
+ int dd; /* Damage dice */
+ int ds; /* Damage sides */
+ s16b effect; /* Special effects */
+ s16b power; /* Special effects power */
};
diff --git a/src/melee1.cc b/src/melee1.cc
index 58ebfbaa..1f4dc573 100644
--- a/src/melee1.cc
+++ b/src/melee1.cc
@@ -32,6 +32,7 @@
#include "xtra1.hpp"
#include "xtra2.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#include <boost/algorithm/string/predicate.hpp>
@@ -97,10 +98,10 @@ static int check_hit(int power, int level)
ac = p_ptr->ac + p_ptr->to_a;
/* Power and Level compete against Armor */
- if ((i > 0) && (randint(i - luck( -10, 10)) > ((ac * 3) / 4))) return (TRUE);
+ if ((i > 0) && (randint(i - luck( -10, 10)) > ((ac * 3) / 4))) return true;
/* Assume miss */
- return (FALSE);
+ return false;
}
@@ -108,7 +109,7 @@ static int check_hit(int power, int level)
/*
* Hack -- possible "insult" messages
*/
-static cptr desc_insult[] =
+static const char *desc_insult[] =
{
"insults you!",
"insults your mother!",
@@ -125,7 +126,7 @@ static cptr desc_insult[] =
/*
* Hack -- possible "insult" messages
*/
-static cptr desc_moan[] =
+static const char *desc_moan[] =
{
"seems sad about something.",
"asks if you have seen his dogs.",
@@ -222,7 +223,7 @@ int get_attack_power(int effect)
/*
* Attack the player via physical attacks.
*/
-bool_ carried_make_attack_normal(int r_idx)
+bool carried_make_attack_normal(int r_idx)
{
auto const &r_info = game->edit_data.r_info;
@@ -236,10 +237,10 @@ bool_ carried_make_attack_normal(int r_idx)
char ddesc[80] = "your symbiote";
auto sym_name = symbiote_name(true);
- bool_ alive = TRUE;
+ bool alive = true;
/* Not allowed to attack */
- if (r_ptr->flags & RF_NEVER_BLOW) return (FALSE);
+ if (r_ptr->flags & RF_NEVER_BLOW) return false;
/* Total armor */
ac = p_ptr->ac + p_ptr->to_a;
@@ -253,7 +254,7 @@ bool_ carried_make_attack_normal(int r_idx)
int power = 0;
int damage = 0;
- cptr act = NULL;
+ const char *act = NULL;
/* Extract the attack infomation */
int effect = r_ptr->blow[ap_cnt].effect;
@@ -480,7 +481,7 @@ bool_ carried_make_attack_normal(int r_idx)
damage -= (damage * ((ac < 150) ? ac : 150) / 250);
/* Take damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
break;
@@ -514,7 +515,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_POISON:
{
/* Take some damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
/* Take "poison" effect */
@@ -529,7 +530,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_UN_BONUS:
{
/* Take some damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
/* Allow complete resist */
@@ -545,7 +546,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_UN_POWER:
{
/* Take some damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
break;
}
@@ -553,7 +554,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_EAT_GOLD:
{
/* Take some damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
break;
}
@@ -561,7 +562,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_EAT_ITEM:
{
/* Take some damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
break;
}
@@ -569,7 +570,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_EAT_FOOD:
{
/* Take some damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
break;
}
@@ -577,7 +578,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_EAT_LITE:
{
/* Take some damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
break;
}
@@ -588,7 +589,7 @@ bool_ carried_make_attack_normal(int r_idx)
msg_print("You are covered in acid!");
/* Special damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
acid_dam(damage, ddesc);
break;
@@ -600,7 +601,7 @@ bool_ carried_make_attack_normal(int r_idx)
msg_print("You are struck by electricity!");
/* Special damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
elec_dam(damage, ddesc);
@@ -613,7 +614,7 @@ bool_ carried_make_attack_normal(int r_idx)
msg_print("You are enveloped in flames!");
/* Special damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
fire_dam(damage, ddesc);
@@ -626,7 +627,7 @@ bool_ carried_make_attack_normal(int r_idx)
msg_print("You are covered with frost!");
/* Special damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
cold_dam(damage, ddesc);
@@ -636,7 +637,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_BLIND:
{
/* Take damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
/* Increase "blind" */
@@ -652,7 +653,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_CONFUSE:
{
/* Take damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
/* Increase "confused" */
@@ -668,7 +669,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_TERRIFY:
{
/* Take damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
/* Increase "afraid" */
@@ -695,7 +696,7 @@ bool_ carried_make_attack_normal(int r_idx)
if (p_ptr->paralyzed && (damage < 1)) damage = 1;
/* Take damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
/* Increase "paralyzed" */
@@ -719,7 +720,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_LOSE_STR:
{
/* Damage (physical) */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
/* Damage (stat) */
@@ -731,7 +732,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_LOSE_INT:
{
/* Damage (physical) */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
/* Damage (stat) */
@@ -743,7 +744,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_LOSE_WIS:
{
/* Damage (physical) */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
/* Damage (stat) */
@@ -755,7 +756,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_LOSE_DEX:
{
/* Damage (physical) */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
/* Damage (stat) */
@@ -767,7 +768,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_LOSE_CON:
{
/* Damage (physical) */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
/* Damage (stat) */
@@ -779,7 +780,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_LOSE_CHR:
{
/* Damage (physical) */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
/* Damage (stat) */
@@ -791,7 +792,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_LOSE_ALL:
{
/* Damage (physical) */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
/* Damage (stats) */
@@ -811,7 +812,7 @@ bool_ carried_make_attack_normal(int r_idx)
damage -= (damage * ((ac < 150) ? ac : 150) / 250);
/* Take damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
/* Radius 8 earthquake centered at the monster */
@@ -828,7 +829,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_EXP_10:
{
/* Take damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
if (p_ptr->hold_life && (rand_int(100) < 95))
@@ -855,7 +856,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_EXP_20:
{
/* Take damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
if (p_ptr->hold_life && (rand_int(100) < 90))
@@ -882,7 +883,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_EXP_40:
{
/* Take damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
if (p_ptr->hold_life && (rand_int(100) < 75))
@@ -909,7 +910,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_EXP_80:
{
/* Take damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
if (p_ptr->hold_life && (rand_int(100) < 50))
@@ -936,7 +937,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBE_DISEASE:
{
/* Take some damage */
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
/* Take "poison" effect */
@@ -949,7 +950,7 @@ bool_ carried_make_attack_normal(int r_idx)
if (randint(100) < 11)
{
/* 1% chance for perm. damage */
- bool_ perm = (randint(10) == 1);
+ bool perm = (randint(10) == 1);
dec_stat(A_CON, randint(10), perm);
}
@@ -1039,7 +1040,7 @@ bool_ carried_make_attack_normal(int r_idx)
break;
}
}
- carried_monster_hit = TRUE;
+ carried_monster_hit = true;
take_hit(damage, ddesc);
break;
}
@@ -1175,7 +1176,7 @@ bool_ carried_make_attack_normal(int r_idx)
}
}
/* Assume we attacked */
- return (TRUE);
+ return true;
}
/*
@@ -1188,14 +1189,14 @@ void black_breath_attack(int chance)
{
msg_print("Your foe calls upon your soul!");
msg_print("You feel the Black Breath slowly draining you of life...");
- p_ptr->black_breath = TRUE;
+ p_ptr->black_breath = true;
}
}
/*
* Attack the player via physical attacks.
*/
-bool_ make_attack_normal(int m_idx, byte divis)
+bool make_attack_normal(int m_idx, byte divis)
{
monster_type *m_ptr = &m_list[m_idx];
@@ -1214,23 +1215,25 @@ bool_ make_attack_normal(int m_idx, byte divis)
char ddesc[80];
- bool_ blinked;
- bool_ touched = FALSE, fear = FALSE, alive = TRUE;
- bool_ explode = FALSE;
+ bool blinked;
+ bool touched = false;
+ bool fear = false;
+ bool alive = true;
+ bool explode = false;
/* Not allowed to attack? */
auto r_ptr = m_ptr->race();
- if (r_ptr->flags & RF_NEVER_BLOW) return (FALSE);
+ if (r_ptr->flags & RF_NEVER_BLOW) return false;
/* ...nor if friendly */
if (is_friend(m_ptr) >= 0)
{
if (p_ptr->control == m_idx) swap_position(m_ptr->fy, m_ptr->fx);
- return FALSE;
+ return false;
}
/* Cannot attack the player if mortal and player fated to never die by the ... */
- if ((r_ptr->flags & RF_MORTAL) && (p_ptr->no_mortal)) return (FALSE);
+ if ((r_ptr->flags & RF_MORTAL) && (p_ptr->no_mortal)) return false;
/* Total armor */
ac = p_ptr->ac + p_ptr->to_a;
@@ -1247,7 +1250,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
/* Assume no blink */
- blinked = FALSE;
+ blinked = false;
/* Scan through all four blows */
for (ap_cnt = 0; ap_cnt < 4; ap_cnt++)
@@ -1255,7 +1258,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
int power = 0;
int damage = 0;
- cptr act = NULL;
+ const char *act = NULL;
/* Extract the attack infomation */
int effect = m_ptr->blow[ap_cnt].effect;
@@ -1439,21 +1442,21 @@ bool_ make_attack_normal(int m_idx, byte divis)
{
act = "hits you.";
do_cut = do_stun = 1;
- touched = TRUE;
+ touched = true;
break;
}
case RBM_TOUCH:
{
act = "touches you.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_PUNCH:
{
act = "punches you.";
- touched = TRUE;
+ touched = true;
do_stun = 1;
break;
}
@@ -1461,7 +1464,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
case RBM_KICK:
{
act = "kicks you.";
- touched = TRUE;
+ touched = true;
do_stun = 1;
break;
}
@@ -1469,7 +1472,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
case RBM_CLAW:
{
act = "claws you.";
- touched = TRUE;
+ touched = true;
do_cut = 1;
break;
}
@@ -1478,14 +1481,14 @@ bool_ make_attack_normal(int m_idx, byte divis)
{
act = "bites you.";
do_cut = 1;
- touched = TRUE;
+ touched = true;
break;
}
case RBM_STING:
{
act = "stings you.";
- touched = TRUE;
+ touched = true;
break;
}
@@ -1499,7 +1502,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
{
act = "butts you.";
do_stun = 1;
- touched = TRUE;
+ touched = true;
break;
}
@@ -1507,28 +1510,28 @@ bool_ make_attack_normal(int m_idx, byte divis)
{
act = "crushes you.";
do_stun = 1;
- touched = TRUE;
+ touched = true;
break;
}
case RBM_ENGULF:
{
act = "engulfs you.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_CHARGE:
{
act = "charges you.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_CRAWL:
{
act = "crawls on you.";
- touched = TRUE;
+ touched = true;
break;
}
@@ -1547,7 +1550,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
case RBM_EXPLODE:
{
act = "explodes.";
- explode = TRUE;
+ explode = true;
break;
}
@@ -1729,7 +1732,10 @@ bool_ make_attack_normal(int m_idx, byte divis)
o_ptr = &p_ptr->inventory[i];
/* Skip non-objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Drain charged wands/staffs
Hack -- don't let artifacts get drained */
@@ -1780,7 +1786,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
msg_print("You quickly protect your money pouch!");
/* Occasional blink anyway */
- if (rand_int(3)) blinked = TRUE;
+ if (rand_int(3)) blinked = true;
}
/* Eat gold */
@@ -1831,7 +1837,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
p_ptr->window |= (PW_PLAYER);
/* Blink away */
- blinked = TRUE;
+ blinked = true;
}
break;
@@ -1851,7 +1857,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
msg_print("You grab hold of your backpack!");
/* Occasional "blink" anyway */
- blinked = TRUE;
+ blinked = true;
/* Done */
break;
@@ -1867,13 +1873,19 @@ bool_ make_attack_normal(int m_idx, byte divis)
o_ptr = &p_ptr->inventory[i];
/* Skip non-objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Skip artifacts */
- if (artifact_p(o_ptr)) continue;
+ if (artifact_p(o_ptr))
+ {
+ continue;
+ }
/* Get a description */
- object_desc(o_name, o_ptr, FALSE, 3);
+ object_desc(o_name, o_ptr, false, 3);
/* Message */
msg_format("%sour %s (%c) was stolen!",
@@ -1912,7 +1924,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
}
/* Forget mark */
- j_ptr->marked = FALSE;
+ j_ptr->marked = false;
/* Memorize monster */
j_ptr->held_m_idx = m_idx;
@@ -1926,7 +1938,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
inc_stack_size_ex(i, -1, OPTIMIZE, NO_DESCRIBE);
/* Blink away */
- blinked = TRUE;
+ blinked = true;
/* Done */
break;
@@ -1950,13 +1962,16 @@ bool_ make_attack_normal(int m_idx, byte divis)
o_ptr = &p_ptr->inventory[i];
/* Skip non-objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Skip non-food objects */
if (o_ptr->tval != TV_FOOD) continue;
/* Get a description */
- object_desc(o_name, o_ptr, FALSE, 0);
+ object_desc(o_name, o_ptr, false, 0);
/* Message */
msg_format("%sour %s (%c) was eaten!",
@@ -2364,7 +2379,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
if (randint(100) < 11)
{
/* 1% chance for perm. damage */
- bool_ perm = (randint(10) == 1);
+ bool perm = (randint(10) == 1);
dec_stat(A_CON, randint(10), perm);
}
@@ -2566,8 +2581,8 @@ bool_ make_attack_normal(int m_idx, byte divis)
{
if (mon_take_hit(m_idx, m_ptr->hp + 1, &fear, NULL))
{
- blinked = FALSE;
- alive = FALSE;
+ blinked = false;
+ alive = false;
}
}
@@ -2581,8 +2596,8 @@ bool_ make_attack_normal(int m_idx, byte divis)
if (mon_take_hit(m_idx, damroll(2, 6), &fear,
" turns into a pile of ash."))
{
- blinked = FALSE;
- alive = FALSE;
+ blinked = false;
+ alive = false;
}
}
}
@@ -2595,8 +2610,8 @@ bool_ make_attack_normal(int m_idx, byte divis)
if (mon_take_hit(m_idx, damroll(2, 6), &fear,
" turns into a pile of cinder."))
{
- blinked = FALSE;
- alive = FALSE;
+ blinked = false;
+ alive = false;
}
}
}
@@ -2607,8 +2622,8 @@ bool_ make_attack_normal(int m_idx, byte divis)
if (mon_take_hit(m_idx, damroll(p_ptr->shield_power_opt, p_ptr->shield_power_opt2), &fear,
" is bashed by your mystic shield."))
{
- blinked = FALSE;
- alive = FALSE;
+ blinked = false;
+ alive = false;
}
}
@@ -2620,8 +2635,8 @@ bool_ make_attack_normal(int m_idx, byte divis)
if (mon_take_hit(m_idx, damroll(p_ptr->shield_power_opt, p_ptr->shield_power_opt2), &fear,
" is burned by your fiery shield."))
{
- blinked = FALSE;
- alive = FALSE;
+ blinked = false;
+ alive = false;
}
}
}
@@ -2632,8 +2647,8 @@ bool_ make_attack_normal(int m_idx, byte divis)
if (mon_take_hit(m_idx, damroll(p_ptr->shield_power_opt, p_ptr->shield_power_opt2), &fear,
" is burned by your fiery shield."))
{
- blinked = FALSE;
- alive = FALSE;
+ blinked = false;
+ alive = false;
}
}
@@ -2647,14 +2662,14 @@ bool_ make_attack_normal(int m_idx, byte divis)
/* Increase fear */
tmp = m_ptr->monfear + p_ptr->shield_power_opt;
- fear = TRUE;
+ fear = true;
/* Set fear */
m_ptr->monfear = (tmp < 200) ? tmp : 200;
}
}
- touched = FALSE;
+ touched = false;
}
}
@@ -2707,7 +2722,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
}
/* Assume we attacked */
- return (TRUE);
+ return true;
}
diff --git a/src/melee1.hpp b/src/melee1.hpp
index 90ece431..f70d8b05 100644
--- a/src/melee1.hpp
+++ b/src/melee1.hpp
@@ -1,7 +1,7 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
int get_attack_power(int effect);
-bool_ carried_make_attack_normal(int r_idx);
-bool_ make_attack_normal(int m_idx, byte divis);
+bool carried_make_attack_normal(int r_idx);
+bool make_attack_normal(int m_idx, byte divis);
diff --git a/src/melee2.cc b/src/melee2.cc
index d769355a..3e697f7e 100644
--- a/src/melee2.cc
+++ b/src/melee2.cc
@@ -16,6 +16,7 @@
#include "cave.hpp"
#include "cave_type.hpp"
#include "cmd1.hpp"
+#include "config.hpp"
#include "dungeon_flag.hpp"
#include "feature_flag.hpp"
#include "feature_type.hpp"
@@ -47,10 +48,16 @@
#include "util.hpp"
#include "variable.hpp"
#include "xtra2.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
+#include "z-util.hpp"
+#include <boost/algorithm/string/predicate.hpp>
#include <cassert>
+using boost::algorithm::equals;
+
#define SPEAK_CHANCE 8
#define GRINDNOISE 20
@@ -61,7 +68,7 @@
* Based on mon_take_hit... all monster attacks on
* other monsters should use
*/
-bool_ mon_take_hit_mon(int s_idx, int m_idx, int dam, bool_ *fear, cptr note)
+bool mon_take_hit_mon(int s_idx, int m_idx, int dam, const char *note)
{
monster_type *m_ptr = &m_list[m_idx], *s_ptr = &m_list[s_idx];
@@ -92,7 +99,10 @@ bool_ mon_take_hit_mon(int s_idx, int m_idx, int dam, bool_ *fear, cptr note)
/* Some monsters are immune to death */
auto const r_ptr = m_ptr->race();
- if (r_ptr->flags & RF_NO_DEATH) return FALSE;
+ if (r_ptr->flags & RF_NO_DEATH)
+ {
+ return false;
+ }
/* Wake it up */
m_ptr->csleep = 0;
@@ -145,7 +155,7 @@ bool_ mon_take_hit_mon(int s_idx, int m_idx, int dam, bool_ *fear, cptr note)
if (!dive) dive = 1;
/* Monster gains some xp */
- monster_gain_exp(s_idx, dive, FALSE);
+ monster_gain_exp(s_idx, dive);
/* Monster lore skill allows gaining xp from pets */
if (get_skill(SKILL_LORE) && (s_ptr->status >= MSTATUS_PET))
@@ -193,24 +203,21 @@ bool_ mon_take_hit_mon(int s_idx, int m_idx, int dam, bool_ *fear, cptr note)
/* Delete the monster */
delete_monster_idx(m_idx);
- /* Not afraid */
- (*fear) = FALSE;
-
/* Monster is dead */
- return (TRUE);
+ return true;
}
}
/* Apply fear */
- mon_handle_fear(m_ptr, dam, fear);
+ mon_handle_fear(m_ptr, dam, nullptr);
/* Not dead yet */
- return (FALSE);
+ return false;
}
-void mon_handle_fear(monster_type *m_ptr, int dam, bool_ *fear)
+void mon_handle_fear(monster_type *m_ptr, int dam, bool *fear)
{
assert(m_ptr != NULL);
@@ -233,7 +240,10 @@ void mon_handle_fear(monster_type *m_ptr, int dam, bool_ *fear)
m_ptr->monfear = 0;
/* No more fear */
- (*fear) = FALSE;
+ if (fear != nullptr)
+ {
+ (*fear) = false;
+ }
}
}
@@ -254,7 +264,10 @@ void mon_handle_fear(monster_type *m_ptr, int dam, bool_ *fear)
((dam >= m_ptr->hp) && (rand_int(100) < 80)))
{
/* Hack -- note fear */
- (*fear) = TRUE;
+ if (fear != nullptr)
+ {
+ (*fear) = true;
+ }
/* XXX XXX XXX Hack -- Add some timed fear */
m_ptr->monfear = (randint(10) +
@@ -297,7 +310,7 @@ void mon_handle_fear(monster_type *m_ptr, int dam, bool_ *fear)
/*
* Internal probability routine
*/
-static bool_ int_outof(std::shared_ptr<monster_race> r_ptr, int prob)
+static bool int_outof(std::shared_ptr<monster_race> r_ptr, int prob)
{
/* Non-Smart monsters are half as "smart" */
if (!(r_ptr->flags & RF_SMART)) prob = prob / 2;
@@ -544,7 +557,7 @@ static void remove_bad_spells(int m_idx, monster_spell_flag_set *spells_p)
* Determine if there is a space near the player in which
* a summoned creature can appear
*/
-static bool_ summon_possible(int y1, int x1)
+static bool summon_possible(int y1, int x1)
{
int y, x;
@@ -564,18 +577,14 @@ static bool_ summon_possible(int y1, int x1)
if (cave[y][x].feat == FEAT_MINOR_GLYPH) continue;
/* Nor on the between */
- if (cave[y][x].feat == FEAT_BETWEEN) return (FALSE);
-
- /* ...nor on the Pattern */
- if ((cave[y][x].feat >= FEAT_PATTERN_START)
- && (cave[y][x].feat <= FEAT_PATTERN_XTRA2)) continue;
+ if (cave[y][x].feat == FEAT_BETWEEN) return false;
/* Require empty floor grid in line of sight */
- if (cave_empty_bold(y, x) && los(y1, x1, y, x)) return (TRUE);
+ if (cave_empty_bold(y, x) && los(y1, x1, y, x)) return true;
}
}
- return FALSE;
+ return false;
}
@@ -583,10 +592,10 @@ static bool_ summon_possible(int y1, int x1)
/*
* Determine if a bolt spell will hit the player.
*
- * This is exactly like "projectable", but it will return FALSE if a monster
+ * This is exactly like "projectable", but it will return false if a monster
* is in the way.
*/
-static bool_ clean_shot(int y1, int x1, int y2, int x2)
+static bool clean_shot(int y1, int x1, int y2, int x2)
{
int dist, y, x;
@@ -606,14 +615,14 @@ static bool_ clean_shot(int y1, int x1, int y2, int x2)
}
/* Check for arrival at "final target" */
- if ((x == x2) && (y == y2)) return (TRUE);
+ if ((x == x2) && (y == y2)) return true;
/* Calculate the new location */
mmove2(&y, &x, y1, x1, y2, x2);
}
/* Assume obstruction */
- return (FALSE);
+ return false;
}
@@ -893,7 +902,7 @@ static void monst_bolt_monst(int m_idx, int y, int x, int typ, int dam_hp)
}
-static void monster_msg(cptr fmt, ...)
+static void monster_msg(const char *fmt, ...)
{
va_list vp;
@@ -912,7 +921,7 @@ static void monster_msg(cptr fmt, ...)
monster_msg_simple(buf);
}
-void monster_msg_simple(cptr s)
+void monster_msg_simple(const char *s)
{
auto &messages = game->messages;
@@ -952,1397 +961,1387 @@ static std::vector<monster_spell const *> extract_spells(monster_spell_flag_set
* at another monster.
*/
int monst_spell_monst_spell = -1;
-static bool_ monst_spell_monst(int m_idx)
+
+static bool monst_spell_monst(int m_idx)
{
static const monster_spell_flag_set SF_INT_MASK = compute_smart_mask();
- int y = 0, x = 0;
- char m_name[80], t_name[80];
- char m_poss[80];
- char ddesc[80];
- monster_type *m_ptr = &m_list[m_idx]; /* Attacker */
- bool_ direct = TRUE;
- bool_ wake_up = FALSE;
-
- /* Extract the blind-ness */
- bool_ blind = (p_ptr->blind ? TRUE : FALSE);
-
- /* Extract the "see-able-ness" */
- bool_ seen = (!blind && m_ptr->ml);
-
- bool_ see_m;
- bool_ see_t;
- bool_ see_either;
- bool_ see_both;
-
- bool_ friendly = FALSE;
+ auto const &dungeon_flags = game->dungeon_flags;
- if (is_friend(m_ptr) > 0) friendly = TRUE;
+ monster_type *m_ptr = &m_list[m_idx]; /* Attacker */
+ bool wake_up = false;
/* Cannot cast spells when confused */
- if (m_ptr->confused) return (FALSE);
+ if (m_ptr->confused)
+ {
+ return false;
+ }
+
+ // Shorthand and/or optimization
+ auto const blind = p_ptr->blind;
+ auto const seen = (!blind && m_ptr->ml);
+ auto const friendly = (is_friend(m_ptr) > 0);
/* Hack -- Extract the spell probability */
const auto r_ptr = m_ptr->race();
const int chance = (r_ptr->freq_inate + r_ptr->freq_spell) / 2;
/* Not allowed to cast spells */
- if ((!chance) && (monst_spell_monst_spell == -1)) return (FALSE);
+ if ((!chance) && (monst_spell_monst_spell == -1))
+ {
+ return false;
+ }
- if ((rand_int(100) >= chance) && (monst_spell_monst_spell == -1)) return (FALSE);
+ if ((rand_int(100) >= chance) && (monst_spell_monst_spell == -1))
+ {
+ return false;
+ }
/* Make sure monster actually has a target */
if (m_ptr->target <= 0)
{
- return FALSE;
+ return false;
}
- {
- int t_idx = m_ptr->target;
+ int t_idx = m_ptr->target;
- monster_type *t_ptr = &m_list[t_idx];
- auto const tr_ptr = t_ptr->race();
+ monster_type *t_ptr = &m_list[t_idx];
+ auto const tr_ptr = t_ptr->race();
- /* Hack -- no fighting >100 squares from player */
- if (t_ptr->cdis > MAX_RANGE) return FALSE;
+ /* Hack -- no fighting >100 squares from player */
+ if (t_ptr->cdis > MAX_RANGE)
+ {
+ return false;
+ }
- /* Monster must be projectable */
- if (!projectable(m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx)) return FALSE;
+ /* Monster must be projectable */
+ if (!projectable(m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx))
+ {
+ return false;
+ }
+
+ /* OK -- we-ve got a target */
+ int const y = t_ptr->fy;
+ int const x = t_ptr->fx;
- /* OK -- we-ve got a target */
- y = t_ptr->fy;
- x = t_ptr->fx;
+ /* Extract the monster level */
+ const int rlev = ((m_ptr->level >= 1) ? m_ptr->level : 1);
- /* Extract the monster level */
- const int rlev = ((m_ptr->level >= 1) ? m_ptr->level : 1);
+ /* Which spells are allowed? */
+ monster_spell_flag_set allowed_spells = r_ptr->spells;
- /* Which spells are allowed? */
- monster_spell_flag_set allowed_spells = r_ptr->spells;
+ /* Hack -- allow "desperate" spells */
+ if ((r_ptr->flags & RF_SMART) &&
+ (m_ptr->hp < m_ptr->maxhp / 10) &&
+ (rand_int(100) < 50))
+ {
+ /* Require intelligent spells */
+ allowed_spells &= SF_INT_MASK;
- /* Hack -- allow "desperate" spells */
- if ((r_ptr->flags & RF_SMART) &&
- (m_ptr->hp < m_ptr->maxhp / 10) &&
- (rand_int(100) < 50))
+ /* No spells left? */
+ if ((!allowed_spells) && (monst_spell_monst_spell == -1))
{
- /* Require intelligent spells */
- allowed_spells &= SF_INT_MASK;
-
- /* No spells left? */
- if ((!allowed_spells) && (monst_spell_monst_spell == -1)) return (FALSE);
+ return false;
}
+ }
- /* Extract spells */
- auto spell = extract_spells(allowed_spells);
+ /* Extract spells */
+ auto spell = extract_spells(allowed_spells);
- /* No spells left? */
- if (spell.empty()) return (FALSE);
+ /* No spells left? */
+ if (spell.empty())
+ {
+ return false;
+ }
- /* Stop if player is dead or gone */
- if (!alive || death) return (FALSE);
+ /* Stop if player is dead or gone */
+ if (!alive || death)
+ {
+ return false;
+ }
- /* Handle "leaving" */
- if (p_ptr->leaving) return (FALSE);
+ /* Handle "leaving" */
+ if (p_ptr->leaving)
+ {
+ return false;
+ }
- /* Get the monster name (or "it") */
- monster_desc(m_name, m_ptr, 0x00);
+ /* Get the monster name (or "it") */
+ char m_name[80];
+ monster_desc(m_name, m_ptr, 0x00);
- /* Get the monster possessive ("his"/"her"/"its") */
- monster_desc(m_poss, m_ptr, 0x22);
+ /* Get the monster possessive ("his"/"her"/"its") */
+ char m_poss[80];
+ monster_desc(m_poss, m_ptr, 0x22);
- /* Get the target's name (or "it") */
- monster_desc(t_name, t_ptr, 0x00);
+ /* Get the target's name (or "it") */
+ char t_name[80];
+ monster_desc(t_name, t_ptr, 0x00);
- /* Hack -- Get the "died from" name */
- monster_desc(ddesc, m_ptr, 0x88);
+ /* Hack -- Get the "died from" name */
+ char ddesc[80];
+ monster_desc(ddesc, m_ptr, 0x88);
- /* Choose a spell to cast */
- auto thrown_spell = spell[rand_int(spell.size())];
+ /* Choose a spell to cast */
+ auto thrown_spell = spell[rand_int(spell.size())];
- /* Force a spell ? */
- if (monst_spell_monst_spell > -1)
+ /* Force a spell ? */
+ if (monst_spell_monst_spell > -1)
+ {
+ thrown_spell = spell[monst_spell_monst_spell];
+ monst_spell_monst_spell = -1;
+ }
+
+ auto const see_m = seen;
+ auto const see_t = !blind && t_ptr->ml;
+ auto const see_either = see_m || see_t;
+ auto const see_both = see_m && see_t;
+
+ /* Do a breath */
+ auto do_breath = [&](char const *element, int gf, s32b max, int divisor) -> void {
+ // Interrupt
+ disturb_on_other();
+ // Message
+ if (!see_either)
+ {
+ monster_msg("You hear breathing noise.");
+ }
+ else if (blind)
+ {
+ monster_msg("%^s breathes.", m_name);
+ }
+ else
{
- thrown_spell = spell[monst_spell_monst_spell];
- monst_spell_monst_spell = -1;
+ monster_msg("%^s breathes %s at %s.", m_name, element, t_name);
}
+ // Breathe
+ monst_breath_monst(m_idx, y, x, gf, std::min(max, m_ptr->hp / divisor), 0);
+ };
- see_m = seen;
- see_t = (!blind && t_ptr->ml);
- see_either = (see_m || see_t);
- see_both = (see_m && see_t);
+ /* Messages for summoning */
+ struct summon_messages {
+ char const *singular;
+ char const *plural;
+ };
- /* Do a breath */
- auto do_breath = [&](char const *element, int gf, s32b max, int divisor) -> void {
- // Interrupt
- disturb_on_other();
- // Message
- if (!see_either)
+ /* Default message for summoning when player is blinded */
+ auto blind_msg_default = summon_messages {
+ "You hear something appear nearby.",
+ "You hear many things appear nearby."
+ };
+
+ /* Do a summoning spell */
+ auto do_summon = [&](char const *action, int n, int friendly_type, int hostile_type, summon_messages const &blind_msg) -> void {
+ // Interrupt
+ disturb_on_other();
+
+ // Message
+ if (blind || !see_m)
+ {
+ monster_msg("%^s mumbles.", m_name);
+ }
+ else
+ {
+ monster_msg("%^s magically %s", m_name, action);
+ }
+
+ // Do the actual summoning
+ int count = 0;
+ for (int k = 0; k < n; k++)
+ {
+ if (friendly)
{
- monster_msg("You hear breathing noise.");
+ count += summon_specific_friendly(m_ptr->fy, m_ptr->fx, rlev, friendly_type, true);
}
- else if (blind)
+ else if (!friendly)
{
- monster_msg("%^s breathes.", m_name);
+ count += summon_specific(m_ptr->fy, m_ptr->fx, rlev, hostile_type);
}
- else
+ }
+ // Message for blinded characters
+ if (blind)
+ {
+ if (count == 1)
{
- monster_msg("%^s breathes %s at %s.", m_name, element, t_name);
+ monster_msg(blind_msg.singular);
}
- // Breathe
- monst_breath_monst(m_idx, y, x, gf, std::min(max, m_ptr->hp / divisor), 0);
- };
+ else if (count > 1)
+ {
+ monster_msg(blind_msg.plural);
+ }
+ }
+ };
- /* Messages for summoning */
- struct summon_messages {
- char const *singular;
- char const *plural;
- };
+ /* There's no summoning friendly uniques or Nazgul */
+ auto spell_idx = thrown_spell->spell_idx;
- /* Default message for summoning when player is blinded */
- auto blind_msg_default = summon_messages {
- "You hear something appear nearby.",
- "You hear many things appear nearby."
- };
+ if (friendly)
+ {
+ if ((thrown_spell->spell_idx == SF_S_UNIQUE_IDX) &&
+ (thrown_spell->spell_idx == SF_S_WRAITH_IDX))
+ {
+ // Summon high undead instead
+ spell_idx = SF_S_HI_UNDEAD_IDX;
+ }
+ }
- /* Do a summoning spell */
- auto do_summon = [&](char const *action, int n, int friendly_type, int hostile_type, summon_messages const &blind_msg) -> void {
- // Interrupt
+ /* Spell effect */
+ switch (spell_idx)
+ {
+ case SF_SHRIEK_IDX:
+ {
disturb_on_other();
+ if (!see_m) monster_msg("You hear a shriek.");
+ else monster_msg("%^s shrieks at %s.", m_name, t_name);
+ wake_up = true;
+ break;
+ }
- // Message
- if (blind || !see_m)
- {
- monster_msg("%^s mumbles.", m_name);
- }
- else
- {
- monster_msg("%^s magically %s", m_name, action);
- }
+ case SF_MULTIPLY_IDX:
+ {
+ break;
+ }
- // Do the actual summoning
- int count = 0;
- for (int k = 0; k < n; k++)
- {
- if (friendly)
- {
- count += summon_specific_friendly(m_ptr->fy, m_ptr->fx, rlev, friendly_type, TRUE);
- }
- else if (!friendly)
- {
- count += summon_specific(m_ptr->fy, m_ptr->fx, rlev, hostile_type);
- }
- }
- // Message for blinded characters
- if (blind)
- {
- if (count == 1)
- {
- monster_msg(blind_msg.singular);
- }
- else if (count > 1)
- {
- monster_msg(blind_msg.plural);
- }
- }
- };
+ case SF_ROCKET_IDX:
+ {
+ disturb_on_other();
+ if (!see_either) monster_msg("You hear an explosion!");
+ else if (blind) monster_msg("%^s shoots something.", m_name);
+ else monster_msg("%^s fires a rocket at %s.", m_name, t_name);
+ monst_breath_monst(m_idx, y, x, GF_ROCKET,
+ ((m_ptr->hp / 4) > 800 ? 800 : (m_ptr->hp / 4)), 2);
+ break;
+ }
- /* There's no summoning friendly uniques or Nazgul */
- auto spell_idx = thrown_spell->spell_idx;
+ case SF_ARROW_1_IDX:
+ {
+ disturb_on_other();
+ if (!see_either) monster_msg("You hear a strange noise.");
+ else if (blind) monster_msg("%^s makes a strange noise.", m_name);
+ else monster_msg("%^s fires an arrow at %s.", m_name, t_name);
+ monst_bolt_monst(m_idx, y, x, GF_ARROW, damroll(1, 6));
+ break;
+ }
- if (friendly)
+ case SF_ARROW_2_IDX:
{
- if ((thrown_spell->spell_idx == SF_S_UNIQUE_IDX) &&
- (thrown_spell->spell_idx == SF_S_WRAITH_IDX))
- {
- // Summon high undead instead
- spell_idx = SF_S_HI_UNDEAD_IDX;
- }
+ disturb_on_other();
+ if (!see_either) monster_msg("You hear a strange noise.");
+ else if (blind) monster_msg("%^s makes a strange noise.", m_name);
+ else monster_msg("%^s fires an arrow at %s.", m_name, t_name);
+ monst_bolt_monst(m_idx, y, x, GF_ARROW, damroll(3, 6));
+ break;
}
- /* Spell effect */
- switch (spell_idx)
+ case SF_ARROW_3_IDX:
{
- case SF_SHRIEK_IDX:
- {
- if (!direct) break;
- disturb_on_other();
- if (!see_m) monster_msg("You hear a shriek.");
- else monster_msg("%^s shrieks at %s.", m_name, t_name);
- wake_up = TRUE;
- break;
- }
+ disturb_on_other();
- case SF_MULTIPLY_IDX:
- {
- break;
- }
+ if (!see_either) monster_msg("You hear a strange noise.");
+ else if (blind) monster_msg("%^s makes a strange noise.", m_name);
+ else monster_msg("%^s fires a missile at %s.", m_name, t_name);
+ monst_bolt_monst(m_idx, y, x, GF_ARROW, damroll(5, 6));
+ break;
+ }
- case SF_ROCKET_IDX:
- {
- disturb_on_other();
- if (!see_either) monster_msg("You hear an explosion!");
- else if (blind) monster_msg("%^s shoots something.", m_name);
- else monster_msg("%^s fires a rocket at %s.", m_name, t_name);
- monst_breath_monst(m_idx, y, x, GF_ROCKET,
- ((m_ptr->hp / 4) > 800 ? 800 : (m_ptr->hp / 4)), 2);
- break;
- }
+ case SF_ARROW_4_IDX:
+ {
+ if (!see_either) monster_msg("You hear a strange noise.");
+ else disturb_on_other();
+ if (blind) monster_msg("%^s makes a strange noise.", m_name);
+ else monster_msg("%^s fires a missile at %s.", m_name, t_name);
+ monst_bolt_monst(m_idx, y, x, GF_ARROW, damroll(7, 6));
+ break;
+ }
- case SF_ARROW_1_IDX:
- {
- disturb_on_other();
- if (!see_either) monster_msg("You hear a strange noise.");
- else if (blind) monster_msg("%^s makes a strange noise.", m_name);
- else monster_msg("%^s fires an arrow at %s.", m_name, t_name);
- monst_bolt_monst(m_idx, y, x, GF_ARROW, damroll(1, 6));
- break;
- }
+ case SF_BR_ACID_IDX:
+ {
+ do_breath("acid", GF_ACID, 1600, 3);
+ break;
+ }
- case SF_ARROW_2_IDX:
- {
- disturb_on_other();
- if (!see_either) monster_msg("You hear a strange noise.");
- else if (blind) monster_msg("%^s makes a strange noise.", m_name);
- else monster_msg("%^s fires an arrow at %s.", m_name, t_name);
- monst_bolt_monst(m_idx, y, x, GF_ARROW, damroll(3, 6));
- break;
- }
+ case SF_BR_ELEC_IDX:
+ {
+ do_breath("lightning", GF_ELEC, 1600, 3);
+ break;
+ }
- case SF_ARROW_3_IDX:
- {
- disturb_on_other();
+ case SF_BR_FIRE_IDX:
+ {
+ do_breath("fire", GF_FIRE, 1600, 3);
+ break;
+ }
- if (!see_either) monster_msg("You hear a strange noise.");
- else if (blind) monster_msg("%^s makes a strange noise.", m_name);
- else monster_msg("%^s fires a missile at %s.", m_name, t_name);
- monst_bolt_monst(m_idx, y, x, GF_ARROW, damroll(5, 6));
- break;
- }
+ case SF_BR_COLD_IDX:
+ {
+ do_breath("frost", GF_COLD, 1600, 3);
+ break;
+ }
- case SF_ARROW_4_IDX:
- {
- if (!see_either) monster_msg("You hear a strange noise.");
- else disturb_on_other();
- if (blind) monster_msg("%^s makes a strange noise.", m_name);
- else monster_msg("%^s fires a missile at %s.", m_name, t_name);
- monst_bolt_monst(m_idx, y, x, GF_ARROW, damroll(7, 6));
- break;
- }
+ case SF_BR_POIS_IDX:
+ {
+ do_breath("gas", GF_POIS, 800, 3);
+ break;
+ }
- case SF_BR_ACID_IDX:
- {
- do_breath("acid", GF_ACID, 1600, 3);
- break;
- }
+ case SF_BR_NETH_IDX:
+ {
+ do_breath("nether", GF_NETHER, 550, 6);
+ break;
+ }
- case SF_BR_ELEC_IDX:
- {
- do_breath("lightning", GF_ELEC, 1600, 3);
- break;
- }
+ case SF_BR_LITE_IDX:
+ {
+ do_breath("light", GF_LITE, 400, 6);
+ break;
+ }
- case SF_BR_FIRE_IDX:
- {
- do_breath("fire", GF_FIRE, 1600, 3);
- break;
- }
+ case SF_BR_DARK_IDX:
+ {
+ do_breath("darkness", GF_DARK, 400, 6);
+ break;
+ }
- case SF_BR_COLD_IDX:
- {
- do_breath("frost", GF_COLD, 1600, 3);
- break;
- }
+ case SF_BR_CONF_IDX:
+ {
+ do_breath("confusion", GF_CONFUSION, 400, 6);
+ break;
+ }
- case SF_BR_POIS_IDX:
- {
- do_breath("gas", GF_POIS, 800, 3);
- break;
- }
+ case SF_BR_SOUN_IDX:
+ {
+ do_breath("sound", GF_SOUND, 400, 6);
+ break;
+ }
- case SF_BR_NETH_IDX:
- {
- do_breath("nether", GF_NETHER, 550, 6);
- break;
- }
+ case SF_BR_CHAO_IDX:
+ {
+ do_breath("chaos", GF_CHAOS, 600, 6);
+ break;
+ }
- case SF_BR_LITE_IDX:
- {
- do_breath("light", GF_LITE, 400, 6);
- break;
- }
+ case SF_BR_DISE_IDX:
+ {
+ do_breath("disenchantment", GF_DISENCHANT, 500, 6);
+ break;
+ }
- case SF_BR_DARK_IDX:
- {
- do_breath("darkness", GF_DARK, 400, 6);
- break;
- }
+ case SF_BR_NEXU_IDX:
+ {
+ do_breath("nexus", GF_NEXUS, 250, 3);
+ break;
+ }
- case SF_BR_CONF_IDX:
- {
- do_breath("confusion", GF_CONFUSION, 400, 6);
- break;
- }
+ case SF_BR_TIME_IDX:
+ {
+ do_breath("time", GF_TIME, 150, 3);
+ break;
+ }
- case SF_BR_SOUN_IDX:
- {
- do_breath("sound", GF_SOUND, 400, 6);
- break;
- }
+ case SF_BR_INER_IDX:
+ {
+ do_breath("inertia", GF_INERTIA, 200, 6);
+ break;
+ }
- case SF_BR_CHAO_IDX:
- {
- do_breath("chaos", GF_CHAOS, 600, 6);
- break;
- }
+ case SF_BR_GRAV_IDX:
+ {
+ do_breath("gravity", GF_GRAVITY, 200, 3);
+ break;
+ }
- case SF_BR_DISE_IDX:
- {
- do_breath("disenchantment", GF_DISENCHANT, 500, 6);
- break;
- }
+ case SF_BR_SHAR_IDX:
+ {
+ do_breath("shards", GF_SHARDS, 400, 6);
+ break;
+ }
- case SF_BR_NEXU_IDX:
- {
- do_breath("nexus", GF_NEXUS, 250, 3);
- break;
- }
+ case SF_BR_PLAS_IDX:
+ {
+ do_breath("plasma", GF_PLASMA, 150, 6);
+ break;
+ }
- case SF_BR_TIME_IDX:
- {
- do_breath("time", GF_TIME, 150, 3);
- break;
- }
+ case SF_BR_WALL_IDX:
+ {
+ do_breath("force", GF_FORCE, 200, 6);
+ break;
+ }
- case SF_BR_INER_IDX:
- {
- do_breath("inertia", GF_INERTIA, 200, 6);
- break;
- }
+ case SF_BR_MANA_IDX:
+ {
+ do_breath("magical energy", GF_MANA, 250, 3);
+ break;
+ }
- case SF_BR_GRAV_IDX:
- {
- do_breath("gravity", GF_GRAVITY, 200, 3);
- break;
- }
+ case SF_BA_NUKE_IDX:
+ {
+ disturb_on_other();
+ if (!see_either) monster_msg("You hear someone mumble.");
+ else if (blind) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts a ball of radiation at %s.", m_name, t_name);
+ monst_breath_monst(m_idx, y, x, GF_NUKE,
+ (rlev + damroll(10, 6)), 2);
+ break;
+ }
- case SF_BR_SHAR_IDX:
+ case SF_BR_NUKE_IDX:
+ {
+ do_breath("toxic waste", GF_NUKE, 800, 3);
+ break;
+ }
+
+ case SF_BA_CHAO_IDX:
+ {
+ disturb_on_other();
+ if (!see_either) monster_msg("You hear someone mumble frighteningly.");
+ else if (blind) monster_msg("%^s mumbles frighteningly.", m_name);
+ else monster_msg("%^s invokes a raw Chaos upon %s.", m_name, t_name);
+ monst_breath_monst(m_idx, y, x, GF_CHAOS,
+ (rlev * 2) + damroll(10, 10), 4);
+ break;
+ }
+
+ case SF_BR_DISI_IDX:
+ {
+ do_breath("disintegration", GF_DISINTEGRATE, 300, 3);
+ break;
+ }
+
+ case SF_BA_ACID_IDX:
+ {
+ disturb_on_other();
+ if (!see_either) monster_msg ("You hear someone mumble.");
+ else if (blind) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts an acid ball at %s.", m_name, t_name);
+ monst_breath_monst(m_idx, y, x, GF_ACID, randint(rlev * 3) + 15, 2);
+ break;
+ }
+
+ case SF_BA_ELEC_IDX:
+ {
+ disturb_on_other();
+ if (!see_either) monster_msg ("You hear someone mumble.");
+ else
+ if (blind) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts a lightning ball at %s.", m_name, t_name);
+ monst_breath_monst(m_idx, y, x, GF_ELEC, randint(rlev * 3 / 2) + 8, 2);
+ break;
+ }
+
+ case SF_BA_FIRE_IDX:
+ {
+ disturb_on_other();
+ if (!see_either) monster_msg ("You hear someone mumble.");
+ else
+ if (blind) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts a fire ball at %s.", m_name, t_name);
+ monst_breath_monst(m_idx, y, x, GF_FIRE, randint(rlev * 7 / 2) + 10, 2);
+ break;
+ }
+
+ case SF_BA_COLD_IDX:
+ {
+ disturb_on_other();
+ if (!see_either) monster_msg ("You hear someone mumble.");
+ else
+ if (blind) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts a frost ball at %s.", m_name, t_name);
+ monst_breath_monst(m_idx, y, x, GF_COLD, randint(rlev * 3 / 2) + 10, 2);
+ break;
+ }
+
+ case SF_BA_POIS_IDX:
+ {
+ disturb_on_other();
+ if (!see_either) monster_msg ("You hear someone mumble.");
+ else
+ if (blind) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts a stinking cloud at %s.", m_name, t_name);
+ monst_breath_monst(m_idx, y, x, GF_POIS, damroll(12, 2), 2);
+ break;
+ }
+
+ case SF_BA_NETH_IDX:
+ {
+ disturb_on_other();
+ if (!see_either) monster_msg ("You hear someone mumble.");
+ else
+ if (blind) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts a nether ball at %s.", m_name, t_name);
+ monst_breath_monst(m_idx, y, x, GF_NETHER, (50 + damroll(10, 10) + rlev), 2);
+ break;
+ }
+
+ case SF_BA_WATE_IDX:
+ {
+ disturb_on_other();
+ if (!see_either) monster_msg ("You hear someone mumble.");
+ else
+ if (blind) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s gestures fluidly at %s.", m_name, t_name);
+ monster_msg("%^s is engulfed in a whirlpool.", t_name);
+ monst_breath_monst(m_idx, y, x, GF_WATER, randint(rlev * 5 / 2) + 50, 4);
+ break;
+ }
+
+ case SF_BA_MANA_IDX:
+ {
+ disturb_on_other();
+ if (!see_either) monster_msg ("You hear someone mumble powerfully.");
+ else
+ if (blind) monster_msg("%^s mumbles powerfully.", m_name);
+ else monster_msg("%^s invokes a mana storm upon %s.", m_name, t_name);
+ monst_breath_monst(m_idx, y, x, GF_MANA, (rlev * 5) + damroll(10, 10), 4);
+ break;
+ }
+
+ case SF_BA_DARK_IDX:
+ {
+ disturb_on_other();
+ if (!see_either) monster_msg ("You hear someone mumble powerfully.");
+ else
+ if (blind) monster_msg("%^s mumbles powerfully.", m_name);
+ else monster_msg("%^s invokes a darkness storm upon %s.", m_name, t_name);
+ monst_breath_monst(m_idx, y, x, GF_DARK, (rlev * 5) + damroll(10, 10), 4);
+ break;
+ }
+
+ case SF_DRAIN_MANA_IDX:
+ {
+ /* Attack power */
+ int r1 = (randint(rlev) / 2) + 1;
+
+ if (see_m)
{
- do_breath("shards", GF_SHARDS, 400, 6);
- break;
+ /* Basic message */
+ monster_msg("%^s draws psychic energy from %s.", m_name, t_name);
}
- case SF_BR_PLAS_IDX:
+ /* Heal the monster */
+ if (m_ptr->hp < m_ptr->maxhp)
{
- do_breath("plasma", GF_PLASMA, 150, 6);
- break;
+ if (!tr_ptr->spells)
+ {
+ if (see_both)
+ monster_msg("%^s is unaffected!", t_name);
+ }
+ else
+ {
+ /* Heal */
+ m_ptr->hp += (6 * r1);
+ if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
+
+ /* Redraw (later) if needed */
+ if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME);
+
+ /* Special message */
+ if (seen)
+ {
+ monster_msg("%^s appears healthier.", m_name);
+ }
+ }
}
- case SF_BR_WALL_IDX:
+ wake_up = true;
+ break;
+ }
+
+ case SF_MIND_BLAST_IDX:
+ {
+ disturb_on_other();
+
+ if (!seen)
{
- do_breath("force", GF_FORCE, 200, 6);
- break;
+ /* */
}
-
- case SF_BR_MANA_IDX:
+ else
{
- do_breath("magical energy", GF_MANA, 250, 3);
- break;
+ monster_msg("%^s gazes intently at %s.", m_name, t_name);
}
- case SF_BA_NUKE_IDX:
+ /* Attempt a saving throw */
+ if ((tr_ptr->flags & RF_UNIQUE) ||
+ (tr_ptr->flags & RF_NO_CONF) ||
+ (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10))
{
- disturb_on_other();
- if (!see_either) monster_msg("You hear someone mumble.");
- else if (blind) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts a ball of radiation at %s.", m_name, t_name);
- monst_breath_monst(m_idx, y, x, GF_NUKE,
- (rlev + damroll(10, 6)), 2);
- break;
+ /* No obvious effect */
+ if (see_t)
+ {
+ monster_msg("%^s is unaffected!", t_name);
+ }
}
-
- case SF_BR_NUKE_IDX:
+ else
{
- do_breath("toxic waste", GF_NUKE, 800, 3);
- break;
+ monster_msg("%^s is blasted by psionic energy.", t_name);
+ t_ptr->confused += rand_int(4) + 4;
+
+ mon_take_hit_mon(m_idx, t_idx, damroll(8, 8), " collapses, a mindless husk.");
}
- case SF_BA_CHAO_IDX:
+ wake_up = true;
+ break;
+ }
+
+ case SF_BRAIN_SMASH_IDX:
+ {
+ disturb_on_other();
+ if (!seen)
{
- disturb_on_other();
- if (!see_either) monster_msg("You hear someone mumble frighteningly.");
- else if (blind) monster_msg("%^s mumbles frighteningly.", m_name);
- else monster_msg("%^s invokes a raw Chaos upon %s.", m_name, t_name);
- monst_breath_monst(m_idx, y, x, GF_CHAOS,
- (rlev * 2) + damroll(10, 10), 4);
- break;
+ /* */
}
-
- case SF_BR_DISI_IDX:
+ else
{
- do_breath("disintegration", GF_DISINTEGRATE, 300, 3);
- break;
+ monster_msg("%^s gazes intently at %s.", m_name, t_name);
}
- case SF_BA_ACID_IDX:
+ /* Attempt a saving throw */
+ if ((tr_ptr->flags & RF_UNIQUE) ||
+ (tr_ptr->flags & RF_NO_CONF) ||
+ (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10))
{
- disturb_on_other();
- if (!see_either) monster_msg ("You hear someone mumble.");
- else if (blind) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts an acid ball at %s.", m_name, t_name);
- monst_breath_monst(m_idx, y, x, GF_ACID, randint(rlev * 3) + 15, 2);
- break;
+ /* No obvious effect */
+ if (see_t)
+ {
+ monster_msg("%^s is unaffected!", t_name);
+ }
}
-
- case SF_BA_ELEC_IDX:
+ else
{
- disturb_on_other();
- if (!see_either) monster_msg ("You hear someone mumble.");
- else
- if (blind) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts a lightning ball at %s.", m_name, t_name);
- monst_breath_monst(m_idx, y, x, GF_ELEC, randint(rlev * 3 / 2) + 8, 2);
- break;
+ if (see_t)
+ {
+ monster_msg("%^s is blasted by psionic energy.", t_name);
+ }
+ t_ptr->confused += rand_int(4) + 4;
+ t_ptr->mspeed -= rand_int(4) + 4;
+ t_ptr->stunned += rand_int(4) + 4;
+ mon_take_hit_mon(m_idx, t_idx, damroll(12, 15), " collapses, a mindless husk.");
}
+ wake_up = true;
+ break;
+ }
- case SF_BA_FIRE_IDX:
+ case SF_CAUSE_1_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s points at %s and curses.", m_name, t_name);
+ if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
{
- disturb_on_other();
- if (!see_either) monster_msg ("You hear someone mumble.");
- else
- if (blind) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts a fire ball at %s.", m_name, t_name);
- monst_breath_monst(m_idx, y, x, GF_FIRE, randint(rlev * 7 / 2) + 10, 2);
- break;
- }
- case SF_BA_COLD_IDX:
+ if (see_t) monster_msg("%^s resists!", t_name);
+ }
+ else
{
- disturb_on_other();
- if (!see_either) monster_msg ("You hear someone mumble.");
- else
- if (blind) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts a frost ball at %s.", m_name, t_name);
- monst_breath_monst(m_idx, y, x, GF_COLD, randint(rlev * 3 / 2) + 10, 2);
- break;
+ mon_take_hit_mon(m_idx, t_idx, damroll(3, 8), " is destroyed.");
}
+ wake_up = true;
+ break;
+ }
- case SF_BA_POIS_IDX:
+ case SF_CAUSE_2_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s points at %s and curses horribly.", m_name, t_name);
+ if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
{
- disturb_on_other();
- if (!see_either) monster_msg ("You hear someone mumble.");
- else
- if (blind) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts a stinking cloud at %s.", m_name, t_name);
- monst_breath_monst(m_idx, y, x, GF_POIS, damroll(12, 2), 2);
- break;
+ if (see_t) monster_msg("%^s resists!", t_name);
}
-
- case SF_BA_NETH_IDX:
+ else
{
- disturb_on_other();
- if (!see_either) monster_msg ("You hear someone mumble.");
- else
- if (blind) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts a nether ball at %s.", m_name, t_name);
- monst_breath_monst(m_idx, y, x, GF_NETHER, (50 + damroll(10, 10) + rlev), 2);
- break;
+ mon_take_hit_mon(m_idx, t_idx, damroll(8, 8), " is destroyed.");
}
+ wake_up = true;
+ break;
+ }
- case SF_BA_WATE_IDX:
+ case SF_CAUSE_3_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s points at %s, incanting terribly!", m_name, t_name);
+ if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
{
- disturb_on_other();
- if (!see_either) monster_msg ("You hear someone mumble.");
- else
- if (blind) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s gestures fluidly at %s.", m_name, t_name);
- monster_msg("%^s is engulfed in a whirlpool.", t_name);
- monst_breath_monst(m_idx, y, x, GF_WATER, randint(rlev * 5 / 2) + 50, 4);
- break;
+ if (see_t) monster_msg("%^s resists!", t_name);
}
-
- case SF_BA_MANA_IDX:
+ else
{
- disturb_on_other();
- if (!see_either) monster_msg ("You hear someone mumble powerfully.");
- else
- if (blind) monster_msg("%^s mumbles powerfully.", m_name);
- else monster_msg("%^s invokes a mana storm upon %s.", m_name, t_name);
- monst_breath_monst(m_idx, y, x, GF_MANA, (rlev * 5) + damroll(10, 10), 4);
- break;
+ mon_take_hit_mon(m_idx, t_idx, damroll(10, 15), " is destroyed.");
}
+ wake_up = true;
+ break;
+ }
- case SF_BA_DARK_IDX:
+ case SF_CAUSE_4_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s points at %s, screaming the word 'DIE!'", m_name, t_name);
+ if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
{
- disturb_on_other();
- if (!see_either) monster_msg ("You hear someone mumble powerfully.");
- else
- if (blind) monster_msg("%^s mumbles powerfully.", m_name);
- else monster_msg("%^s invokes a darkness storm upon %s.", m_name, t_name);
- monst_breath_monst(m_idx, y, x, GF_DARK, (rlev * 5) + damroll(10, 10), 4);
- break;
+ if (see_t) monster_msg("%^s resists!", t_name);
}
-
- case SF_DRAIN_MANA_IDX:
+ else
{
- /* Attack power */
- int r1 = (randint(rlev) / 2) + 1;
+ mon_take_hit_mon(m_idx, t_idx, damroll(15, 15), " is destroyed.");
+ }
+ wake_up = true;
+ break;
+ }
- if (see_m)
- {
- /* Basic message */
- monster_msg("%^s draws psychic energy from %s.", m_name, t_name);
- }
+ case SF_BO_ACID_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts an acid bolt at %s.", m_name, t_name);
+ monst_bolt_monst(m_idx, y, x, GF_ACID,
+ damroll(7, 8) + (rlev / 3));
+ break;
+ }
- /* Heal the monster */
- if (m_ptr->hp < m_ptr->maxhp)
- {
- if (!tr_ptr->spells)
- {
- if (see_both)
- monster_msg("%^s is unaffected!", t_name);
- }
- else
- {
- /* Heal */
- m_ptr->hp += (6 * r1);
- if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
+ case SF_BO_ELEC_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts a lightning bolt at %s.", m_name, t_name);
+ monst_bolt_monst(m_idx, y, x, GF_ELEC,
+ damroll(4, 8) + (rlev / 3));
+ break;
+ }
- /* Redraw (later) if needed */
- if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME);
+ case SF_BO_FIRE_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts a fire bolt at %s.", m_name, t_name);
+ monst_bolt_monst(m_idx, y, x, GF_FIRE,
+ damroll(9, 8) + (rlev / 3));
+ break;
+ }
- /* Special message */
- if (seen)
- {
- monster_msg("%^s appears healthier.", m_name);
- }
- }
- }
+ case SF_BO_COLD_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts a frost bolt at %s.", m_name, t_name);
+ monst_bolt_monst(m_idx, y, x, GF_COLD,
+ damroll(6, 8) + (rlev / 3));
+ break;
+ }
- wake_up = TRUE;
- break;
- }
+ case SF_BO_POIS_IDX:
+ {
+ /* XXX XXX XXX */
+ break;
+ }
- case SF_MIND_BLAST_IDX:
- {
- if (!direct) break;
+ case SF_BO_NETH_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts a nether bolt at %s.", m_name, t_name);
+ monst_bolt_monst(m_idx, y, x, GF_NETHER,
+ 30 + damroll(5, 5) + (rlev * 3) / 2);
+ break;
+ }
- disturb_on_other();
+ case SF_BO_WATE_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts a water bolt at %s.", m_name, t_name);
+ monst_bolt_monst(m_idx, y, x, GF_WATER,
+ damroll(10, 10) + (rlev));
+ break;
+ }
- if (!seen)
- {
- /* */
- }
- else
- {
- monster_msg("%^s gazes intently at %s.", m_name, t_name);
- }
+ case SF_BO_MANA_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts a mana bolt at %s.", m_name, t_name);
+ monst_bolt_monst(m_idx, y, x, GF_MANA,
+ randint(rlev * 7 / 2) + 50);
+ break;
+ }
- /* Attempt a saving throw */
- if ((tr_ptr->flags & RF_UNIQUE) ||
- (tr_ptr->flags & RF_NO_CONF) ||
- (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10))
- {
- /* No obvious effect */
- if (see_t)
- {
- monster_msg("%^s is unaffected!", t_name);
- }
- }
- else
- {
- bool_ fear;
- monster_msg("%^s is blasted by psionic energy.", t_name);
- t_ptr->confused += rand_int(4) + 4;
+ case SF_BO_PLAS_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts a plasma bolt at %s.", m_name, t_name);
+ monst_bolt_monst(m_idx, y, x, GF_PLASMA,
+ 10 + damroll(8, 7) + (rlev));
+ break;
+ }
- mon_take_hit_mon(m_idx, t_idx, damroll(8, 8), &fear, " collapses, a mindless husk.");
- }
+ case SF_BO_ICEE_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts an ice bolt at %s.", m_name, t_name);
+ monst_bolt_monst(m_idx, y, x, GF_ICE,
+ damroll(6, 6) + (rlev));
+ break;
+ }
- wake_up = TRUE;
- break;
- }
+ case SF_MISSILE_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts a magic missile at %s.", m_name, t_name);
+ monst_bolt_monst(m_idx, y, x, GF_MISSILE,
+ damroll(2, 6) + (rlev / 3));
+ break;
+ }
- case SF_BRAIN_SMASH_IDX:
+ case SF_SCARE_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m) monster_msg("%^s mumbles, and you hear scary noises.", m_name);
+ else monster_msg("%^s casts a fearful illusion at %s.", m_name, t_name);
+ if (tr_ptr->flags & RF_NO_FEAR)
{
- if (!direct) break;
- disturb_on_other();
- if (!seen)
- {
- /* */
- }
- else
- {
- monster_msg("%^s gazes intently at %s.", m_name, t_name);
- }
-
- /* Attempt a saving throw */
- if ((tr_ptr->flags & RF_UNIQUE) ||
- (tr_ptr->flags & RF_NO_CONF) ||
- (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10))
- {
- /* No obvious effect */
- if (see_t)
- {
- monster_msg("%^s is unaffected!", t_name);
- }
- }
- else
- {
- bool_ fear;
- if (see_t)
- {
- monster_msg("%^s is blasted by psionic energy.", t_name);
- }
- t_ptr->confused += rand_int(4) + 4;
- t_ptr->mspeed -= rand_int(4) + 4;
- t_ptr->stunned += rand_int(4) + 4;
- mon_take_hit_mon(m_idx, t_idx, damroll(12, 15), &fear, " collapses, a mindless husk.");
- }
- wake_up = TRUE;
- break;
+ if (see_t) monster_msg("%^s refuses to be frightened.", t_name);
}
-
- case SF_CAUSE_1_IDX:
+ else if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
{
- if (!direct) break;
- disturb_on_other();
- if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s points at %s and curses.", m_name, t_name);
- if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
- {
-
- if (see_t) monster_msg("%^s resists!", t_name);
- }
- else
- {
- bool_ fear;
- mon_take_hit_mon(m_idx, t_idx, damroll(3, 8), &fear, " is destroyed.");
- }
- wake_up = TRUE;
- break;
+ if (see_t) monster_msg("%^s refuses to be frightened.", t_name);
}
-
- case SF_CAUSE_2_IDX:
+ else
{
- if (!direct) break;
- disturb_on_other();
- if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s points at %s and curses horribly.", m_name, t_name);
- if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
- {
- if (see_t) monster_msg("%^s resists!", t_name);
- }
- else
- {
- bool_ fear;
- mon_take_hit_mon(m_idx, t_idx, damroll(8, 8), &fear, " is destroyed.");
- }
- wake_up = TRUE;
- break;
+ if (!(t_ptr->monfear) && see_t) monster_msg("%^s flees in terror!", t_name);
+ t_ptr->monfear += rand_int(4) + 4;
}
+ wake_up = true;
+ break;
+ }
- case SF_CAUSE_3_IDX:
+ case SF_BLIND_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s casts a spell, burning %s%s eyes.", m_name, t_name,
+ (equals(t_name, "it") ? "s" : "'s"));
+ if (tr_ptr->flags & RF_NO_CONF) /* Simulate blindness with confusion */
{
- if (!direct) break;
- disturb_on_other();
- if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s points at %s, incanting terribly!", m_name, t_name);
- if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
- {
- if (see_t) monster_msg("%^s resists!", t_name);
- }
- else
- {
- bool_ fear;
- mon_take_hit_mon(m_idx, t_idx, damroll(10, 15), &fear, " is destroyed.");
- }
- wake_up = TRUE;
- break;
+ if (see_t) monster_msg("%^s is unaffected.", t_name);
}
-
- case SF_CAUSE_4_IDX:
+ else if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
{
- if (!direct) break;
- disturb_on_other();
- if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s points at %s, screaming the word 'DIE!'", m_name, t_name);
- if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
- {
- if (see_t) monster_msg("%^s resists!", t_name);
- }
- else
- {
- bool_ fear;
- mon_take_hit_mon(m_idx, t_idx, damroll(15, 15), &fear, " is destroyed.");
- }
- wake_up = TRUE;
- break;
+ if (see_t) monster_msg("%^s is unaffected.", t_name);
}
-
- case SF_BO_ACID_IDX:
+ else
{
- disturb_on_other();
- if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts an acid bolt at %s.", m_name, t_name);
- monst_bolt_monst(m_idx, y, x, GF_ACID,
- damroll(7, 8) + (rlev / 3));
- break;
+ if (see_t) monster_msg("%^s is blinded!", t_name);
+ t_ptr->confused += 12 + (byte)rand_int(4);
}
+ wake_up = true;
+ break;
- case SF_BO_ELEC_IDX:
- {
- disturb_on_other();
- if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts a lightning bolt at %s.", m_name, t_name);
- monst_bolt_monst(m_idx, y, x, GF_ELEC,
- damroll(4, 8) + (rlev / 3));
- break;
- }
+ }
- case SF_BO_FIRE_IDX:
+ case SF_CONF_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m) monster_msg("%^s mumbles, and you hear puzzling noises.", m_name);
+ else monster_msg("%^s creates a mesmerising illusion in front of %s.", m_name, t_name);
+ if (tr_ptr->flags & RF_NO_CONF)
{
- disturb_on_other();
- if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts a fire bolt at %s.", m_name, t_name);
- monst_bolt_monst(m_idx, y, x, GF_FIRE,
- damroll(9, 8) + (rlev / 3));
- break;
+ if (see_t) monster_msg("%^s disbelieves the feeble spell.", t_name);
}
-
- case SF_BO_COLD_IDX:
+ else if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
{
- disturb_on_other();
- if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts a frost bolt at %s.", m_name, t_name);
- monst_bolt_monst(m_idx, y, x, GF_COLD,
- damroll(6, 8) + (rlev / 3));
- break;
+ if (see_t) monster_msg("%^s disbelieves the feeble spell.", t_name);
}
-
- case SF_BO_POIS_IDX:
+ else
{
- /* XXX XXX XXX */
- break;
+ if (see_t) monster_msg("%^s seems confused.", t_name);
+ t_ptr->confused += 12 + (byte)rand_int(4);
}
+ wake_up = true;
+ break;
+ }
- case SF_BO_NETH_IDX:
+ case SF_SLOW_IDX:
+ {
+ disturb_on_other();
+ if (!blind && see_either) monster_msg("%^s drains power from %s%s muscles.", m_name, t_name,
+ (equals(t_name, "it") ? "s" : "'s"));
+ if (tr_ptr->flags & RF_UNIQUE)
{
- disturb_on_other();
- if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts a nether bolt at %s.", m_name, t_name);
- monst_bolt_monst(m_idx, y, x, GF_NETHER,
- 30 + damroll(5, 5) + (rlev * 3) / 2);
- break;
+ if (see_t) monster_msg("%^s is unaffected.", t_name);
}
-
- case SF_BO_WATE_IDX:
+ else if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
{
- disturb_on_other();
- if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts a water bolt at %s.", m_name, t_name);
- monst_bolt_monst(m_idx, y, x, GF_WATER,
- damroll(10, 10) + (rlev));
- break;
+ if (see_t) monster_msg("%^s is unaffected.", t_name);
}
-
- case SF_BO_MANA_IDX:
+ else
{
- disturb_on_other();
- if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts a mana bolt at %s.", m_name, t_name);
- monst_bolt_monst(m_idx, y, x, GF_MANA,
- randint(rlev * 7 / 2) + 50);
- break;
+ t_ptr->mspeed -= 10;
+ if (see_t) monster_msg("%^s starts moving slower.", t_name);
}
+ wake_up = true;
+ break;
+ }
- case SF_BO_PLAS_IDX:
+ case SF_HOLD_IDX:
+ {
+ disturb_on_other();
+ if (!blind && see_m) monster_msg("%^s stares intently at %s.", m_name, t_name);
+ if ((tr_ptr->flags & RF_UNIQUE) ||
+ (tr_ptr->flags & RF_NO_STUN))
{
- disturb_on_other();
- if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts a plasma bolt at %s.", m_name, t_name);
- monst_bolt_monst(m_idx, y, x, GF_PLASMA,
- 10 + damroll(8, 7) + (rlev));
- break;
+ if (see_t) monster_msg("%^s is unaffected.", t_name);
}
-
- case SF_BO_ICEE_IDX:
+ else if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
{
- disturb_on_other();
- if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts an ice bolt at %s.", m_name, t_name);
- monst_bolt_monst(m_idx, y, x, GF_ICE,
- damroll(6, 6) + (rlev));
- break;
+ if (see_t) monster_msg("%^s is unaffected.", t_name);
}
-
- case SF_MISSILE_IDX:
+ else
{
- disturb_on_other();
- if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts a magic missile at %s.", m_name, t_name);
- monst_bolt_monst(m_idx, y, x, GF_MISSILE,
- damroll(2, 6) + (rlev / 3));
- break;
+ t_ptr->stunned += randint(4) + 4;
+ if (see_t) monster_msg("%^s is paralyzed!", t_name);
}
+ wake_up = true;
+ break;
+ }
- case SF_SCARE_IDX:
+ case SF_HASTE_IDX:
+ {
+ disturb_on_other();
+ if (blind || !see_m)
{
- if (!direct) break;
- disturb_on_other();
- if (blind || !see_m) monster_msg("%^s mumbles, and you hear scary noises.", m_name);
- else monster_msg("%^s casts a fearful illusion at %s.", m_name, t_name);
- if (tr_ptr->flags & RF_NO_FEAR)
- {
- if (see_t) monster_msg("%^s refuses to be frightened.", t_name);
- }
- else if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
- {
- if (see_t) monster_msg("%^s refuses to be frightened.", t_name);
- }
- else
- {
- if (!(t_ptr->monfear) && see_t) monster_msg("%^s flees in terror!", t_name);
- t_ptr->monfear += rand_int(4) + 4;
- }
- wake_up = TRUE;
- break;
+ monster_msg("%^s mumbles.", m_name);
}
-
- case SF_BLIND_IDX:
+ else
{
- if (!direct) break;
- disturb_on_other();
- if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s casts a spell, burning %s%s eyes.", m_name, t_name,
- (!strcmp(t_name, "it") ? "s" : "'s"));
- if (tr_ptr->flags & RF_NO_CONF) /* Simulate blindness with confusion */
- {
- if (see_t) monster_msg("%^s is unaffected.", t_name);
- }
- else if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
- {
- if (see_t) monster_msg("%^s is unaffected.", t_name);
- }
- else
- {
- if (see_t) monster_msg("%^s is blinded!", t_name);
- t_ptr->confused += 12 + (byte)rand_int(4);
- }
- wake_up = TRUE;
- break;
-
+ monster_msg("%^s concentrates on %s body.", m_name, m_poss);
}
- case SF_CONF_IDX:
+ /* Allow quick speed increases to base+10 */
+ if (m_ptr->mspeed < m_ptr->speed + 10)
{
- if (!direct) break;
- disturb_on_other();
- if (blind || !see_m) monster_msg("%^s mumbles, and you hear puzzling noises.", m_name);
- else monster_msg("%^s creates a mesmerising illusion in front of %s.", m_name, t_name);
- if (tr_ptr->flags & RF_NO_CONF)
- {
- if (see_t) monster_msg("%^s disbelieves the feeble spell.", t_name);
- }
- else if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
- {
- if (see_t) monster_msg("%^s disbelieves the feeble spell.", t_name);
- }
- else
- {
- if (see_t) monster_msg("%^s seems confused.", t_name);
- t_ptr->confused += 12 + (byte)rand_int(4);
- }
- wake_up = TRUE;
- break;
+ if (see_m) monster_msg("%^s starts moving faster.", m_name);
+ m_ptr->mspeed += 10;
}
- case SF_SLOW_IDX:
+ /* Allow small speed increases to base+20 */
+ else if (m_ptr->mspeed < m_ptr->speed + 20)
{
- if (!direct) break;
- disturb_on_other();
- if (!blind && see_either) monster_msg("%^s drains power from %s%s muscles.", m_name, t_name,
- (!strcmp(t_name, "it") ? "s" : "'s"));
- if (tr_ptr->flags & RF_UNIQUE)
- {
- if (see_t) monster_msg("%^s is unaffected.", t_name);
- }
- else if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
- {
- if (see_t) monster_msg("%^s is unaffected.", t_name);
- }
- else
- {
- t_ptr->mspeed -= 10;
- if (see_t) monster_msg("%^s starts moving slower.", t_name);
- }
- wake_up = TRUE;
- break;
+ if (see_m) monster_msg("%^s starts moving faster.", m_name);
+ m_ptr->mspeed += 2;
}
- case SF_HOLD_IDX:
+ break;
+ }
+
+ case SF_HAND_DOOM_IDX:
+ {
+ disturb_on_other();
+ if (!see_m) monster_msg("You hear someone invoke the Hand of Doom!");
+ else if (!blind) monster_msg("%^s invokes the Hand of Doom on %s.", m_name, t_name);
+ else
+ monster_msg ("You hear someone invoke the Hand of Doom!");
+ if (tr_ptr->flags & RF_UNIQUE)
{
- if (!direct) break;
- disturb_on_other();
- if (!blind && see_m) monster_msg("%^s stares intently at %s.", m_name, t_name);
- if ((tr_ptr->flags & RF_UNIQUE) ||
- (tr_ptr->flags & RF_NO_STUN))
- {
- if (see_t) monster_msg("%^s is unaffected.", t_name);
- }
- else if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
- {
- if (see_t) monster_msg("%^s is unaffected.", t_name);
- }
- else
- {
- t_ptr->stunned += randint(4) + 4;
- if (see_t) monster_msg("%^s is paralyzed!", t_name);
- }
- wake_up = TRUE;
- break;
+ if (!blind && see_t) monster_msg("^%s is unaffected!", t_name);
}
-
- case SF_HASTE_IDX:
+ else
{
- disturb_on_other();
- if (blind || !see_m)
+ if (((m_ptr->level) + randint(20)) >
+ ((t_ptr->level) + 10 + randint(20)))
{
- monster_msg("%^s mumbles.", m_name);
+ t_ptr->hp = t_ptr->hp
+ - (((s32b) ((65 + randint(25)) * (t_ptr->hp))) / 100);
+ if (t_ptr->hp < 1) t_ptr->hp = 1;
}
else
{
- monster_msg("%^s concentrates on %s body.", m_name, m_poss);
+ if (see_t) monster_msg("%^s resists!", t_name);
}
+ }
- /* Allow quick speed increases to base+10 */
- if (m_ptr->mspeed < m_ptr->speed + 10)
- {
- if (see_m) monster_msg("%^s starts moving faster.", m_name);
- m_ptr->mspeed += 10;
- }
+ wake_up = true;
+ break;
+ }
- /* Allow small speed increases to base+20 */
- else if (m_ptr->mspeed < m_ptr->speed + 20)
- {
- if (see_m) monster_msg("%^s starts moving faster.", m_name);
- m_ptr->mspeed += 2;
- }
+ case SF_HEAL_IDX:
+ {
+ disturb_on_other();
- break;
+ /* Message */
+ if (blind || !see_m)
+ {
+ monster_msg("%^s mumbles.", m_name);
}
-
- case SF_HAND_DOOM_IDX:
+ else
{
- if (!direct) break;
- disturb_on_other();
- if (!see_m) monster_msg("You hear someone invoke the Hand of Doom!");
- else if (!blind) monster_msg("%^s invokes the Hand of Doom on %s.", m_name, t_name);
- else
- monster_msg ("You hear someone invoke the Hand of Doom!");
- if (tr_ptr->flags & RF_UNIQUE)
- {
- if (!blind && see_t) monster_msg("^%s is unaffected!", t_name);
- }
- else
- {
- if (((m_ptr->level) + randint(20)) >
- ((t_ptr->level) + 10 + randint(20)))
- {
- t_ptr->hp = t_ptr->hp
- - (((s32b) ((65 + randint(25)) * (t_ptr->hp))) / 100);
- if (t_ptr->hp < 1) t_ptr->hp = 1;
- }
- else
- {
- if (see_t) monster_msg("%^s resists!", t_name);
- }
- }
-
- wake_up = TRUE;
- break;
+ monster_msg("%^s concentrates on %s wounds.", m_name, m_poss);
}
- case SF_HEAL_IDX:
+ /* Heal some */
+ m_ptr->hp += (rlev * 6);
+
+ /* Fully healed */
+ if (m_ptr->hp >= m_ptr->maxhp)
{
- disturb_on_other();
+ /* Fully healed */
+ m_ptr->hp = m_ptr->maxhp;
/* Message */
- if (blind || !see_m)
+ if (seen)
{
- monster_msg("%^s mumbles.", m_name);
+ monster_msg("%^s looks completely healed!", m_name);
}
else
{
- monster_msg("%^s concentrates on %s wounds.", m_name, m_poss);
+ monster_msg("%^s sounds completely healed!", m_name);
}
+ }
- /* Heal some */
- m_ptr->hp += (rlev * 6);
-
- /* Fully healed */
- if (m_ptr->hp >= m_ptr->maxhp)
+ /* Partially healed */
+ else
+ {
+ /* Message */
+ if (seen)
{
- /* Fully healed */
- m_ptr->hp = m_ptr->maxhp;
-
- /* Message */
- if (seen)
- {
- monster_msg("%^s looks completely healed!", m_name);
- }
- else
- {
- monster_msg("%^s sounds completely healed!", m_name);
- }
+ monster_msg("%^s looks healthier.", m_name);
}
-
- /* Partially healed */
else
{
- /* Message */
- if (seen)
- {
- monster_msg("%^s looks healthier.", m_name);
- }
- else
- {
- monster_msg("%^s sounds healthier.", m_name);
- }
+ monster_msg("%^s sounds healthier.", m_name);
}
+ }
- /* Redraw (later) if needed */
- if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME);
+ /* Redraw (later) if needed */
+ if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME);
+ /* Cancel fear */
+ if (m_ptr->monfear)
+ {
/* Cancel fear */
- if (m_ptr->monfear)
- {
- /* Cancel fear */
- m_ptr->monfear = 0;
+ m_ptr->monfear = 0;
- /* Message */
- if (see_m) monster_msg("%^s recovers %s courage.", m_name, m_poss);
- }
+ /* Message */
+ if (see_m) monster_msg("%^s recovers %s courage.", m_name, m_poss);
+ }
+ break;
+ }
+
+ case SF_BLINK_IDX:
+ {
+ disturb_on_other();
+ if (see_m) monster_msg("%^s blinks away.", m_name);
+ teleport_away(m_idx, 10);
+ break;
+ }
+
+ case SF_TPORT_IDX:
+ {
+ if (dungeon_flags & DF_NO_TELEPORT)
+ {
+ break; /* No teleport on special levels */
+ }
+ else
+ {
+ disturb_on_other();
+ if (see_m) monster_msg("%^s teleports away.", m_name);
+ teleport_away(m_idx, MAX_SIGHT * 2 + 5);
break;
}
+ }
- case SF_BLINK_IDX:
+ case SF_TELE_TO_IDX:
+ {
+ /* Not implemented */
+ break;
+ }
+
+ case SF_TELE_AWAY_IDX:
+ {
+ if (dungeon_flags & DF_NO_TELEPORT)
{
- disturb_on_other();
- if (see_m) monster_msg("%^s blinks away.", m_name);
- teleport_away(m_idx, 10);
break;
}
- case SF_TPORT_IDX:
+ bool resists_tele = false;
+ disturb_on_other();
+ monster_msg("%^s teleports %s away.", m_name, t_name);
+
+ if (tr_ptr->flags & RF_RES_TELE)
{
- if (dungeon_flags & DF_NO_TELEPORT)
+ if (tr_ptr->flags & RF_UNIQUE)
{
- break; /* No teleport on special levels */
+ if (see_t)
+ {
+ monster_msg("%^s is unaffected!", t_name);
+ }
+ resists_tele = true;
}
- else
+ else if (t_ptr->level > randint(100))
{
- disturb_on_other();
- if (see_m) monster_msg("%^s teleports away.", m_name);
- teleport_away(m_idx, MAX_SIGHT * 2 + 5);
- break;
+ if (see_t)
+ {
+ monster_msg("%^s resists!", t_name);
+ }
+ resists_tele = true;
}
}
- case SF_TELE_TO_IDX:
+ if (!resists_tele)
{
- /* Not implemented */
- break;
+ teleport_away(t_idx, MAX_SIGHT * 2 + 5);
}
- case SF_TELE_AWAY_IDX:
- {
- if (dungeon_flags & DF_NO_TELEPORT)
- {
- break;
- }
-
- if (!direct)
- {
- break;
- }
- else
- {
- bool_ resists_tele = FALSE;
- disturb_on_other();
- monster_msg("%^s teleports %s away.", m_name, t_name);
+ break;
+ }
+ case SF_TELE_LEVEL_IDX:
+ {
+ /* Not implemented */
+ break;
+ }
- if (tr_ptr->flags & RF_RES_TELE)
- {
- if (tr_ptr->flags & RF_UNIQUE)
- {
- if (see_t)
- {
- monster_msg("%^s is unaffected!", t_name);
- }
- resists_tele = TRUE;
- }
- else if (t_ptr->level > randint(100))
- {
- if (see_t)
- {
- monster_msg("%^s resists!", t_name);
- }
- resists_tele = TRUE;
- }
- }
+ case SF_DARKNESS_IDX:
+ {
+ disturb_on_other();
+ if (blind) monster_msg("%^s mumbles.", m_name);
+ else monster_msg("%^s gestures in shadow.", m_name);
+ if (seen)
+ monster_msg("%^s is surrounded by darkness.", t_name);
+ project(m_idx, 3, y, x, 0, GF_DARK_WEAK, PROJECT_GRID | PROJECT_KILL);
+ /* Lite up the room */
+ unlite_room(y, x);
+ break;
+ }
- if (!resists_tele)
- {
- teleport_away(t_idx, MAX_SIGHT * 2 + 5);
- }
- }
+ case SF_FORGET_IDX:
+ {
+ /* Not implemented */
+ break;
+ }
- break;
- }
+ case SF_S_ANIMAL_IDX:
+ {
+ do_summon("summons an animal!", 1, SUMMON_ANIMAL, SUMMON_ANIMAL, blind_msg_default);
+ break;
+ }
- case SF_TELE_LEVEL_IDX:
- {
- /* Not implemented */
- break;
- }
+ case SF_S_ANIMALS_IDX:
+ {
+ do_summon("summons some animals!", 4, SUMMON_ANIMAL, SUMMON_ANIMAL, blind_msg_default);
+ break;
+ }
- case SF_DARKNESS_IDX:
- {
- if (!direct) break;
- disturb_on_other();
- if (blind) monster_msg("%^s mumbles.", m_name);
- else monster_msg("%^s gestures in shadow.", m_name);
- if (seen)
- monster_msg("%^s is surrounded by darkness.", t_name);
- project(m_idx, 3, y, x, 0, GF_DARK_WEAK, PROJECT_GRID | PROJECT_KILL);
- /* Lite up the room */
- unlite_room(y, x);
- break;
- }
+ case SF_S_BUG_IDX:
+ {
+ do_summon("codes some software bugs.", 6, SUMMON_BUG, SUMMON_BUG, blind_msg_default);
+ break;
+ }
- case SF_FORGET_IDX:
- {
- /* Not implemented */
- break;
- }
+ case SF_S_RNG_IDX:
+ {
+ do_summon("codes some RNGs.", 6, SUMMON_RNG, SUMMON_RNG, blind_msg_default);
+ break;
+ }
- case SF_S_ANIMAL_IDX:
- {
- do_summon("summons an animal!", 1, SUMMON_ANIMAL, SUMMON_ANIMAL, blind_msg_default);
- break;
- }
+ case SF_S_THUNDERLORD_IDX:
+ {
+ do_summon("summons a Thunderlord!", 1, SUMMON_THUNDERLORD, SUMMON_THUNDERLORD, blind_msg_default);
+ break;
+ }
- case SF_S_ANIMALS_IDX:
- {
- do_summon("summons some animals!", 4, SUMMON_ANIMAL, SUMMON_ANIMAL, blind_msg_default);
- break;
- }
+ case SF_S_KIN_IDX:
+ {
+ // Describe the summons
+ char action[256];
+ sprintf(action,
+ "summons %s %s.",
+ m_poss,
+ (r_ptr->flags & RF_UNIQUE ? "minions" : "kin"));
+ // Force the right type of "kin"
+ summon_kin_type = r_ptr->d_char;
+ // Summon
+ do_summon(action, 6, SUMMON_KIN, SUMMON_KIN, blind_msg_default);
+ break;
+ }
- case SF_S_BUG_IDX:
- {
- do_summon("codes some software bugs.", 6, SUMMON_BUG, SUMMON_BUG, blind_msg_default);
- break;
- }
+ case SF_S_HI_DEMON_IDX:
+ {
+ do_summon("summons greater demons!", 8, SUMMON_HI_DEMON, SUMMON_HI_DEMON, blind_msg_default);
+ break;
+ }
- case SF_S_RNG_IDX:
- {
- do_summon("codes some RNGs.", 6, SUMMON_RNG, SUMMON_RNG, blind_msg_default);
- break;
- }
+ case SF_S_MONSTER_IDX:
+ {
+ do_summon("summons help!", 1, SUMMON_NO_UNIQUES, 0, blind_msg_default);
+ break;
+ }
- case SF_S_THUNDERLORD_IDX:
- {
- do_summon("summons a Thunderlord!", 1, SUMMON_THUNDERLORD, SUMMON_THUNDERLORD, blind_msg_default);
- break;
- }
+ case SF_S_MONSTERS_IDX:
+ {
+ do_summon("summons monsters!", 8, SUMMON_NO_UNIQUES, 0, blind_msg_default);
+ break;
+ }
- case SF_S_KIN_IDX:
- {
- // Describe the summons
- char action[256];
- sprintf(action,
- "summons %s %s.",
- m_poss,
- (r_ptr->flags & RF_UNIQUE ? "minions" : "kin"));
- // Force the right type of "kin"
- summon_kin_type = r_ptr->d_char;
- // Summon
- do_summon(action, 6, SUMMON_KIN, SUMMON_KIN, blind_msg_default);
- break;
- }
+ case SF_S_ANT_IDX:
+ {
+ do_summon("summons ants.", 6, SUMMON_ANT, SUMMON_ANT, blind_msg_default);
+ break;
+ }
- case SF_S_HI_DEMON_IDX:
- {
- do_summon("summons greater demons!", 8, SUMMON_HI_DEMON, SUMMON_HI_DEMON, blind_msg_default);
- break;
- }
+ case SF_S_SPIDER_IDX:
+ {
+ do_summon("summons spiders.", 6, SUMMON_SPIDER, SUMMON_SPIDER, blind_msg_default);
+ break;
+ }
- case SF_S_MONSTER_IDX:
- {
- do_summon("summons help!", 1, SUMMON_NO_UNIQUES, 0, blind_msg_default);
- break;
- }
+ case SF_S_HOUND_IDX:
+ {
+ do_summon("summons hounds.", 6, SUMMON_HOUND, SUMMON_HOUND, blind_msg_default);
+ break;
+ }
- case SF_S_MONSTERS_IDX:
- {
- do_summon("summons monsters!", 8, SUMMON_NO_UNIQUES, 0, blind_msg_default);
- break;
- }
+ case SF_S_HYDRA_IDX:
+ {
+ do_summon("summons hydras.", 6, SUMMON_HYDRA, SUMMON_HYDRA, blind_msg_default);
+ break;
+ }
- case SF_S_ANT_IDX:
- {
- do_summon("summons ants.", 6, SUMMON_ANT, SUMMON_ANT, blind_msg_default);
- break;
- }
+ case SF_S_ANGEL_IDX:
+ {
+ do_summon("summons an angel!", 1, SUMMON_ANGEL, SUMMON_ANGEL, blind_msg_default);
+ break;
+ }
- case SF_S_SPIDER_IDX:
- {
- do_summon("summons spiders.", 6, SUMMON_SPIDER, SUMMON_SPIDER, blind_msg_default);
- break;
- }
+ case SF_S_DEMON_IDX:
+ {
+ do_summon("summons a demon!", 1, SUMMON_DEMON, SUMMON_DEMON, blind_msg_default);
+ break;
+ }
- case SF_S_HOUND_IDX:
- {
- do_summon("summons hounds.", 6, SUMMON_HOUND, SUMMON_HOUND, blind_msg_default);
- break;
- }
+ case SF_S_UNDEAD_IDX:
+ {
+ do_summon("summons an undead adversary!", 1, SUMMON_UNDEAD, SUMMON_UNDEAD, blind_msg_default);
+ break;
+ }
- case SF_S_HYDRA_IDX:
- {
- do_summon("summons hydras.", 6, SUMMON_HYDRA, SUMMON_HYDRA, blind_msg_default);
- break;
- }
+ case SF_S_DRAGON_IDX:
+ {
+ do_summon("summons a dragon!", 1, SUMMON_DRAGON, SUMMON_DRAGON, blind_msg_default);
+ break;
+ }
- case SF_S_ANGEL_IDX:
- {
- do_summon("summons an angel!", 1, SUMMON_ANGEL, SUMMON_ANGEL, blind_msg_default);
- break;
- }
+ case SF_S_HI_UNDEAD_IDX:
+ {
+ summon_messages blind_msg {
+ "You hear a creepy thing appear nearby.",
+ "You hear many creepy things appear nearby."
+ };
+ do_summon("summons greater undead!", 8, SUMMON_HI_UNDEAD_NO_UNIQUES, SUMMON_HI_UNDEAD, blind_msg);
+ break;
+ }
- case SF_S_DEMON_IDX:
- {
- do_summon("summons a demon!", 1, SUMMON_DEMON, SUMMON_DEMON, blind_msg_default);
- break;
- }
+ case SF_S_HI_DRAGON_IDX:
+ {
+ summon_messages blind_msg {
+ "You hear many a powerful thing appear nearby.",
+ "You hear many powerful things appear nearby."
+ };
+ do_summon("summons ancient dragons!", 8, SUMMON_HI_DRAGON_NO_UNIQUES, SUMMON_HI_DRAGON, blind_msg);
+ break;
+ }
- case SF_S_UNDEAD_IDX:
- {
- do_summon("summons an undead adversary!", 1, SUMMON_UNDEAD, SUMMON_UNDEAD, blind_msg_default);
- break;
- }
+ case SF_S_WRAITH_IDX:
+ {
+ // No summoning Nazgul; see the remapping code above the switch.
+ assert(!friendly);
+ // Summon
+ summon_messages blind_msg {
+ "You hear an immortal being appear nearby.",
+ "You hear immortal beings appear nearby."
+ };
+ do_summon("summons a wraith!", 8, 0 /* not used */, SUMMON_WRAITH, blind_msg);
+ break;
+ }
- case SF_S_DRAGON_IDX:
+ case SF_S_UNIQUE_IDX:
+ {
+ // No summoning uniques; see the remapping code above the switch.
+ assert(!friendly);
+ // Interrupt
+ disturb_on_other();
+ // Message
+ if (blind || !see_m)
{
- do_summon("summons a dragon!", 1, SUMMON_DRAGON, SUMMON_DRAGON, blind_msg_default);
- break;
+ monster_msg("%^s mumbles.", m_name);
}
-
- case SF_S_HI_UNDEAD_IDX:
+ else
{
- summon_messages blind_msg {
- "You hear a creepy thing appear nearby.",
- "You hear many creepy things appear nearby."
- };
- do_summon("summons greater undead!", 8, SUMMON_HI_UNDEAD_NO_UNIQUES, SUMMON_HI_UNDEAD, blind_msg);
- break;
+ monster_msg("%^s magically summons special opponents!", m_name);
}
-
- case SF_S_HI_DRAGON_IDX:
+ // Summon
+ int count = 0;
+ for (int k = 0; k < 8; k++)
{
- summon_messages blind_msg {
- "You hear many a powerful thing appear nearby.",
- "You hear many powerful things appear nearby."
- };
- do_summon("summons ancient dragons!", 8, SUMMON_HI_DRAGON_NO_UNIQUES, SUMMON_HI_DRAGON, blind_msg);
- break;
+ count += summon_specific(m_ptr->fy, m_ptr->fx, rlev, SUMMON_UNIQUE);
}
-
- case SF_S_WRAITH_IDX:
+ for (int k = 0; k < 8; k++)
{
- // No summoning Nazgul; see the remapping code above the switch.
- assert(!friendly);
- // Summon
- summon_messages blind_msg {
- "You hear an immortal being appear nearby.",
- "You hear immortal beings appear nearby."
- };
- do_summon("summons a wraith!", 8, 0 /* not used */, SUMMON_WRAITH, blind_msg);
- break;
+ count += summon_specific(m_ptr->fy, m_ptr->fx, rlev, SUMMON_HI_UNDEAD);
}
-
- case SF_S_UNIQUE_IDX:
+ // Message
+ if (blind)
{
- // No summoning uniques; see the remapping code above the switch.
- assert(!friendly);
- // Interrupt
- disturb_on_other();
- // Message
- if (blind || !see_m)
- {
- monster_msg("%^s mumbles.", m_name);
- }
- else
- {
- monster_msg("%^s magically summons special opponents!", m_name);
- }
- // Summon
- int count = 0;
- for (int k = 0; k < 8; k++)
- {
- count += summon_specific(m_ptr->fy, m_ptr->fx, rlev, SUMMON_UNIQUE);
- }
- for (int k = 0; k < 8; k++)
+ if (count == 1)
{
- count += summon_specific(m_ptr->fy, m_ptr->fx, rlev, SUMMON_HI_UNDEAD);
+ monster_msg("You hear a powerful thing appear nearby.");
}
- // Message
- if (blind)
+ else if (count > 1)
{
- if (count == 1)
- {
- monster_msg("You hear a powerful thing appear nearby.");
- }
- else if (count > 1)
- {
- monster_msg("You hear many powerful things appear nearby.");
- }
+ monster_msg("You hear many powerful things appear nearby.");
}
- break;
}
+ break;
}
+ }
- if (wake_up)
- {
- t_ptr->csleep = 0;
- }
-
- /* A spell was cast */
- return (TRUE);
+ if (wake_up)
+ {
+ t_ptr->csleep = 0;
}
- /* No enemy found */
- return (FALSE);
+ /* A spell was cast */
+ return true;
}
void curse_equipment(int chance, int heavy_chance)
{
- bool_ changed = FALSE;
+ bool changed = false;
object_type * o_ptr =
&p_ptr->inventory[rand_range(INVEN_WIELD, INVEN_TOTAL - 1)];
- if (randint(100) > chance) return;
+ if (randint(100) > chance)
+ {
+ return;
+ }
- if (!(o_ptr->k_idx)) return;
+ if (!o_ptr->k_ptr)
+ {
+ return;
+ }
auto const flags = object_flags(o_ptr);
-
/* Extra, biased saving throw for blessed items */
if ((flags & TR_BLESSED) && (randint(888) > chance))
{
char o_name[256];
- object_desc(o_name, o_ptr, FALSE, 0);
+ object_desc(o_name, o_ptr, false, 0);
msg_format("Your %s resist%s cursing!", o_name,
((o_ptr->number > 1) ? "" : "s"));
/* Hmmm -- can we wear multiple items? If not, this is unnecessary */
@@ -2353,17 +2352,15 @@ void curse_equipment(int chance, int heavy_chance)
(o_ptr->name1 || o_ptr->name2 || (!o_ptr->artifact_name.empty())))
{
if (!(flags & TR_HEAVY_CURSE))
- changed = TRUE;
+ changed = true;
o_ptr->art_flags |= TR_HEAVY_CURSE;
o_ptr->art_flags |= TR_CURSED;
- o_ptr->ident |= IDENT_CURSED;
}
else
{
- if (!(o_ptr->ident & IDENT_CURSED))
- changed = TRUE;
+ if (!(o_ptr->art_flags & TR_CURSED))
+ changed = true;
o_ptr->art_flags |= TR_CURSED;
- o_ptr->ident |= IDENT_CURSED;
}
if (changed)
@@ -2379,23 +2376,28 @@ void curse_equipment(int chance, int heavy_chance)
void curse_equipment_dg(int chance, int heavy_chance)
{
- bool_ changed = FALSE;
+ bool changed = false;
object_type * o_ptr =
&p_ptr->inventory[rand_range(INVEN_WIELD, INVEN_TOTAL - 1)];
- if (randint(100) > chance) return;
+ if (randint(100) > chance)
+ {
+ return;
+ }
- if (!(o_ptr->k_idx)) return;
+ if (!o_ptr->k_ptr)
+ {
+ return;
+ }
auto const flags = object_flags(o_ptr);
-
/* Extra, biased saving throw for blessed items */
if ((flags & TR_BLESSED) && (randint(888) > chance))
{
char o_name[256];
- object_desc(o_name, o_ptr, FALSE, 0);
+ object_desc(o_name, o_ptr, false, 0);
msg_format("Your %s resist%s cursing!", o_name,
((o_ptr->number > 1) ? "" : "s"));
return;
@@ -2405,19 +2407,17 @@ void curse_equipment_dg(int chance, int heavy_chance)
(o_ptr->name1 || o_ptr->name2 || (!o_ptr->artifact_name.empty())))
{
if (!(flags & TR_HEAVY_CURSE))
- changed = TRUE;
+ changed = true;
o_ptr->art_flags |= TR_HEAVY_CURSE;
o_ptr->art_flags |= TR_CURSED;
o_ptr->art_flags |= TR_DG_CURSE;
- o_ptr->ident |= IDENT_CURSED;
}
else
{
- if (!(o_ptr->ident & IDENT_CURSED))
- changed = TRUE;
+ if (!(flags & TR_CURSED))
+ changed = true;
o_ptr->art_flags |= TR_CURSED;
o_ptr->art_flags |= TR_DG_CURSE;
- o_ptr->ident |= IDENT_CURSED;
}
if (changed)
@@ -2434,7 +2434,7 @@ void curse_equipment_dg(int chance, int heavy_chance)
/*
* Creatures can cast spells, shoot missiles, and breathe.
*
- * Returns "TRUE" if a spell (or whatever) was (successfully) cast.
+ * Returns "true" if a spell (or whatever) was (successfully) cast.
*
* XXX XXX XXX This function could use some work, but remember to
* keep it as optimized as possible, while retaining generic code.
@@ -2471,7 +2471,7 @@ void curse_equipment_dg(int chance, int heavy_chance)
* Note the special "MFLAG_NICE" flag, which prevents a monster from using
* any spell attacks until the player has had a single chance to move.
*/
-static bool_ make_attack_spell(int m_idx)
+static bool make_attack_spell(int m_idx)
{
static const auto SF_BOLT_MASK = compute_bolt_mask();
static const auto SF_SUMMON_MASK = compute_summoning_mask();
@@ -2480,55 +2480,55 @@ static bool_ make_attack_spell(int m_idx)
int chance, rlev, failrate;
char m_name[80];
- bool_ no_inate = FALSE;
+ bool no_inate = false;
/* Extract the blind-ness */
- bool_ blind = (p_ptr->blind ? TRUE : FALSE);
+ bool blind = (p_ptr->blind ? true : false);
/* Get a pointer to the monster */
monster_type *m_ptr = &m_list[m_idx];
/* Extract the "see-able-ness" */
- bool_ seen = (!blind && m_ptr->ml);
+ bool seen = (!blind && m_ptr->ml);
/* Target location */
if (m_ptr->target != 0)
{
- return FALSE;
+ return false;
}
int y = p_ptr->py;
int x = p_ptr->px;
/* Cannot cast spells when confused */
- if (m_ptr->confused) return (FALSE);
+ if (m_ptr->confused) return false;
/* Cannot cast spells when nice */
- if (m_ptr->mflag & (MFLAG_NICE)) return (FALSE);
- if (is_friend(m_ptr) >= 0) return (FALSE);
+ if (m_ptr->mflag & (MFLAG_NICE)) return false;
+ if (is_friend(m_ptr) >= 0) return false;
/* Cannot attack the player if mortal and player fated to never die by the ... */
auto const r_ptr = m_ptr->race();
- if ((r_ptr->flags & RF_MORTAL) && (p_ptr->no_mortal)) return (FALSE);
+ if ((r_ptr->flags & RF_MORTAL) && (p_ptr->no_mortal)) return false;
/* Hack -- Extract the spell probability */
chance = (r_ptr->freq_inate + r_ptr->freq_spell) / 2;
/* Not allowed to cast spells */
- if (!chance) return (FALSE);
+ if (!chance) return false;
/* Only do spells occasionally */
- if (rand_int(100) >= chance) return (FALSE);
+ if (rand_int(100) >= chance) return false;
/* Sometimes forbid inate attacks (breaths) */
- if (rand_int(100) >= (chance * 2)) no_inate = TRUE;
+ if (rand_int(100) >= (chance * 2)) no_inate = true;
/* Require projectable player */
{
/* Check range */
- if (m_ptr->cdis > MAX_RANGE) return (FALSE);
+ if (m_ptr->cdis > MAX_RANGE) return false;
/* Check path */
- if (!projectable(m_ptr->fy, m_ptr->fx, y, x)) return (FALSE);
+ if (!projectable(m_ptr->fy, m_ptr->fx, y, x)) return false;
}
/* Extract the monster level */
@@ -2552,14 +2552,14 @@ static bool_ make_attack_spell(int m_idx)
allowed_spells &= SF_INT_MASK;
/* No spells left? */
- if (!allowed_spells) return (FALSE);
+ if (!allowed_spells) return false;
}
/* Remove the "ineffective" spells */
remove_bad_spells(m_idx, &allowed_spells);
/* No spells left */
- if (!allowed_spells) return (FALSE);
+ if (!allowed_spells) return false;
/* Check for a clean bolt shot */
if ((allowed_spells & SF_BOLT_MASK) &&
@@ -2580,19 +2580,19 @@ static bool_ make_attack_spell(int m_idx)
}
/* No spells left */
- if (!allowed_spells) return (FALSE);
+ if (!allowed_spells) return false;
/* Extract the "inate" spells */
auto spell = extract_spells(allowed_spells);
/* No spells left */
- if (spell.empty()) return (FALSE);
+ if (spell.empty()) return false;
/* Stop if player is dead or gone */
- if (!alive || death) return (FALSE);
+ if (!alive || death) return false;
/* Stop if player is leaving */
- if (p_ptr->leaving) return (FALSE);
+ if (p_ptr->leaving) return false;
/* Get the monster name (or "it") */
monster_desc(m_name, m_ptr, 0x00);
@@ -2601,7 +2601,7 @@ static bool_ make_attack_spell(int m_idx)
auto thrown_spell = choose_attack_spell(m_idx, spell);
/* Abort if no spell was chosen */
- if (!thrown_spell) return (FALSE);
+ if (!thrown_spell) return false;
/* Calculate spell failure rate */
failrate = 25 - (rlev + 3) / 4;
@@ -2615,7 +2615,7 @@ static bool_ make_attack_spell(int m_idx)
/* Message */
msg_format("%^s tries to cast a spell, but fails.", m_name);
- return (TRUE);
+ return true;
}
/* Can the player disrupt its puny attempts? */
@@ -3814,7 +3814,7 @@ static bool_ make_attack_spell(int m_idx)
}
/* A spell was cast */
- return (TRUE);
+ return true;
}
@@ -3840,16 +3840,16 @@ static int mon_will_run(int m_idx)
u32b p_val, m_val;
/* Keep monsters from running too far away */
- if (m_ptr->cdis > MAX_SIGHT + 5) return (FALSE);
+ if (m_ptr->cdis > MAX_SIGHT + 5) return false;
/* Friends don't run away */
- if (is_friend(m_ptr) >= 0) return (FALSE);
+ if (is_friend(m_ptr) >= 0) return false;
/* All "afraid" monsters will run away */
- if (m_ptr->monfear) return (TRUE);
+ if (m_ptr->monfear) return true;
/* Nearby monsters will not become terrified */
- if (m_ptr->cdis <= 5) return (FALSE);
+ if (m_ptr->cdis <= 5) return false;
/* Examine player power (level) */
p_lev = p_ptr->lev;
@@ -3858,8 +3858,8 @@ static int mon_will_run(int m_idx)
m_lev = m_ptr->level + (m_idx & 0x08) + 25;
/* Optimize extreme cases below */
- if (m_lev > p_lev + 4) return (FALSE);
- if (m_lev + 4 <= p_lev) return (TRUE);
+ if (m_lev > p_lev + 4) return false;
+ if (m_lev + 4 <= p_lev) return true;
/* Examine player health */
p_chp = p_ptr->chp;
@@ -3874,10 +3874,10 @@ static int mon_will_run(int m_idx)
m_val = (m_lev * m_mhp) + (m_chp << 2); /* div m_mhp */
/* Strong players scare strong monsters */
- if (p_val * m_mhp > m_val * p_mhp) return (TRUE);
+ if (p_val * m_mhp > m_val * p_mhp) return true;
/* Assume no terror */
- return (FALSE);
+ return false;
}
@@ -3913,12 +3913,12 @@ static int mon_will_run(int m_idx)
* but instead of heading directly for it, the monster should "swerve"
* around the player so that he has a smaller chance of getting hit.
*/
-static bool_ get_fear_moves_aux(int m_idx, int *yp, int *xp)
+static bool get_fear_moves_aux(int m_idx, int *yp, int *xp)
{
/* Monster flowing disabled */
if (!options->flow_by_sound)
{
- return (FALSE);
+ return false;
}
/* Monster location */
@@ -3934,13 +3934,13 @@ static bool_ get_fear_moves_aux(int m_idx, int *yp, int *xp)
if (cave[fy][fx].when < cave[p_ptr->py][p_ptr->px].when)
{
/* No reason to attempt flowing */
- return (FALSE);
+ return false;
}
/* Monster is too far away to use flow information */
auto const r_ptr = m_ptr->race();
- if (cave[fy][fx].cost > MONSTER_FLOW_DEPTH) return (FALSE);
- if (cave[fy][fx].cost > r_ptr->aaf) return (FALSE);
+ if (cave[fy][fx].cost > MONSTER_FLOW_DEPTH) return false;
+ if (cave[fy][fx].cost > r_ptr->aaf) return false;
/* Loop state */
int when = 0;
@@ -3985,14 +3985,14 @@ static bool_ get_fear_moves_aux(int m_idx, int *yp, int *xp)
}
/* No legal move (?) */
- if (!when) return (FALSE);
+ if (!when) return false;
/* Find deltas */
(*yp) = fy - gy;
(*xp) = fx - gx;
/* Success */
- return (TRUE);
+ return true;
}
@@ -4007,9 +4007,9 @@ static bool_ get_fear_moves_aux(int m_idx, int *yp, int *xp)
* This function may take lots of CPU time if lots of monsters are
* fleeing.
*
-* Return TRUE if a safe location is available.
+* Return true if a safe location is available.
*/
-static bool_ find_safety(int m_idx, int *yp, int *xp)
+static bool find_safety(int m_idx, int *yp, int *xp)
{
monster_type *m_ptr = &m_list[m_idx];
@@ -4071,12 +4071,12 @@ static bool_ find_safety(int m_idx, int *yp, int *xp)
(*xp) = fx - gx;
/* Found safe place */
- return (TRUE);
+ return true;
}
}
/* No safe place */
- return (FALSE);
+ return false;
}
@@ -4086,9 +4086,9 @@ static bool_ find_safety(int m_idx, int *yp, int *xp)
* Pack monsters will use this to "ambush" the player and lure him out
* of corridors into open space so they can swarm him.
*
- * Return TRUE if a good location is available.
+ * Return true if a good location is available.
*/
-static bool_ find_hiding(int m_idx, int *yp, int *xp)
+static bool find_hiding(int m_idx, int *yp, int *xp)
{
monster_type *m_ptr = &m_list[m_idx];
@@ -4143,12 +4143,12 @@ static bool_ find_hiding(int m_idx, int *yp, int *xp)
(*xp) = fx - gx;
/* Found good place */
- return (TRUE);
+ return true;
}
}
/* No good place */
- return (FALSE);
+ return false;
}
@@ -4157,24 +4157,40 @@ void find_corpse(monster_type *m_ptr, int *y, int *x)
{
auto const &r_info = game->edit_data.r_info;
- int k, last = -1;
+ int last = -1;
- for (k = 0; k < max_o_idx; k++)
+ for (int k = 0; k < max_o_idx; k++)
{
object_type *o_ptr = &o_list[k];
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
+
+ if (o_ptr->tval != TV_CORPSE)
+ {
+ continue;
+ }
- if (o_ptr->tval != TV_CORPSE) continue;
- if ((o_ptr->sval != SV_CORPSE_CORPSE) && (o_ptr->sval != SV_CORPSE_SKELETON)) continue;
+ if ((o_ptr->sval != SV_CORPSE_CORPSE) && (o_ptr->sval != SV_CORPSE_SKELETON))
+ {
+ continue;
+ }
auto rt_ptr = &r_info[o_ptr->pval2];
/* Cannot incarnate into a higher level monster */
- if (rt_ptr->level > m_ptr->level) continue;
+ if (rt_ptr->level > m_ptr->level)
+ {
+ continue;
+ }
/* Must be in LOS */
- if (!los(m_ptr->fy, m_ptr->fx, o_ptr->iy, o_ptr->ix)) continue;
+ if (!los(m_ptr->fy, m_ptr->fx, o_ptr->iy, o_ptr->ix))
+ {
+ continue;
+ }
if (last != -1)
{
@@ -4246,7 +4262,7 @@ static void get_target_monster(int m_idx)
/*
* Choose "logical" directions for monster movement
*/
-static bool_ get_moves(int m_idx, int *mm)
+static bool get_moves(int m_idx, int *mm)
{
monster_type *m_ptr = &m_list[m_idx];
@@ -4254,7 +4270,7 @@ static bool_ get_moves(int m_idx, int *mm)
int y2 = p_ptr->py;
int x2 = p_ptr->px;
- bool_ done = FALSE;
+ bool done = false;
/* Oups get nearer */
if ((is_friend(m_ptr) > 0) && (m_ptr->cdis > p_ptr->pet_follow_distance))
@@ -4336,7 +4352,7 @@ static bool_ get_moves(int m_idx, int *mm)
{
if (!los(m_ptr->fy, m_ptr->fx, y2, x2))
{
- return (FALSE);
+ return false;
}
}
@@ -4370,7 +4386,7 @@ static bool_ get_moves(int m_idx, int *mm)
if ((room < 8) && (p_ptr->chp > ((p_ptr->mhp * 3) / 4)))
{
/* Find hiding place */
- if (find_hiding(m_idx, &y, &x)) done = TRUE;
+ if (find_hiding(m_idx, &y, &x)) done = true;
}
}
@@ -4408,7 +4424,7 @@ static bool_ get_moves(int m_idx, int *mm)
x = m_ptr->fx - x2;
/* Done */
- done = TRUE;
+ done = true;
}
}
@@ -4446,7 +4462,7 @@ static bool_ get_moves(int m_idx, int *mm)
/* Check for no move */
- if (!x && !y) return (FALSE);
+ if (!x && !y) return false;
/* Extract the "absolute distances" */
int ay = ABS(y);
@@ -4615,7 +4631,7 @@ static bool_ get_moves(int m_idx, int *mm)
/* Wants to move... */
- return (TRUE);
+ return true;
}
@@ -4633,21 +4649,20 @@ int check_hit2(int power, int level, int ac)
i = (power + (level * 3));
/* Power and Level compete against Armor */
- if ((i > 0) && (randint(i) > ((ac * 3) / 4))) return (TRUE);
+ if ((i > 0) && (randint(i) > ((ac * 3) / 4))) return true;
/* Assume miss */
- return (FALSE);
+ return false;
}
/* Monster attacks monster */
-static bool_ monst_attack_monst(int m_idx, int t_idx)
+static bool monst_attack_monst(int m_idx, int t_idx)
{
char temp[80];
- bool_ blinked = FALSE;
- bool_ touched = FALSE;
- bool_ explode = FALSE;
- bool_ fear = FALSE;
+ bool blinked = false;
+ bool touched = false;
+ bool explode = false;
monster_type *t_ptr = &m_list[t_idx];
byte y_saver = t_ptr->fy;
byte x_saver = t_ptr->fx;
@@ -4658,7 +4673,7 @@ static bool_ monst_attack_monst(int m_idx, int t_idx)
const auto tr_ptr = t_ptr->race();
/* Not allowed to attack */
- if (r_ptr->flags & RF_NEVER_BLOW) return FALSE;
+ if (r_ptr->flags & RF_NEVER_BLOW) return false;
/* Total armor */
const int ac = t_ptr->ac;
@@ -4679,7 +4694,7 @@ static bool_ monst_attack_monst(int m_idx, int t_idx)
monster_desc(ddesc, m_ptr, 0x88);
/* Assume no blink */
- blinked = FALSE;
+ blinked = false;
if (!(m_ptr->ml || t_ptr->ml))
{
@@ -4692,7 +4707,7 @@ static bool_ monst_attack_monst(int m_idx, int t_idx)
int power = 0;
int damage = 0;
- cptr act = NULL;
+ const char *act = NULL;
/* Extract the attack infomation */
int effect = m_ptr->blow[ap_cnt].effect;
@@ -4735,49 +4750,49 @@ static bool_ monst_attack_monst(int m_idx, int t_idx)
case RBM_HIT:
{
act = "hits %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_TOUCH:
{
act = "touches %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_PUNCH:
{
act = "punches %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_KICK:
{
act = "kicks %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_CLAW:
{
act = "claws %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_BITE:
{
act = "bites %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_STING:
{
act = "stings %s.";
- touched = TRUE;
+ touched = true;
break;
}
@@ -4790,92 +4805,92 @@ static bool_ monst_attack_monst(int m_idx, int t_idx)
case RBM_BUTT:
{
act = "butts %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_CRUSH:
{
act = "crushes %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_ENGULF:
{
act = "engulfs %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_CHARGE:
{
act = "charges %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_CRAWL:
{
act = "crawls on %s.";
- touched = TRUE;
+ touched = true;
break;
}
case RBM_DROOL:
{
act = "drools on %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_SPIT:
{
act = "spits on %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_EXPLODE:
{
act = "explodes.";
- explode = TRUE;
- touched = FALSE;
+ explode = true;
+ touched = false;
break;
}
case RBM_GAZE:
{
act = "gazes at %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_WAIL:
{
act = "wails at %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_SPORE:
{
act = "releases spores at %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_XXX4:
{
act = "projects XXX4's at %s.";
- touched = FALSE;
+ touched = false;
break;
}
case RBM_BEG:
{
act = "begs %s for money.";
- touched = FALSE;
+ touched = false;
t_ptr->csleep = 0;
break;
}
@@ -4883,7 +4898,7 @@ static bool_ monst_attack_monst(int m_idx, int t_idx)
case RBM_INSULT:
{
act = "insults %s.";
- touched = FALSE;
+ touched = false;
t_ptr->csleep = 0;
break;
}
@@ -4891,7 +4906,7 @@ static bool_ monst_attack_monst(int m_idx, int t_idx)
case RBM_MOAN:
{
act = "moans at %s.";
- touched = FALSE;
+ touched = false;
t_ptr->csleep = 0;
break;
}
@@ -4899,7 +4914,7 @@ static bool_ monst_attack_monst(int m_idx, int t_idx)
case RBM_SHOW:
{
act = "sings to %s.";
- touched = FALSE;
+ touched = false;
t_ptr->csleep = 0;
break;
}
@@ -4965,7 +4980,7 @@ static bool_ monst_attack_monst(int m_idx, int t_idx)
case RBE_EAT_GOLD:
{
pt = damage = 0;
- if (randint(2) == 1) blinked = TRUE;
+ if (randint(2) == 1) blinked = true;
break;
}
@@ -5075,7 +5090,7 @@ static bool_ monst_attack_monst(int m_idx, int t_idx)
{
if (m_ptr->ml || t_ptr->ml)
{
- blinked = FALSE;
+ blinked = false;
monster_msg("%^s is suddenly very hot!", m_name);
}
project(t_idx, 0, m_ptr->fy, m_ptr->fx,
@@ -5089,7 +5104,7 @@ static bool_ monst_attack_monst(int m_idx, int t_idx)
{
if (m_ptr->ml || t_ptr->ml)
{
- blinked = FALSE;
+ blinked = false;
monster_msg("%^s gets zapped!", m_name);
}
project(t_idx, 0, m_ptr->fy, m_ptr->fx,
@@ -5139,9 +5154,9 @@ static bool_ monst_attack_monst(int m_idx, int t_idx)
if (explode)
{
- mon_take_hit_mon(m_idx, m_idx, m_ptr->hp + 1, &fear, " explodes into tiny shreds.");
+ mon_take_hit_mon(m_idx, m_idx, m_ptr->hp + 1, " explodes into tiny shreds.");
- blinked = FALSE;
+ blinked = false;
}
@@ -5160,7 +5175,7 @@ static bool_ monst_attack_monst(int m_idx, int t_idx)
teleport_away(m_idx, MAX_SIGHT * 2 + 5);
}
- return TRUE;
+ return true;
}
@@ -5170,7 +5185,7 @@ static bool_ monst_attack_monst(int m_idx, int t_idx)
static u32b noise = 0L;
/* Determine whether the player is invisible to a monster */
-static bool_ player_invis(monster_type * m_ptr)
+static bool player_invis(monster_type * m_ptr)
{
const auto r_ptr = m_ptr->race();
s16b inv = p_ptr->invis;
@@ -5231,7 +5246,7 @@ static bool_ player_invis(monster_type * m_ptr)
*
* A "direction" of "5" means "pick a random direction".
*/
-static void process_monster(int m_idx, bool_ is_frien)
+static void process_monster(int m_idx)
{
auto const &f_info = game->edit_data.f_info;
@@ -5240,7 +5255,7 @@ static void process_monster(int m_idx, bool_ is_frien)
int mm[8];
monster_type *m_ptr = &m_list[m_idx];
- const bool_ inv = player_invis(m_ptr);
+ const bool inv = player_invis(m_ptr);
auto const r_ptr = m_ptr->race();
if (r_ptr->flags & RF_DOPPLEGANGER) doppleganger = m_idx;
@@ -5252,8 +5267,7 @@ static void process_monster(int m_idx, bool_ is_frien)
if (d > m_ptr->bleeding) d = m_ptr->bleeding;
/* Exit if the monster dies */
- bool_ xxx = FALSE;
- if (mon_take_hit(m_idx, d, &xxx, " bleeds to death.")) return;
+ if (mon_take_hit(m_idx, d, nullptr, " bleeds to death.")) return;
/* Hack -- Recover from bleeding */
if (m_ptr->bleeding > d)
@@ -5292,8 +5306,7 @@ static void process_monster(int m_idx, bool_ is_frien)
if (d < 1) d = 1;
/* Exit if the monster dies */
- bool_ xxx = FALSE;
- if (mon_take_hit(m_idx, d, &xxx, " dies of poison.")) return;
+ if (mon_take_hit(m_idx, d, nullptr, " dies of poison.")) return;
/* Hack -- Recover from bleeding */
if (m_ptr->poisoned > d)
@@ -5453,16 +5466,16 @@ static void process_monster(int m_idx, bool_ is_frien)
}
/* Do the monster get angry? */
- bool_ gets_angry = FALSE;
+ bool gets_angry = false;
/* No one wants to be your friend if you're aggravating */
if ((m_ptr->status > MSTATUS_NEUTRAL) && (m_ptr->status < MSTATUS_COMPANION) && (p_ptr->aggravate) && !(r_ptr->flags & RF_PET))
- gets_angry = TRUE;
+ gets_angry = true;
/* Paranoia... no friendly uniques outside wizard mode -- TY */
if ((m_ptr->status > MSTATUS_NEUTRAL) && (m_ptr->status < MSTATUS_COMPANION) && !(wizard) &&
(r_ptr->flags & RF_UNIQUE) && !(r_ptr->flags & RF_PET))
- gets_angry = TRUE;
+ gets_angry = true;
if (gets_angry)
{
@@ -5570,13 +5583,13 @@ static void process_monster(int m_idx, bool_ is_frien)
* Attempt to cast a spell at an enemy other than the player
* (may slow the game a smidgeon, but I haven't noticed.)
*/
- hack_message_pain_may_silent = TRUE;
+ hack_message_pain_may_silent = true;
if (monst_spell_monst(m_idx))
{
- hack_message_pain_may_silent = FALSE;
+ hack_message_pain_may_silent = false;
return;
}
- hack_message_pain_may_silent = FALSE;
+ hack_message_pain_may_silent = false;
/* Hack -- Assume no movement */
@@ -5584,7 +5597,7 @@ static void process_monster(int m_idx, bool_ is_frien)
mm[4] = mm[5] = mm[6] = mm[7] = 0;
/* Confused -- 100% random */
- if (m_ptr->confused || (inv == TRUE && m_ptr->target == 0))
+ if (m_ptr->confused || (inv == true && m_ptr->target == 0))
{
/* Try four "random" directions */
mm[0] = mm[1] = mm[2] = mm[3] = 5;
@@ -5627,13 +5640,13 @@ static void process_monster(int m_idx, bool_ is_frien)
if (!c_ptr->m_idx) return;
/* Assume nothing */
- bool_ do_turn = FALSE;
- bool_ do_move = FALSE;
- bool_ do_view = FALSE;
+ bool do_turn = false;
+ bool do_move = false;
+ bool do_view = false;
/* Assume nothing */
- bool_ did_open_door = FALSE;
- bool_ did_bash_door = FALSE;
+ bool did_open_door = false;
+ bool did_bash_door = false;
/* Take a zero-terminated array of "directions" */
for (i = 0; mm[i]; i++)
@@ -5659,7 +5672,7 @@ static void process_monster(int m_idx, bool_ is_frien)
if (cave_floor_bold(ny, nx))
{
/* Go ahead and move */
- do_move = TRUE;
+ do_move = true;
}
/* Hack -- check for Glyph of Warding */
@@ -5667,7 +5680,7 @@ static void process_monster(int m_idx, bool_ is_frien)
!(r_ptr->flags & RF_NEVER_BLOW))
{
/* Assume no move allowed */
- do_move = FALSE;
+ do_move = false;
/* Break the ward */
if (randint(BREAK_GLYPH) < m_ptr->level)
@@ -5685,14 +5698,14 @@ static void process_monster(int m_idx, bool_ is_frien)
place_floor_convert_glass(ny, nx);
/* Allow movement */
- do_move = TRUE;
+ do_move = true;
}
}
/* Hack -- trees are obstacle */
else if ((cave[ny][nx].feat == FEAT_TREES) && (r_ptr->flags & RF_KILL_TREES))
{
- do_move = TRUE;
+ do_move = true;
/* Forget the tree */
c_ptr->info &= ~(CAVE_MARK);
@@ -5704,13 +5717,13 @@ static void process_monster(int m_idx, bool_ is_frien)
/* Hack -- player 'in' wall */
else if ((ny == p_ptr->py) && (nx == p_ptr->px))
{
- do_move = TRUE;
+ do_move = true;
}
else if (c_ptr->m_idx)
{
/* Possibly a monster to attack */
- do_move = TRUE;
+ do_move = true;
}
/* Permanent wall */
@@ -5724,28 +5737,28 @@ static void process_monster(int m_idx, bool_ is_frien)
else if ((f_info[c_ptr->feat].flags & FF_CAN_LEVITATE) && (r_ptr->flags & RF_CAN_FLY))
{
/* Pass through walls/doors/rubble */
- do_move = TRUE;
+ do_move = true;
}
/* Some monsters can fly */
else if ((f_info[c_ptr->feat].flags & FF_CAN_FLY) && (r_ptr->flags & RF_CAN_FLY))
{
/* Pass through trees/... */
- do_move = TRUE;
+ do_move = true;
}
/* Monster moves through walls (and doors) */
else if ((f_info[c_ptr->feat].flags & FF_CAN_PASS) && (r_ptr->flags & RF_PASS_WALL))
{
/* Pass through walls/doors/rubble */
- do_move = TRUE;
+ do_move = true;
}
/* Monster destroys walls (and doors) */
else if ((f_info[c_ptr->feat].flags & FF_CAN_PASS) && (r_ptr->flags & RF_KILL_WALL))
{
/* Eat through walls/doors/rubble */
- do_move = TRUE;
+ do_move = true;
if (randint(GRINDNOISE) == 1)
{
@@ -5759,14 +5772,14 @@ static void process_monster(int m_idx, bool_ is_frien)
cave_set_feat(ny, nx, FEAT_FLOOR);
/* Note changes to viewable region */
- if (player_has_los_bold(ny, nx)) do_view = TRUE;
+ if (player_has_los_bold(ny, nx)) do_view = true;
}
/* Monster moves through walls (and doors) */
else if ((f_info[c_ptr->feat].flags & FF_CAN_PASS) && (r_ptr->flags & RF_PASS_WALL))
{
/* Pass through walls/doors/rubble */
- do_move = TRUE;
+ do_move = true;
}
/* Monster moves through webs */
@@ -5774,7 +5787,7 @@ static void process_monster(int m_idx, bool_ is_frien)
(r_ptr->flags & RF_SPIDER))
{
/* Pass through webs */
- do_move = TRUE;
+ do_move = true;
}
/* Handle doors and secret doors */
@@ -5782,10 +5795,10 @@ static void process_monster(int m_idx, bool_ is_frien)
(c_ptr->feat <= FEAT_DOOR_TAIL)) ||
(c_ptr->feat == FEAT_SECRET))
{
- bool_ may_bash = TRUE;
+ bool may_bash = true;
/* Take a turn */
- do_turn = TRUE;
+ do_turn = true;
if ((r_ptr->flags & RF_OPEN_DOOR) &&
((is_friend(m_ptr) <= 0) || p_ptr->pet_open_doors))
@@ -5795,10 +5808,10 @@ static void process_monster(int m_idx, bool_ is_frien)
(c_ptr->feat == FEAT_SECRET))
{
/* The door is open */
- did_open_door = TRUE;
+ did_open_door = true;
/* Do not bash the door */
- may_bash = FALSE;
+ may_bash = false;
}
/* Locked doors (not jammed) */
@@ -5816,7 +5829,7 @@ static void process_monster(int m_idx, bool_ is_frien)
cave_set_feat(ny, nx, FEAT_DOOR_HEAD + 0x00);
/* Do not bash the door */
- may_bash = FALSE;
+ may_bash = false;
}
}
}
@@ -5843,10 +5856,10 @@ static void process_monster(int m_idx, bool_ is_frien)
}
/* The door was bashed open */
- did_bash_door = TRUE;
+ did_bash_door = true;
/* Hack -- fall into doorway */
- do_move = TRUE;
+ do_move = true;
}
}
@@ -5870,14 +5883,14 @@ static void process_monster(int m_idx, bool_ is_frien)
}
/* Handle viewable doors */
- if (player_has_los_bold(ny, nx)) do_view = TRUE;
+ if (player_has_los_bold(ny, nx)) do_view = true;
}
}
else if (do_move && (c_ptr->feat == FEAT_MINOR_GLYPH)
&& !(r_ptr->flags & RF_NEVER_BLOW))
{
/* Assume no move allowed */
- do_move = FALSE;
+ do_move = false;
/* Break the ward */
if (randint(BREAK_MINOR_GLYPH) < m_ptr->level)
@@ -5902,7 +5915,7 @@ static void process_monster(int m_idx, bool_ is_frien)
place_floor_convert_glass(ny, nx);
/* Allow movement */
- do_move = TRUE;
+ do_move = true;
}
}
@@ -5925,17 +5938,17 @@ static void process_monster(int m_idx, bool_ is_frien)
{
ny = oy + ddy[d];
nx = ox + ddx[d];
- do_move = FALSE;
+ do_move = false;
}
else
{
m_ptr->hp -= distance(ny, nx, oy, ox) * 2;
- do_move = TRUE;
+ do_move = true;
}
}
else
{
- do_move = TRUE;
+ do_move = true;
}
}
@@ -5944,15 +5957,15 @@ static void process_monster(int m_idx, bool_ is_frien)
{
if (inscription_info[c_ptr->inscription].when & INSCRIP_EXEC_MONST_WALK)
{
- bool_ t;
+ bool t;
t = execute_inscription(c_ptr->inscription, ny, nx);
if (!t && do_move)
{
/* Hack -- attack the player even if on the inscription */
if ((ny == p_ptr->py) && (nx == p_ptr->px))
- do_move = TRUE;
+ do_move = true;
else
- do_move = FALSE;
+ do_move = false;
}
}
}
@@ -5962,7 +5975,7 @@ static void process_monster(int m_idx, bool_ is_frien)
(r_ptr->flags & RF_NEVER_BLOW))
{
/* Do not move */
- do_move = FALSE;
+ do_move = false;
}
/* The player is in the way. Attack him. */
@@ -5972,20 +5985,12 @@ static void process_monster(int m_idx, bool_ is_frien)
make_attack_normal(m_idx, 1);
/* Do not move */
- do_move = FALSE;
+ do_move = false;
/* Took a turn */
- do_turn = TRUE;
+ do_turn = true;
}
- if ((cave[ny][nx].feat >= FEAT_PATTERN_START) &&
- (cave[ny][nx].feat <= FEAT_PATTERN_XTRA2) &&
- do_turn == FALSE)
- {
- do_move = FALSE;
- }
-
-
/* A monster is in the way */
if (do_move && c_ptr->m_idx)
{
@@ -5993,7 +5998,7 @@ static void process_monster(int m_idx, bool_ is_frien)
monster_type *m2_ptr = &m_list[c_ptr->m_idx];
/* Assume no movement */
- do_move = FALSE;
+ do_move = false;
/* Kill weaker monsters */
if ((r_ptr->flags & RF_KILL_BODY) &&
@@ -6008,7 +6013,7 @@ static void process_monster(int m_idx, bool_ is_frien)
(is_friend(m2_ptr) <= 0))
{
/* Allow movement */
- do_move = TRUE;
+ do_move = true;
/* Kill the monster */
delete_monster(ny, nx);
@@ -6020,17 +6025,17 @@ static void process_monster(int m_idx, bool_ is_frien)
/* Attack 'enemies' */
else if (is_enemy(m_ptr, m2_ptr) || m_ptr->confused)
{
- do_move = FALSE;
+ do_move = false;
/* attack */
if (m2_ptr->r_idx && (m2_ptr->hp >= 0))
{
- hack_message_pain_may_silent = TRUE;
+ hack_message_pain_may_silent = true;
if (monst_attack_monst(m_idx, c_ptr->m_idx))
{
- hack_message_pain_may_silent = FALSE;
+ hack_message_pain_may_silent = false;
return;
}
- hack_message_pain_may_silent = FALSE;
+ hack_message_pain_may_silent = false;
}
}
@@ -6040,7 +6045,7 @@ static void process_monster(int m_idx, bool_ is_frien)
(cave_floor_bold(m_ptr->fy, m_ptr->fx)))
{
/* Allow movement */
- do_move = TRUE;
+ do_move = true;
}
}
@@ -6053,14 +6058,14 @@ static void process_monster(int m_idx, bool_ is_frien)
if (do_move && !monster_can_cross_terrain(c_ptr->feat, r_ptr))
{
/* Assume no move allowed */
- do_move = FALSE;
+ do_move = false;
}
/* Some monsters never move */
if (do_move && (r_ptr->flags & RF_NEVER_MOVE))
{
/* Do not move */
- do_move = FALSE;
+ do_move = false;
}
@@ -6069,7 +6074,7 @@ static void process_monster(int m_idx, bool_ is_frien)
if (do_move)
{
/* Take a turn */
- do_turn = TRUE;
+ do_turn = true;
/* Hack -- Update the old location */
cave[oy][ox].m_idx = c_ptr->m_idx;
@@ -6082,7 +6087,7 @@ static void process_monster(int m_idx, bool_ is_frien)
y_ptr->fx = ox;
/* Update the old monster */
- update_mon(c_ptr->m_idx, TRUE);
+ update_mon(c_ptr->m_idx, true);
/* Wake up the moved monster */
m_list[c_ptr->m_idx].csleep = 0;
@@ -6103,7 +6108,7 @@ static void process_monster(int m_idx, bool_ is_frien)
m_ptr->fx = nx;
/* Update the monster */
- update_mon(m_idx, TRUE);
+ update_mon(m_idx, true);
/* Redraw the old grid */
lite_spot(oy, ox);
@@ -6147,7 +6152,8 @@ static void process_monster(int m_idx, bool_ is_frien)
if ((o_ptr->tval == TV_CORPSE) && (r_ptr->flags & RF_POSSESSOR) &&
((o_ptr->sval == SV_CORPSE_CORPSE) || (o_ptr->sval == SV_CORPSE_SKELETON)))
{
- if (ai_possessor(m_idx, this_o_idx)) return;
+ ai_possessor(m_idx, this_o_idx);
+ return;
}
/* Take or Kill objects on the floor */
@@ -6164,7 +6170,7 @@ static void process_monster(int m_idx, bool_ is_frien)
auto const flags = object_flags(o_ptr);
/* Acquire the object name */
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Acquire the monster name */
monster_desc(m_name, m_ptr, 0x04);
@@ -6214,7 +6220,7 @@ static void process_monster(int m_idx, bool_ is_frien)
excise_object_idx(this_o_idx);
/* Forget mark */
- o_ptr->marked = FALSE;
+ o_ptr->marked = false;
/* Forget location */
o_ptr->iy = o_ptr->ix = 0;
@@ -6329,7 +6335,6 @@ void summon_maint(int m_idx)
/* Well, then I'll take my wages from you. */
p_ptr->maintain_sum += cost;
}
- return;
}
@@ -6372,8 +6377,8 @@ void process_monsters()
int i, e;
int fx, fy;
- bool_ test;
- bool_ is_frien = FALSE;
+ bool test;
+ bool is_frien = false;
monster_type *m_ptr;
@@ -6443,23 +6448,23 @@ void process_monsters()
/* Assume no move */
- test = FALSE;
+ test = false;
/* Control monster aint affected by distance */
if (p_ptr->control == i)
{
- test = TRUE;
+ test = true;
}
/* No free upkeep on partial summons just because they're out
* of line of sight. */
- else if (m_ptr->mflag & MFLAG_PARTIAL) test = TRUE;
+ else if (m_ptr->mflag & MFLAG_PARTIAL) test = true;
/* Handle "sensing radius" */
else if (m_ptr->cdis <= r_ptr->aaf)
{
/* We can "sense" the player */
- test = TRUE;
+ test = true;
}
/* Handle "sight" and "aggravation" */
@@ -6468,7 +6473,7 @@ void process_monsters()
p_ptr->aggravate))
{
/* We can "see" or "feel" the player */
- test = TRUE;
+ test = true;
}
/* Hack -- Monsters can "smell" the player from far away */
@@ -6479,11 +6484,11 @@ void process_monsters()
(cave[fy][fx].cost < r_ptr->aaf))
{
/* We can "smell" the player */
- test = TRUE;
+ test = true;
}
/* Running away wont save them ! */
- if (m_ptr->poisoned || m_ptr->bleeding) test = TRUE;
+ if (m_ptr->poisoned || m_ptr->bleeding) test = true;
/* Do nothing */
if (!test) continue;
@@ -6491,10 +6496,10 @@ void process_monsters()
/* Save global index */
hack_m_idx = i;
- if (is_friend(m_ptr) > 0) is_frien = TRUE;
+ if (is_friend(m_ptr) > 0) is_frien = true;
/* Process the monster */
- process_monster(i, is_frien);
+ process_monster(i);
/* Hack -- notice death or departure */
if (!alive || death) break;
diff --git a/src/melee2.hpp b/src/melee2.hpp
index d5106850..ac869927 100644
--- a/src/melee2.hpp
+++ b/src/melee2.hpp
@@ -1,11 +1,11 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "monster_type_fwd.hpp"
extern int monst_spell_monst_spell;
-bool_ mon_take_hit_mon(int s_idx, int m_idx, int dam, bool_ *fear, cptr note);
-void mon_handle_fear(monster_type *m_ptr, int dam, bool_ *fear);
+bool mon_take_hit_mon(int s_idx, int m_idx, int dam, const char *note);
+void mon_handle_fear(monster_type *m_ptr, int dam, bool *fear);
int check_hit2(int power, int level, int ac);
void process_monsters();
void curse_equipment(int chance, int heavy_chance);
diff --git a/src/message.hpp b/src/message.hpp
index 7b47a9db..94ce0a86 100644
--- a/src/message.hpp
+++ b/src/message.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include <string>
diff --git a/src/messages.cc b/src/messages.cc
index 071dc66e..df578e31 100644
--- a/src/messages.cc
+++ b/src/messages.cc
@@ -22,7 +22,7 @@ message const &Messages::at(int age) const
return buffer.at(i);
}
-void Messages::add(cptr msg, byte color)
+void Messages::add(const char *msg, byte color)
{
assert(msg != nullptr);
add(std::string(msg), color);
diff --git a/src/messages.hpp b/src/messages.hpp
index 0443a6c8..a6be685f 100644
--- a/src/messages.hpp
+++ b/src/messages.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "message.hpp"
#include <boost/circular_buffer.hpp>
@@ -41,7 +41,7 @@ public:
/**
* Add a message.
*/
- void add(cptr msg, byte color);
+ void add(const char *msg, byte color);
/**
* Add a message.
diff --git a/src/mimic.cc b/src/mimic.cc
index 6ce7b180..656714a6 100644
--- a/src/mimic.cc
+++ b/src/mimic.cc
@@ -9,8 +9,11 @@
#include "xtra1.hpp"
#include "z-rand.hpp"
+#include <boost/algorithm/string/predicate.hpp>
#include <cassert>
+using boost::algorithm::equals;
+
/**
* Mimicry forms
*/
@@ -25,11 +28,11 @@ typedef struct mimic_form_type mimic_form_type;
struct mimic_form_type
{
int modules[3]; /* Modules where this mimicry form is available; terminated with a -1 entry */
- cptr name; /* Name of mimicry form */
- cptr obj_name; /* Object mimicry form name */
- cptr desc; /* Description */
- cptr realm; /* Realm of mimicry */
- bool_ limit; /* If true, the form is not available except through special means */
+ const char *name; /* Name of mimicry form */
+ const char *obj_name; /* Object mimicry form name */
+ const char *desc; /* Description */
+ const char *realm; /* Realm of mimicry */
+ bool limit; /* If true, the form is not available except through special means */
byte level;
byte rarity;
mimic_duration_type duration;
@@ -73,13 +76,13 @@ static void mouse_power()
{
if (p_ptr->mimic_level >= 30)
{
- p_ptr->powers[POWER_INVISIBILITY] = TRUE;
+ p_ptr->powers.insert(POWER_INVISIBILITY);
}
}
static s32b eagle_calc()
{
- p_ptr->ffall = TRUE;
+ p_ptr->ffall = true;
p_ptr->pspeed = p_ptr->pspeed + 2 + (p_ptr->mimic_level / 6);
p_ptr->stat_add[A_STR] += -3;
@@ -175,7 +178,7 @@ static void spider_power()
{
if (p_ptr->mimic_level >= 25)
{
- p_ptr->powers[POWER_WEB] = TRUE;
+ p_ptr->powers.insert(POWER_WEB);
}
}
@@ -205,7 +208,7 @@ static s32b ent_calc()
static void ent_power()
{
- p_ptr->powers[PWR_GROW_TREE] = TRUE;
+ p_ptr->powers.insert(PWR_GROW_TREE);
}
static s32b vapour_calc()
@@ -417,7 +420,7 @@ static mimic_form_type mimic_forms[MIMIC_FORMS_MAX] =
"Abominable Cloak",
"Abominations are failed experiments of powerful wizards.",
NULL /* no realm */,
- FALSE,
+ false,
1, 101, {20, 100},
abomination_calc,
NULL,
@@ -433,7 +436,7 @@ static mimic_form_type mimic_forms[MIMIC_FORMS_MAX] =
"Mouse Fur",
"Mice are small, fast and very stealthy",
"nature",
- FALSE,
+ false,
1, 10, {20, 40},
mouse_calc,
mouse_power,
@@ -445,7 +448,7 @@ static mimic_form_type mimic_forms[MIMIC_FORMS_MAX] =
"Feathers Cloak",
"Eagles are master of the air, good hunters with excellent vision.",
"nature",
- FALSE,
+ false,
10, 30, {10, 50},
eagle_calc,
NULL,
@@ -457,7 +460,7 @@ static mimic_form_type mimic_forms[MIMIC_FORMS_MAX] =
"Feathered Cloak",
"Eagles are master of the air, good hunters with excellent vision.",
"nature",
- FALSE,
+ false,
10, 30, {10, 50},
eagle_calc,
NULL,
@@ -469,7 +472,7 @@ static mimic_form_type mimic_forms[MIMIC_FORMS_MAX] =
"Wolf Pelt",
"Wolves are masters of movement, strong and have excellent eyesight.",
"nature",
- FALSE,
+ false,
20, 40, {10, 50},
wolf_calc,
NULL,
@@ -481,7 +484,7 @@ static mimic_form_type mimic_forms[MIMIC_FORMS_MAX] =
"Spider Web",
"Spiders are clever and become good climbers.",
"nature",
- FALSE,
+ false,
25, 50, {10, 50},
spider_calc,
spider_power,
@@ -493,7 +496,7 @@ static mimic_form_type mimic_forms[MIMIC_FORMS_MAX] =
"Entish Bark",
"Ents are powerful tree-like beings dating from the dawn of time.",
"nature",
- TRUE,
+ true,
40, 60, {10, 30},
ent_calc,
ent_power,
@@ -505,7 +508,7 @@ static mimic_form_type mimic_forms[MIMIC_FORMS_MAX] =
"Cloak of Mist",
"A sentient cloud, darting around",
"nature",
- FALSE,
+ false,
15, 10, {10, 40},
vapour_calc,
NULL,
@@ -517,7 +520,7 @@ static mimic_form_type mimic_forms[MIMIC_FORMS_MAX] =
"Snakeskin Cloak",
"Serpents are fast, lethal predators.",
"nature",
- FALSE,
+ false,
30, 25, {15, 20},
serpent_calc,
NULL,
@@ -529,7 +532,7 @@ static mimic_form_type mimic_forms[MIMIC_FORMS_MAX] =
"Mumak Hide",
"A giant, elaphantine form.",
"nature",
- FALSE,
+ false,
40, 40, {15, 20},
mumak_calc,
NULL,
@@ -545,7 +548,7 @@ static mimic_form_type mimic_forms[MIMIC_FORMS_MAX] =
NULL,
"A fierce, terrible bear.",
NULL /* no realm */,
- TRUE,
+ true,
1, 101, {50, 200},
bear_calc,
NULL,
@@ -557,7 +560,7 @@ static mimic_form_type mimic_forms[MIMIC_FORMS_MAX] =
NULL,
"A corrupted maia.",
NULL /* no realm */,
- TRUE,
+ true,
1, 101, {30, 70},
balrog_calc,
NULL,
@@ -569,7 +572,7 @@ static mimic_form_type mimic_forms[MIMIC_FORMS_MAX] =
NULL,
"A near god-like being.",
NULL /* no realm */,
- TRUE,
+ true,
1, 101, {30, 70},
maia_calc,
NULL,
@@ -581,7 +584,7 @@ static mimic_form_type mimic_forms[MIMIC_FORMS_MAX] =
NULL,
"A towering column of flames",
NULL /* no realm */,
- TRUE,
+ true,
1, 101, {10, 10},
fire_elemental_calc,
NULL,
@@ -598,11 +601,11 @@ static bool mimic_form_enabled(mimic_form_type const *f)
{
if (f->modules[i] == game_module_idx)
{
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
/*
@@ -618,12 +621,12 @@ static mimic_form_type *get_mimic_form(int mf_idx)
/*
* Find a mimic by name
*/
-s16b resolve_mimic_name(cptr name)
+s16b resolve_mimic_name(const char *name)
{
for (s16b i = 0; i < MIMIC_FORMS_MAX; i++)
{
auto const mf_ptr = get_mimic_form(i);
- if (mimic_form_enabled(mf_ptr) && streq(mf_ptr->name, name))
+ if (mimic_form_enabled(mf_ptr) && equals(mf_ptr->name, name))
{
return i;
}
@@ -635,7 +638,7 @@ s16b resolve_mimic_name(cptr name)
/*
* Find a random mimic form
*/
-s16b find_random_mimic_shape(byte level, bool_ limit)
+s16b find_random_mimic_shape(byte level, bool limit)
{
int tries = 1000;
@@ -666,7 +669,7 @@ s16b find_random_mimic_shape(byte level, bool_ limit)
/*
* Get mimic name
*/
-cptr get_mimic_name(s16b mf_idx)
+const char *get_mimic_name(s16b mf_idx)
{
return get_mimic_form(mf_idx)->name;
}
@@ -674,7 +677,7 @@ cptr get_mimic_name(s16b mf_idx)
/*
* Get mimic object name
*/
-cptr get_mimic_object_name(s16b mf_idx)
+const char *get_mimic_object_name(s16b mf_idx)
{
return get_mimic_form(mf_idx)->obj_name;
}
diff --git a/src/mimic.hpp b/src/mimic.hpp
index 4ce9a6e8..80a1722c 100644
--- a/src/mimic.hpp
+++ b/src/mimic.hpp
@@ -1,9 +1,9 @@
-#include "h-basic.h"
+#include "h-basic.hpp"
-s16b resolve_mimic_name(cptr name);
-s16b find_random_mimic_shape(byte level, bool_ limit);
-cptr get_mimic_name(s16b mf_idx);
-cptr get_mimic_object_name(s16b mf_idx);
+s16b resolve_mimic_name(const char *name);
+s16b find_random_mimic_shape(byte level, bool limit);
+const char *get_mimic_name(s16b mf_idx);
+const char *get_mimic_object_name(s16b mf_idx);
byte get_mimic_level(s16b mf_idx);
s32b get_mimic_random_duration(s16b mf_idx);
byte calc_mimic();
diff --git a/src/module_type.hpp b/src/module_type.hpp
index 1b75d84c..f207c24f 100644
--- a/src/module_type.hpp
+++ b/src/module_type.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* Module descriptor.
@@ -10,7 +10,7 @@ struct module_type
/* Metadata about the module: author, description, etc. */
struct {
/* Module name */
- cptr name;
+ const char *name;
/* Module version number */
struct {
@@ -21,18 +21,18 @@ struct module_type
/* Module author */
struct {
- cptr name;
- cptr email;
+ const char *name;
+ const char *email;
} author;
/* Module description */
- cptr desc;
+ const char *desc;
/* Save file tag */
- cptr save_file_tag;
+ const char *save_file_tag;
/* Module directory */
- cptr module_dir;
+ const char *module_dir;
} meta;
/* Random artifact generation chances */
diff --git a/src/modules.cc b/src/modules.cc
index de9ad1ad..08c16a93 100644
--- a/src/modules.cc
+++ b/src/modules.cc
@@ -11,6 +11,7 @@
#include "birth.hpp"
#include "cave.hpp"
#include "cave_type.hpp"
+#include "config.hpp"
#include "corrupt.hpp"
#include "files.hpp"
#include "hook_eat_in.hpp"
@@ -33,58 +34,41 @@
#include "stats.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
+#include "z-form.hpp"
+#include "z-util.hpp"
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/filesystem.hpp>
#include <cassert>
#include <chrono>
#include <thread>
+using boost::algorithm::equals;
using std::this_thread::sleep_for;
using std::chrono::milliseconds;
+namespace fs = boost::filesystem;
+
/*
* Check and create if needed the directory dirpath
*/
-bool_ private_check_user_directory(cptr dirpath)
+bool private_check_user_directory(const char *dirpath)
{
- /* Is this used anywhere else in *bands? */
- struct stat stat_buf;
-
- int ret;
-
- /* See if it already exists */
- ret = stat(dirpath, &stat_buf);
-
- /* It does */
- if (ret == 0)
+ if (fs::exists(dirpath))
{
- /* Now we see if it's a directory */
- if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) return (TRUE);
-
- /*
- * Something prevents us from create a directory with
- * the same pathname
- */
- return (FALSE);
+ /* Must be directory, otherwise there'll be trouble. */
+ return fs::is_directory(dirpath);
}
-
- /* No - this maybe the first time. Try to create a directory */
else
{
- /* Create the ~/.ToME directory */
- ret = mkdir(dirpath, 0700);
-
- /* An error occured */
- if (ret == -1) return (FALSE);
-
- /* Success */
- return (TRUE);
+ boost::system::error_code ec;
+ fs::create_directory(dirpath, ec);
+ return !ec;
}
}
-static void module_reset_dir_aux(char **dir, cptr new_path)
+static void module_reset_dir_aux(char **dir, const char *new_path)
{
char buf[1024];
@@ -99,26 +83,22 @@ static void module_reset_dir_aux(char **dir, cptr new_path)
quit(format("Unable to create module dir %s\n", *dir));
}
-static void module_reset_dir(cptr dir, cptr new_path)
+static void module_reset_dir(const char *dir, const char *new_path)
{
char **d = 0;
char buf[1025];
- if (!strcmp(dir, "core")) d = &ANGBAND_DIR_CORE;
- if (!strcmp(dir, "dngn")) d = &ANGBAND_DIR_DNGN;
- if (!strcmp(dir, "data")) d = &ANGBAND_DIR_DATA;
- if (!strcmp(dir, "edit")) d = &ANGBAND_DIR_EDIT;
- if (!strcmp(dir, "file")) d = &ANGBAND_DIR_FILE;
- if (!strcmp(dir, "help")) d = &ANGBAND_DIR_HELP;
- if (!strcmp(dir, "info")) d = &ANGBAND_DIR_INFO;
- if (!strcmp(dir, "pref")) d = &ANGBAND_DIR_PREF;
- if (!strcmp(dir, "xtra")) d = &ANGBAND_DIR_XTRA;
- if (!strcmp(dir, "user")) d = &ANGBAND_DIR_USER;
- if (!strcmp(dir, "note")) d = &ANGBAND_DIR_NOTE;
-
- if (
- !strcmp(dir, "user") ||
- !strcmp(dir, "note"))
+ if (equals(dir, "data")) d = &ANGBAND_DIR_DATA;
+ if (equals(dir, "edit")) d = &ANGBAND_DIR_EDIT;
+ if (equals(dir, "file")) d = &ANGBAND_DIR_FILE;
+ if (equals(dir, "help")) d = &ANGBAND_DIR_HELP;
+ if (equals(dir, "info")) d = &ANGBAND_DIR_INFO;
+ if (equals(dir, "pref")) d = &ANGBAND_DIR_PREF;
+ if (equals(dir, "xtra")) d = &ANGBAND_DIR_XTRA;
+ if (equals(dir, "user")) d = &ANGBAND_DIR_USER;
+ if (equals(dir, "note")) d = &ANGBAND_DIR_NOTE;
+
+ if (equals(dir, "user") || equals(dir, "note"))
{
char user_path[1024];
/* copied from init_file_paths */
@@ -135,7 +115,7 @@ static void module_reset_dir(cptr dir, cptr new_path)
quit(format("Unable to create module dir %s\n", *d));
}
}
- else if (!strcmp(dir, "save"))
+ else if (equals(dir, "save"))
{
module_reset_dir_aux(&ANGBAND_DIR_SAVE, new_path);
}
@@ -204,24 +184,19 @@ static void activate_module(int module_idx)
VERSION_PATCH = module_ptr->meta.version.patch;
/* Change window name if needed */
- if (strcmp(game_module, "ToME"))
+ if (equals(game_module, "ToME"))
{
strnfmt(angband_term_name[0], 79, "T-Engine: %s", game_module);
- Term_xtra(TERM_XTRA_RENAME_MAIN_WIN, 0);
+ Term_rename_main_win(angband_term_name[0]);
}
-
- /* Reprocess the player name, just in case */
- process_player_base();
}
static void init_module(module_type *module_ptr)
{
/* Set up module directories? */
- cptr dir = module_ptr->meta.module_dir;
+ const char *dir = module_ptr->meta.module_dir;
if (dir) {
- module_reset_dir("core", dir);
module_reset_dir("data", dir);
- module_reset_dir("dngn", dir);
module_reset_dir("edit", dir);
module_reset_dir("file", dir);
module_reset_dir("help", dir);
@@ -237,17 +212,14 @@ bool module_savefile_loadable(std::string const &tag)
return tag == modules[game_module_idx].meta.save_file_tag;
}
-/* Did the player force a module on command line */
-cptr force_module = NULL;
-
/* Find module index by name. Returns -1 if matching module not found */
-int find_module(cptr name)
+int find_module(const char *name)
{
int i = 0;
for (i=0; i<MAX_MODULES; i++)
{
- if (streq(name, modules[i].meta.name))
+ if (equals(name, modules[i].meta.name))
{
return i;
}
@@ -256,23 +228,16 @@ int find_module(cptr name)
return -1;
}
-/* Display possible modules and select one */
-bool_ select_module()
+bool select_module(program_args const &args)
{
- s32b k, sel, max;
-
/* How many modules? */
- max = MAX_MODULES;
+ s32b max = MAX_MODULES;
/* No need to bother the player if there is only one module */
- sel = -1;
- if (force_module) {
- /* Find module by name */
- sel = find_module(force_module);
- }
- /* Only a single choice */
- if (max == 1) {
- sel = 0;
+ s32b sel = -1;
+ if (args.module)
+ {
+ sel = find_module(args.module);
}
/* No module selected */
if (sel != -1)
@@ -284,15 +249,15 @@ bool_ select_module()
activate_module(sel);
- return FALSE;
+ return false;
}
sel = 0;
/* Preprocess the basic prefs, we need them to have movement keys */
- process_pref_file("pref.prf");
+ process_pref_file(name_file_pref("pref"));
- while (TRUE)
+ while (true)
{
/* Clear screen */
Term_clear();
@@ -304,7 +269,7 @@ bool_ select_module()
dump_modules(sel, max);
- k = inkey();
+ s32b k = inkey();
if (k == ESCAPE)
{
@@ -340,6 +305,7 @@ bool_ select_module()
else k = toupper(I2A(sel));
}
+ // Process
{
int x;
@@ -355,15 +321,14 @@ bool_ select_module()
activate_module(x);
- return (FALSE);
+ return false;
}
}
- /* Shouldnt happen */
- return (FALSE);
+ abort();
}
-static bool_ dleft(byte c, cptr str, int y, int o)
+static bool dleft(byte c, const char *str, int y, int o)
{
int i = strlen(str);
int x = 39 - (strlen(str) / 2) + o;
@@ -388,17 +353,17 @@ static bool_ dleft(byte c, cptr str, int y, int o)
a = a + 1;
if (inkey_scan()) {
- return TRUE;
+ return true;
}
}
}
i = i - 1;
}
- return FALSE;
+ return false;
}
-static bool_ dright(byte c, cptr str, int y, int o)
+static bool dright(byte c, const char *str, int y, int o)
{
int n = strlen(str); // Conversion to int to avoid warnings
int x = 39 - (n / 2) + o;
@@ -421,25 +386,25 @@ static bool_ dright(byte c, cptr str, int y, int o)
a = a - 1;
if (inkey_scan()) {
- return TRUE;
+ return true;
}
}
}
}
- return FALSE;
+ return false;
}
typedef struct intro_text intro_text;
struct intro_text
{
- bool_ (*drop_func)(byte, cptr, int, int);
+ bool (*drop_func)(byte, const char *, int, int);
byte color;
- cptr text;
+ const char *text;
int y0;
int x0;
};
-static bool_ show_intro(intro_text intro_texts[])
+static bool show_intro(intro_text intro_texts[])
{
int i = 0;
@@ -454,7 +419,7 @@ static bool_ show_intro(intro_text intro_texts[])
else if (it->drop_func(it->color, it->text, it->y0, it->x0))
{
/* Abort */
- return TRUE;
+ return true;
}
}
@@ -463,7 +428,7 @@ static bool_ show_intro(intro_text intro_texts[])
inkey();
/* Continue */
- return FALSE;
+ return false;
}
void tome_intro()
@@ -595,12 +560,12 @@ static bool drunk_takes_wine(void *, void *in_, void *)
object_type forge;
object_prep(&forge, lookup_kind(TV_BOTTLE,1));
drop_near(&forge, 50, p_ptr->py, p_ptr->px);
- return TRUE;
+ return true;
}
}
else
{
- return FALSE;
+ return false;
}
}
@@ -672,8 +637,7 @@ static bool food_vessel(void *, void *in_, void *ut)
object_prep(&forge, lookup_kind(TV_JUNK, 3));
- forge.ident |= IDENT_MENTAL | IDENT_KNOWN;
- inven_carry(&forge, FALSE);
+ inven_carry(&forge, false);
return true;
}
@@ -709,13 +673,13 @@ static bool erebor_stair(void *, void *in_, void *out_)
{
msg_print("The moon-letters on the map show you "
"the keyhole! You use the key to enter.");
- out->allow = TRUE;
+ out->allow = true;
}
else
{
msg_print("You have found a door, but you cannot "
"find a way to enter. Ask in Dale, perhaps?");
- out->allow = FALSE;
+ out->allow = false;
}
}
@@ -748,12 +712,12 @@ static bool orthanc_stair(void *, void *in_, void *out_)
if (keys >= 1)
{
msg_print("#BYou have the key to the tower of Orthanc! You may proceed.#w");
- out->allow = TRUE;
+ out->allow = true;
}
else
{
msg_print("#yYou may not enter Orthanc without the key to the gates!#w Rumours say the key was lost in the Mines of Moria...");
- out->allow = FALSE;
+ out->allow = false;
}
}
@@ -1267,6 +1231,6 @@ void init_hooks_module()
}
default:
- assert(FALSE);
+ assert(false);
}
}
diff --git a/src/modules.hpp b/src/modules.hpp
index 867955c9..7e51b16f 100644
--- a/src/modules.hpp
+++ b/src/modules.hpp
@@ -1,14 +1,15 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
+#include "program_args.hpp"
+
#include <string>
-bool_ select_module();
+bool select_module(program_args const &);
bool module_savefile_loadable(std::string const &savefile_mod);
void tome_intro();
void theme_intro();
s16b *theme_race_status(int r_idx);
void init_hooks_module();
-int find_module(cptr name);
-bool_ private_check_user_directory(cptr dirpath);
-extern cptr force_module;
+int find_module(const char *name);
+bool private_check_user_directory(const char *dirpath);
diff --git a/src/monster1.cc b/src/monster1.cc
index 50c8c548..fb220fc7 100644
--- a/src/monster1.cc
+++ b/src/monster1.cc
@@ -20,12 +20,14 @@
#include "variable.hpp"
#include "wilderness_map.hpp"
#include "wilderness_type_info.hpp"
+#include "z-form.hpp"
+#include "z-term.hpp"
/*
* Pronoun arrays, by gender.
*/
-static cptr wd_he[3] = { "it", "he", "she" };
-static cptr wd_his[3] = { "its", "his", "her" };
+static const char *wd_he[3] = { "it", "he", "she" };
+static const char *wd_his[3] = { "its", "his", "her" };
/*
@@ -50,19 +52,20 @@ static cptr wd_his[3] = { "its", "his", "her" };
*/
static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
{
- bool_ old = FALSE;
- bool_ sin = FALSE;
+ bool old = false;
+ bool sin = false;
int m, n, r;
- cptr p, q;
+ const char *p;
+ const char *q;
- bool_ breath = FALSE;
- bool_ magic = FALSE;
+ bool breath = false;
+ bool magic = false;
- int vn = 0;
+ int vn = 0;
byte color[64];
- cptr vp[64];
+ const char *vp[64];
/* Shorthand */
auto const flags = r_ptr->flags;
@@ -115,7 +118,7 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
/* Nothing yet */
- old = FALSE;
+ old = false;
/* Describe location */
if (r_ptr->flags & RF_PET)
@@ -123,7 +126,7 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
text_out(format("%^s is ", wd_he[msex]));
text_out_c(TERM_L_BLUE, "friendly");
text_out(" to you");
- old = TRUE;
+ old = true;
}
/* Describe location */
@@ -134,7 +137,7 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
else
text_out(format("%^s ", wd_he[msex]));
text_out_c(TERM_L_GREEN, "lives in the town or the wilderness");
- old = TRUE;
+ old = true;
}
else
{
@@ -153,7 +156,7 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
text_out_c(TERM_L_GREEN, format("%d", r_ptr->level));
}
- old = TRUE;
+ old = true;
}
@@ -167,7 +170,7 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
else
{
text_out(format("%^s ", wd_he[msex]));
- old = TRUE;
+ old = true;
}
text_out("moves");
@@ -225,7 +228,7 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
else
{
text_out(format("%^s ", wd_he[msex]));
- old = TRUE;
+ old = true;
}
/* Describe */
@@ -236,7 +239,7 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
if (old)
{
text_out(". ");
- old = FALSE;
+ old = false;
}
@@ -271,7 +274,7 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
else text_out(" creature");
/* Group some variables */
- if (TRUE)
+ if (true)
{
long i, j;
@@ -411,7 +414,7 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
if (vn)
{
/* Note breath */
- breath = TRUE;
+ breath = true;
/* Intro */
text_out(format("%^s", wd_he[msex]));
@@ -503,7 +506,7 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
if (vn)
{
/* Note magic */
- magic = TRUE;
+ magic = true;
/* Intro */
if (breath)
@@ -824,7 +827,7 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
/* How aware is it? */
{
- cptr act;
+ const char *act;
if (r_ptr->sleep > 200)
{
@@ -894,10 +897,10 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
if (r_ptr->flags & RF_ONLY_ITEM) drop_gold = 0;
/* No "n" needed */
- sin = FALSE;
+ sin = false;
/* Count maximum drop */
- n = MAX(drop_gold, drop_item);
+ n = std::max(drop_gold, drop_item);
/* Intro text */
if (n == 0)
@@ -908,7 +911,7 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
else if (n == 1)
{
text_out(format("%^s may carry a", wd_he[msex]));
- sin = TRUE;
+ sin = true;
}
else if (n == 2)
{
@@ -930,7 +933,7 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
else if (flags & RF_DROP_GOOD)
{
p = " good";
- sin = FALSE;
+ sin = false;
}
/* Okay */
@@ -945,7 +948,7 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
{
/* Handle singular "an" */
if (sin) text_out("n");
- sin = FALSE;
+ sin = false;
/* Dump "object(s)" */
if (p) text_out_c(TERM_ORANGE, p);
@@ -960,11 +963,11 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
if (drop_gold)
{
/* Cancel prefix */
- if (!p) sin = FALSE;
+ if (!p) sin = false;
/* Handle singular "an" */
if (sin) text_out("n");
- sin = FALSE;
+ sin = false;
/* Dump "treasure(s)" */
if (p) text_out(p);
@@ -1376,190 +1379,99 @@ void display_roff(int r_idx, int ego)
}
-bool_ monster_quest(int r_idx)
+bool monster_quest(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
/* Random quests are in the dungeon */
- if (r_ptr->flags & RF_WILD_ONLY) return FALSE;
+ if (r_ptr->flags & RF_WILD_ONLY) return false;
/* No random quests for aquatic monsters */
- if (r_ptr->flags & RF_AQUATIC) return FALSE;
+ if (r_ptr->flags & RF_AQUATIC) return false;
/* No random quests for multiplying monsters */
- if (r_ptr->spells & SF_MULTIPLY) return FALSE;
+ if (r_ptr->spells & SF_MULTIPLY) return false;
- return TRUE;
+ return true;
}
-
-bool_ monster_dungeon(int r_idx)
+bool monster_dungeon(const monster_race *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
- if (!(r_ptr->flags & RF_WILD_ONLY))
- return TRUE;
- else
- return FALSE;
+ return !(r_ptr->flags & RF_WILD_ONLY);
}
-
-static bool_ monster_ocean(int r_idx)
+static bool monster_ocean(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
- if (r_ptr->flags & RF_WILD_OCEAN)
- return TRUE;
- else
- return FALSE;
+ return bool(r_ptr->flags & RF_WILD_OCEAN);
}
-
-static bool_ monster_shore(int r_idx)
+static bool monster_shore(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
- if (r_ptr->flags & RF_WILD_SHORE)
- return TRUE;
- else
- return FALSE;
+ return bool(r_ptr->flags & RF_WILD_SHORE);
}
-
-static bool_ monster_waste(int r_idx)
+static bool monster_waste(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
- if (r_ptr->flags & RF_WILD_WASTE)
- return TRUE;
- else
- return FALSE;
+ return bool(r_ptr->flags & RF_WILD_WASTE);
}
-
-static bool_ monster_town(int r_idx)
+static bool monster_town(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
- if (r_ptr->flags & RF_WILD_TOWN)
- return TRUE;
- else
- return FALSE;
+ return bool(r_ptr->flags & RF_WILD_TOWN);
}
-
-static bool_ monster_wood(int r_idx)
+static bool monster_wood(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
- if (r_ptr->flags & RF_WILD_WOOD)
- return TRUE;
- else
- return FALSE;
+ return bool(r_ptr->flags & RF_WILD_WOOD);
}
-
-static bool_ monster_volcano(int r_idx)
+static bool monster_volcano(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
- if (r_ptr->flags & RF_WILD_VOLCANO)
- return TRUE;
- else
- return FALSE;
+ return bool(r_ptr->flags & RF_WILD_VOLCANO);
}
-
-static bool_ monster_mountain(int r_idx)
+static bool monster_mountain(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
- if (r_ptr->flags & RF_WILD_MOUNTAIN)
- return TRUE;
- else
- return FALSE;
+ return bool(r_ptr->flags & RF_WILD_MOUNTAIN);
}
-
-static bool_ monster_grass(int r_idx)
+static bool monster_grass(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
- if (r_ptr->flags & RF_WILD_GRASS)
- return TRUE;
- else
- return FALSE;
+ return bool(r_ptr->flags & RF_WILD_GRASS);
}
-
-static bool_ monster_deep_water(int r_idx)
+static bool monster_deep_water(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
- if (!monster_dungeon(r_idx)) return FALSE;
+ if (!monster_dungeon(r_ptr))
+ {
+ return false;
+ }
- if (r_ptr->flags & RF_AQUATIC)
- return TRUE;
- else
- return FALSE;
+ return bool(r_ptr->flags & RF_AQUATIC);
}
-
-static bool_ monster_shallow_water(int r_idx)
+static bool monster_shallow_water(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
- if (!monster_dungeon(r_idx)) return FALSE;
+ if (!monster_dungeon(r_ptr))
+ {
+ return false;
+ }
- if (r_ptr->flags & RF_AURA_FIRE)
- return FALSE;
- else
- return TRUE;
+ return !(r_ptr->flags & RF_AURA_FIRE);
}
-
-static bool_ monster_lava(int r_idx)
+static bool monster_lava(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
- if (!monster_dungeon(r_idx)) return FALSE;
+ if (!monster_dungeon(r_ptr))
+ {
+ return false;
+ }
- if (((r_ptr->flags & RF_IM_FIRE) ||
- (r_ptr->flags & RF_CAN_FLY)) &&
- !(r_ptr->flags & RF_AURA_COLD))
- return TRUE;
- else
- return FALSE;
+ return ((r_ptr->flags & RF_IM_FIRE) ||
+ (r_ptr->flags & RF_CAN_FLY)) &&
+ !(r_ptr->flags & RF_AURA_COLD);
}
-void set_mon_num_hook()
+void reset_get_monster_hook()
{
auto const &wf_info = game->edit_data.wf_info;
@@ -1569,38 +1481,38 @@ void set_mon_num_hook()
switch (wf_info[wilderness(p_ptr->wilderness_x, p_ptr->wilderness_y).feat].terrain_idx)
{
case TERRAIN_TOWN:
- get_mon_num_hook = monster_town;
+ get_monster_hook = monster_town;
break;
case TERRAIN_DEEP_WATER:
- get_mon_num_hook = monster_ocean;
+ get_monster_hook = monster_ocean;
break;
case TERRAIN_SHALLOW_WATER:
- get_mon_num_hook = monster_shore;
+ get_monster_hook = monster_shore;
break;
case TERRAIN_DIRT:
- get_mon_num_hook = monster_waste;
+ get_monster_hook = monster_waste;
break;
case TERRAIN_GRASS:
- get_mon_num_hook = monster_grass;
+ get_monster_hook = monster_grass;
break;
case TERRAIN_TREES:
- get_mon_num_hook = monster_wood;
+ get_monster_hook = monster_wood;
break;
case TERRAIN_SHALLOW_LAVA:
case TERRAIN_DEEP_LAVA:
- get_mon_num_hook = monster_volcano;
+ get_monster_hook = monster_volcano;
break;
case TERRAIN_MOUNTAIN:
- get_mon_num_hook = monster_mountain;
+ get_monster_hook = monster_mountain;
break;
default:
- get_mon_num_hook = monster_dungeon;
+ get_monster_hook = monster_dungeon;
break;
}
}
else
{
- get_mon_num_hook = monster_dungeon;
+ get_monster_hook = monster_dungeon;
}
}
@@ -1608,64 +1520,55 @@ void set_mon_num_hook()
/*
* Check if monster can cross terrain
*/
-bool_ monster_can_cross_terrain(byte feat, std::shared_ptr<monster_race> r_ptr)
+bool monster_can_cross_terrain(byte feat, std::shared_ptr<monster_race> r_ptr)
{
/* Deep water */
if (feat == FEAT_DEEP_WATER)
{
- if ((r_ptr->flags & RF_AQUATIC) ||
- (r_ptr->flags & RF_CAN_FLY) ||
- (r_ptr->flags & RF_CAN_SWIM))
- return TRUE;
- else
- return FALSE;
+ return ((r_ptr->flags & RF_AQUATIC) ||
+ (r_ptr->flags & RF_CAN_FLY) ||
+ (r_ptr->flags & RF_CAN_SWIM));
}
/* Shallow water */
else if (feat == FEAT_SHAL_WATER)
{
- if (r_ptr->flags & RF_AURA_FIRE)
- return FALSE;
- else
- return TRUE;
+ return !(r_ptr->flags & RF_AURA_FIRE);
}
/* Aquatic monster */
else if ((r_ptr->flags & RF_AQUATIC) &&
!(r_ptr->flags & RF_CAN_FLY))
{
- return FALSE;
+ return false;
}
/* Lava */
else if ((feat == FEAT_SHAL_LAVA) ||
- (feat == FEAT_DEEP_LAVA))
+ (feat == FEAT_DEEP_LAVA))
{
- if ((r_ptr->flags & RF_IM_FIRE) ||
- (r_ptr->flags & RF_CAN_FLY))
- return TRUE;
- else
- return FALSE;
+ return ((r_ptr->flags & RF_IM_FIRE) ||
+ (r_ptr->flags & RF_CAN_FLY));
}
- return TRUE;
+ return true;
}
-void set_mon_num2_hook(int y, int x)
+void set_monster_aux_hook(int y, int x)
{
/* Set the monster list */
switch (cave[y][x].feat)
{
case FEAT_SHAL_WATER:
- get_mon_num2_hook = monster_shallow_water;
+ get_monster_aux_hook = monster_shallow_water;
break;
case FEAT_DEEP_WATER:
- get_mon_num2_hook = monster_deep_water;
+ get_monster_aux_hook = monster_deep_water;
break;
case FEAT_DEEP_LAVA:
case FEAT_SHAL_LAVA:
- get_mon_num2_hook = monster_lava;
+ get_monster_aux_hook = monster_lava;
break;
default:
- get_mon_num2_hook = NULL;
+ get_monster_aux_hook = NULL;
break;
}
}
diff --git a/src/monster2.cc b/src/monster2.cc
index 624dca53..753b1627 100644
--- a/src/monster2.cc
+++ b/src/monster2.cc
@@ -45,6 +45,8 @@
#include "xtra1.hpp"
#include "xtra2.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
+#include "z-util.hpp"
#include <algorithm>
#include <string>
@@ -62,16 +64,15 @@ s32b monster_exp(s16b level)
return (capped_level * capped_level * capped_level * 6);
}
-/* Monster gain a few levels ? */
-void monster_check_experience(int m_idx, bool_ silent)
+void monster_check_experience(int m_idx, bool silent)
{
auto const &r_info = game->edit_data.r_info;
monster_type *m_ptr = &m_list[m_idx];
auto r_ptr = &r_info[m_ptr->r_idx];
- char m_name[80];
/* Get the name */
+ char m_name[80];
monster_desc(m_name, m_ptr, 0);
/* Gain levels while possible */
@@ -81,7 +82,10 @@ void monster_check_experience(int m_idx, bool_ silent)
/* Gain a level */
m_ptr->level++;
- if (m_ptr->ml && (!silent)) cmsg_format(TERM_L_BLUE, "%^s gains a level.", m_name);
+ if (m_ptr->ml && (!silent))
+ {
+ cmsg_format(TERM_L_BLUE, "%^s gains a level.", m_name);
+ }
/* Gain hp */
if (magik(80))
@@ -109,15 +113,17 @@ void monster_check_experience(int m_idx, bool_ silent)
{
int i = rand_int(3), tries = 20;
- while ((tries--) && !m_ptr->blow[i].d_dice) i = rand_int(3);
+ while ((tries--) && !m_ptr->blow[i].d_dice)
+ {
+ i = rand_int(3);
+ }
m_ptr->blow[i].d_dice++;
}
}
}
-/* Monster gain some xp */
-void monster_gain_exp(int m_idx, u32b exp, bool_ silent)
+void monster_gain_exp(int m_idx, u32b exp)
{
monster_type *m_ptr = &m_list[m_idx];
@@ -125,26 +131,26 @@ void monster_gain_exp(int m_idx, u32b exp, bool_ silent)
if (wizard)
{
char m_name[80];
-
- /* Get the name */
monster_desc(m_name, m_ptr, 0);
-
- if (!silent) msg_format("%^s gains %ld exp.", m_name, exp);
+ msg_format("%^s gains %ld exp.", m_name, exp);
}
- monster_check_experience(m_idx, silent);
+ monster_check_experience(m_idx, false);
}
void monster_set_level(int m_idx, int level)
{
monster_type *m_ptr = &m_list[m_idx];
- if (level > 150) level = 150;
+ if (level > 150)
+ {
+ level = 150;
+ }
if (m_ptr->level < level)
{
m_ptr->exp = monster_exp(level);
- monster_check_experience(m_idx, TRUE);
+ monster_check_experience(m_idx, true);
}
}
@@ -172,45 +178,63 @@ s32b modify_aux(s32b a, s32b b, char mod)
}
/* Is this ego ok for this monster ? */
-bool_ mego_ok(monster_race const *r_ptr, int ego)
+bool mego_ok(monster_race const *r_ptr, int ego)
{
const auto &re_info = game->edit_data.re_info;
auto re_ptr = &re_info[ego];
- bool_ ok = FALSE;
+ bool ok = false;
int i;
/* needed flags */
- if (re_ptr->flags && ((re_ptr->flags & r_ptr->flags) != re_ptr->flags)) return FALSE;
+ if (re_ptr->flags && ((re_ptr->flags & r_ptr->flags) != re_ptr->flags))
+ {
+ return false;
+ }
/* unwanted flags */
- if (re_ptr->hflags && (re_ptr->hflags & r_ptr->flags)) return FALSE;
+ if (re_ptr->hflags && (re_ptr->hflags & r_ptr->flags))
+ {
+ return false;
+ }
/* Need good race -- IF races are specified */
if (re_ptr->r_char[0])
{
for (i = 0; i < 5; i++)
{
- if (r_ptr->d_char == re_ptr->r_char[i]) ok = TRUE;
+ if (r_ptr->d_char == re_ptr->r_char[i])
+ {
+ ok = true;
+ }
+ }
+
+ if (!ok)
+ {
+ return false;
}
- if (!ok) return FALSE;
}
+
if (re_ptr->nr_char[0])
{
for (i = 0; i < 5; i++)
{
- if (r_ptr->d_char == re_ptr->nr_char[i]) return (FALSE);
+ if (r_ptr->d_char == re_ptr->nr_char[i])
+ {
+ return false;
+ }
}
}
- /* Passed all tests ? */
- return TRUE;
+ // Passed all tests
+ return true;
}
/* Choose an ego type */
static int pick_ego_monster(monster_race const *r_ptr)
{
const auto &re_info = game->edit_data.re_info;
+ auto const &dungeon_flags = game->dungeon_flags;
/* Assume no ego */
int ego = 0, lvl;
@@ -356,7 +380,7 @@ std::shared_ptr<monster_race> race_info_idx(int r_idx, int ego)
return nr_ptr;
}
-static cptr horror_desc[MAX_HORROR] =
+static const char *horror_desc[MAX_HORROR] =
{
"abominable",
"abysmal",
@@ -383,7 +407,7 @@ static cptr horror_desc[MAX_HORROR] =
"unspeakable",
};
-static cptr funny_desc[MAX_FUNNY] =
+static const char *funny_desc[MAX_FUNNY] =
{
"silly",
"hilarious",
@@ -413,7 +437,7 @@ static cptr funny_desc[MAX_FUNNY] =
"preposterous",
};
-static cptr funny_comments[MAX_COMMENT] =
+static const char *funny_comments[MAX_COMMENT] =
{
"Wow, cosmic, man!",
"Rad!",
@@ -430,10 +454,6 @@ static cptr funny_comments[MAX_COMMENT] =
*/
void delete_monster_idx(int i)
{
- auto &k_info = game->edit_data.k_info;
- auto &a_info = game->edit_data.a_info;
- auto &random_artifacts = game->random_artifacts;
-
/* Get location */
monster_type *m_ptr = &m_list[i];
int y = m_ptr->fy;
@@ -442,14 +462,14 @@ void delete_monster_idx(int i)
/* Hack -- Reduce the racial counter */
auto const r_ptr = m_ptr->race();
r_ptr->cur_num--;
- r_ptr->on_saved = FALSE;
+ r_ptr->on_saved = false;
/* Hack -- count the number of "reproducers" */
if (r_ptr->spells & SF_MULTIPLY) num_repro--;
/* XXX XXX XXX remove monster light source */
- bool_ had_lite = FALSE;
- if (r_ptr->flags & RF_HAS_LITE) had_lite = TRUE;
+ bool had_lite = false;
+ if (r_ptr->flags & RF_HAS_LITE) had_lite = true;
/* Hack -- remove target monster */
@@ -491,23 +511,7 @@ void delete_monster_idx(int i)
if (options->preserve)
{
- /* Hack -- Preserve unknown artifacts */
- if (artifact_p(o_ptr) && !object_known_p(o_ptr))
- {
- /* Mega-Hack -- Preserve the artifact */
- if (o_ptr->tval == TV_RANDART)
- {
- random_artifacts[o_ptr->sval].generated = FALSE;
- }
- else if (k_info[o_ptr->k_idx].flags & TR_NORM_ART)
- {
- k_info[o_ptr->k_idx].artifact = FALSE;
- }
- else
- {
- a_info[o_ptr->name1].cur_num = 0;
- }
- }
+ rescue_artifact(o_ptr);
}
/* Delete the object */
@@ -528,7 +532,7 @@ void delete_monster_idx(int i)
dungeon_type = DUNGEON_WILDERNESS;
dun_level = 0;
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
}
/* Update monster light */
@@ -814,16 +818,18 @@ s16b m_pop()
/*
* Apply a "monster restriction function" to the "monster allocation table"
*/
-errr get_mon_num_prep()
+void get_mon_num_prep()
{
auto &alloc = game->alloc;
+ auto const &r_info = game->edit_data.r_info;
+
/* Scan the allocation table */
for (auto &&entry: alloc.race_table)
{
/* Accept monsters which pass the restriction, if any */
- if ((!get_mon_num_hook || (*get_mon_num_hook)(entry.index)) &&
- (!get_mon_num2_hook || (*get_mon_num2_hook)(entry.index)))
+ if ((!get_monster_hook || (*get_monster_hook)(&r_info[entry.index])) &&
+ (!get_monster_aux_hook || (*get_monster_aux_hook)(&r_info[entry.index])))
{
/* Accept this monster */
entry.prob2 = entry.prob1;
@@ -836,16 +842,13 @@ errr get_mon_num_prep()
entry.prob2 = 0;
}
}
-
- /* Success */
- return (0);
}
/*
* Some dungeon types restrict the possible monsters.
- * Return TRUE is the monster is OK and FALSE otherwise
+ * Return true is the monster is OK and false otherwise
*/
-static bool_ apply_rule(monster_race const *r_ptr, byte rule)
+static bool apply_rule(monster_race const *r_ptr, byte rule)
{
auto const &d_info = game->edit_data.d_info;
@@ -853,7 +856,7 @@ static bool_ apply_rule(monster_race const *r_ptr, byte rule)
if (d_ptr->rules[rule].mode == DUNGEON_MODE_NONE)
{
- return TRUE;
+ return true;
}
else if ((d_ptr->rules[rule].mode == DUNGEON_MODE_AND) || (d_ptr->rules[rule].mode == DUNGEON_MODE_NAND))
{
@@ -862,40 +865,40 @@ static bool_ apply_rule(monster_race const *r_ptr, byte rule)
if (d_ptr->rules[rule].mflags)
{
if ((d_ptr->rules[rule].mflags & r_ptr->flags) != d_ptr->rules[rule].mflags)
- return FALSE;
+ return false;
}
if (d_ptr->rules[rule].mspells)
{
if ((d_ptr->rules[rule].mspells & r_ptr->spells) != d_ptr->rules[rule].mspells)
- return FALSE;
+ return false;
}
for (a = 0; a < 5; a++)
{
- if (d_ptr->rules[rule].r_char[a] && (d_ptr->rules[rule].r_char[a] != r_ptr->d_char)) return FALSE;
+ if (d_ptr->rules[rule].r_char[a] && (d_ptr->rules[rule].r_char[a] != r_ptr->d_char)) return false;
}
/* All checks passed ? lets go ! */
- return TRUE;
+ return true;
}
else if ((d_ptr->rules[rule].mode == DUNGEON_MODE_OR) || (d_ptr->rules[rule].mode == DUNGEON_MODE_NOR))
{
int a;
- if (d_ptr->rules[rule].mflags && (r_ptr->flags & d_ptr->rules[rule].mflags)) return TRUE;
- if (d_ptr->rules[rule].mspells && (r_ptr->spells & d_ptr->rules[rule].mspells)) return TRUE;
+ if (d_ptr->rules[rule].mflags && (r_ptr->flags & d_ptr->rules[rule].mflags)) return true;
+ if (d_ptr->rules[rule].mspells && (r_ptr->spells & d_ptr->rules[rule].mspells)) return true;
for (a = 0; a < 5; a++)
- if (d_ptr->rules[rule].r_char[a] == r_ptr->d_char) return TRUE;
+ if (d_ptr->rules[rule].r_char[a] == r_ptr->d_char) return true;
/* All checks failled ? Sorry ... */
- return FALSE;
+ return false;
}
/* Should NEVER happen */
- return FALSE;
+ return false;
}
-bool_ restrict_monster_to_dungeon(int r_idx)
+bool restrict_monster_to_dungeon(int r_idx)
{
auto const &d_info = game->edit_data.d_info;
auto const &r_info = game->edit_data.r_info;
@@ -907,20 +910,20 @@ bool_ restrict_monster_to_dungeon(int r_idx)
byte rule = d_ptr->rule_percents[rand_int(100)];
/* Apply the rule */
- bool_ rule_ret = apply_rule(r_ptr, rule);
+ bool rule_ret = apply_rule(r_ptr, rule);
/* Should the rule be right or not ? */
if ((d_ptr->rules[rule].mode == DUNGEON_MODE_NAND) || (d_ptr->rules[rule].mode == DUNGEON_MODE_NOR)) rule_ret = !rule_ret;
/* Rule ok ? */
- if (rule_ret) return TRUE;
+ if (rule_ret) return true;
/* Not allowed */
- return FALSE;
+ return false;
}
/* Ugly hack, let summon unappropriate monsters */
-bool_ summon_hack = FALSE;
+bool summon_hack = false;
/*
* Choose a monster race that seems "appropriate" to the given level
@@ -954,8 +957,6 @@ s16b get_mon_num(int level)
int r_idx;
long value, total;
- int in_tome;
-
/* Boost the level */
if (level > 0)
{
@@ -984,9 +985,6 @@ s16b get_mon_num(int level)
/* Reset total */
total = 0L;
- /* Check whether this is ToME or a module */
- in_tome = strcmp(game_module, "ToME") == 0;
-
/* Process probabilities */
for (i = 0; i < alloc.race_table.size(); i++)
{
@@ -1163,14 +1161,14 @@ s16b get_mon_num(int level)
* 0x22 --> Possessive, genderized if visible ("his") or "its"
* 0x23 --> Reflexive, genderized if visible ("himself") or "itself"
*/
-void monster_desc(char *desc, monster_type *m_ptr, int mode)
+void monster_desc(char *desc, monster_type const *m_ptr, int mode)
{
auto const &re_info = game->edit_data.re_info;
auto const &r_info = game->edit_data.r_info;
auto r_ptr = m_ptr->race();
char silly_name[80], name[100];
- bool_ seen, pron;
+ bool seen, pron;
int insanity = (p_ptr->msane - p_ptr->csane) * 100 / p_ptr->msane;
if (m_ptr->ego)
@@ -1238,7 +1236,7 @@ void monster_desc(char *desc, monster_type *m_ptr, int mode)
/* Assume simple result */
- cptr res = "it";
+ const char *res = "it";
/* Brute force: split on the possibilities */
switch (kind | (mode & 0x07))
@@ -1425,9 +1423,9 @@ void monster_race_desc(char *desc, int r_idx, int ego)
-static void sanity_blast(monster_type * m_ptr, bool_ necro)
+static void sanity_blast(monster_type * m_ptr, bool necro)
{
- bool_ happened = FALSE;
+ bool happened = false;
int power = 100;
if (!necro)
@@ -1546,8 +1544,8 @@ static void sanity_blast(monster_type * m_ptr, bool_ necro)
if (randint(power) < p_ptr->skill_sav) /* Permanent lose int & wis */
{
- if (dec_stat(A_INT, 10, TRUE)) happened = TRUE;
- if (dec_stat(A_WIS, 10, TRUE)) happened = TRUE;
+ if (dec_stat(A_INT, 10, true)) happened = true;
+ if (dec_stat(A_WIS, 10, true)) happened = true;
if (happened)
msg_print("You feel much less sane than before.");
return;
@@ -1620,7 +1618,7 @@ static void sanity_blast(monster_type * m_ptr, bool_ necro)
* as "detected last turn", and "detected this turn", and "currently
* in line of sight", all of which are used for visibility testing.
*/
-void update_mon(int m_idx, bool_ full)
+void update_mon(int m_idx, bool full)
{
monster_type *m_ptr = &m_list[m_idx];
@@ -1628,13 +1626,13 @@ void update_mon(int m_idx, bool_ full)
const int fy = m_ptr->fy;
const int fx = m_ptr->fx;
- const bool_ old_ml = m_ptr->ml;
+ const bool old_ml = m_ptr->ml;
/* Seen at all */
- bool_ flag = FALSE;
+ bool flag = false;
/* Seen by vision */
- bool_ easy = FALSE;
+ bool easy = false;
auto const r_ptr = m_ptr->race();
@@ -1660,7 +1658,7 @@ void update_mon(int m_idx, bool_ full)
if (!m_ptr->ml) return;
/* Detected */
- if (m_ptr->mflag & (MFLAG_MARK)) flag = TRUE;
+ if (m_ptr->mflag & (MFLAG_MARK)) flag = true;
}
/* Process "nearby" monsters on the current "panel" */
@@ -1677,7 +1675,7 @@ void update_mon(int m_idx, bool_ full)
if (!(r_ptr->flags & RF_COLD_BLOOD))
{
/* Infravision works */
- easy = flag = TRUE;
+ easy = flag = true;
}
}
@@ -1687,7 +1685,7 @@ void update_mon(int m_idx, bool_ full)
/* Visible, or detectable, monsters get seen */
if (p_ptr->see_inv || !(r_ptr->flags & RF_INVISIBLE))
{
- easy = flag = TRUE;
+ easy = flag = true;
}
}
}
@@ -1727,23 +1725,23 @@ void update_mon(int m_idx, bool_ full)
{
if (rand_int(100) < 10)
{
- flag = TRUE;
+ flag = true;
}
}
/* Normal mind, allow telepathy */
else
{
- flag = TRUE;
+ flag = true;
}
}
}
/* Apply "detection" spells */
- if (m_ptr->mflag & (MFLAG_MARK)) flag = TRUE;
+ if (m_ptr->mflag & (MFLAG_MARK)) flag = true;
/* Hack -- Wizards have "perfect telepathy" */
- if (wizard) flag = TRUE;
+ if (wizard) flag = true;
}
@@ -1754,7 +1752,7 @@ void update_mon(int m_idx, bool_ full)
if (!m_ptr->ml)
{
/* Mark as visible */
- m_ptr->ml = TRUE;
+ m_ptr->ml = true;
/* Draw the monster */
lite_spot(fy, fx);
@@ -1783,7 +1781,7 @@ void update_mon(int m_idx, bool_ full)
if (m_ptr->ml)
{
/* Mark as not visible */
- m_ptr->ml = FALSE;
+ m_ptr->ml = false;
/* Erase the monster */
lite_spot(fy, fx);
@@ -1814,7 +1812,7 @@ void update_mon(int m_idx, bool_ full)
{
if (r_ptr->flags & RF_ELDRITCH_HORROR)
{
- sanity_blast(m_ptr, FALSE);
+ sanity_blast(m_ptr, false);
}
}
@@ -1866,7 +1864,7 @@ void update_mon(int m_idx, bool_ full)
/*
* This function simply updates all the (non-dead) monsters (see above).
*/
-void update_monsters(bool_ full)
+void update_monsters(bool full)
{
int i;
@@ -1886,7 +1884,6 @@ void update_monsters(bool_ full)
void monster_carry(monster_type *m_ptr, int m_idx, object_type *q_ptr)
{
- auto &k_info = game->edit_data.k_info;
auto &a_info = game->edit_data.a_info;
auto &random_artifacts = game->random_artifacts;
@@ -1916,13 +1913,13 @@ void monster_carry(monster_type *m_ptr, int m_idx, object_type *q_ptr)
{
a_info[q_ptr->name1].cur_num = 0;
}
- else if (k_info[q_ptr->k_idx].flags & TR_NORM_ART)
+ else if (q_ptr->k_ptr->flags & TR_NORM_ART)
{
- k_info[q_ptr->k_idx].artifact = 0;
+ q_ptr->k_ptr->artifact = false;
}
else if (q_ptr->tval == TV_RANDART)
{
- random_artifacts[q_ptr->sval].generated = FALSE;
+ random_artifacts[q_ptr->sval].generated = false;
}
}
}
@@ -1952,20 +1949,22 @@ static int possible_randart[] =
};
-bool_ kind_is_randart(int k_idx)
+static bool kind_is_randart(object_kind const *k_ptr)
{
- auto const &k_info = game->edit_data.k_info;
-
- int max;
- auto k_ptr = &k_info[k_idx];
-
- if (!kind_is_legal(k_idx)) return (FALSE);
+ if (!kind_is_legal(k_ptr))
+ {
+ return false;
+ }
- for (max = 0; possible_randart[max] != -1; max++)
+ for (int max = 0; possible_randart[max] != -1; max++)
{
- if (k_ptr->tval == possible_randart[max]) return (TRUE);
+ if (k_ptr->tval == possible_randart[max])
+ {
+ return true;
+ }
}
- return (FALSE);
+
+ return false;
}
/*
@@ -1987,18 +1986,19 @@ bool_ kind_is_randart(int k_idx)
* This is the only function which may place a monster in the dungeon,
* except for the savefile loading code.
*/
-bool_ bypass_r_ptr_max_num = FALSE;
+bool bypass_r_ptr_max_num = false;
static int place_monster_result = 0;
-bool_ place_monster_one_no_drop = FALSE;
+bool place_monster_one_no_drop = false;
static s16b hack_m_idx_ii = 0;
-s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
+s16b place_monster_one(int y, int x, int r_idx, int ego, bool slp, int status)
{
auto &r_info = game->edit_data.r_info;
+ auto &k_info = game->edit_data.k_info;
auto &alloc = game->alloc;
+ auto const &dungeon_flags = game->dungeon_flags;
int i;
- char dummy[5];
- bool_ add_level = FALSE;
+ bool add_level = false;
int min_level = 0, max_level = 0;
/* DO NOT PLACE A MONSTER IN THE SMALL SCALE WILDERNESS !!! */
@@ -2050,13 +2050,6 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
return 0;
}
- /* Nor on the Pattern */
- if ((cave[y][x].feat >= FEAT_PATTERN_START)
- && (cave[y][x].feat <= FEAT_PATTERN_XTRA2))
- {
- return 0;
- }
-
/* Paranoia */
if (!r_idx)
{
@@ -2232,7 +2225,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
m_ptr->mflag = 0;
/* Not visible */
- m_ptr->ml = FALSE;
+ m_ptr->ml = false;
/* No objects yet */
m_ptr->hold_o_idxs.clear();
@@ -2263,8 +2256,8 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
/* Only if not fated to die */
if ((dungeon_type != DUNGEON_DEATH) && (!place_monster_one_no_drop))
{
- const bool_ good = (r_ptr->flags & RF_DROP_GOOD) ? TRUE : FALSE;
- const bool_ great = (r_ptr->flags & RF_DROP_GREAT) ? TRUE : FALSE;
+ const bool good = (r_ptr->flags & RF_DROP_GOOD) ? true : false;
+ const bool great = (r_ptr->flags & RF_DROP_GREAT) ? true : false;
auto const do_gold = (r_ptr->flags & RF_ONLY_ITEM).empty();
auto const do_item = (r_ptr->flags & RF_ONLY_GOLD).empty();
@@ -2304,7 +2297,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
init_match_theme(obj_theme::no_theme());
/* Apply restriction */
- get_obj_num_hook = kind_is_legal;
+ get_object_hook = kind_is_legal;
/* Rebuild allocation table */
get_obj_num_prep();
@@ -2316,7 +2309,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
i = get_obj_num(dun_level);
if (!i) continue;
- if (!kind_is_randart(i)) continue;
+ if (!kind_is_randart(k_info.at(i).get())) continue;
break;
}
@@ -2326,7 +2319,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
if (tries)
{
object_prep(q_ptr, i);
- create_artifact(q_ptr, FALSE, TRUE);
+ create_artifact(q_ptr, false, true);
q_ptr->found = OBJ_FOUND_MONSTER;
q_ptr->found_aux1 = m_ptr->r_idx;
q_ptr->found_aux2 = m_ptr->ego;
@@ -2395,7 +2388,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
/* Reset "coin" type */
coin_type = 0;
}
- place_monster_one_no_drop = FALSE;
+ place_monster_one_no_drop = false;
/* Assign maximal hitpoints */
@@ -2439,19 +2432,19 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
if (dungeon_flags & DF_ADJUST_LEVEL_1_2)
{
min_level = max_level = dun_level / 2;
- add_level = TRUE;
+ add_level = true;
}
if (dungeon_flags & DF_ADJUST_LEVEL_1)
{
if (!min_level) min_level = dun_level;
max_level = dun_level;
- add_level = TRUE;
+ add_level = true;
}
if (dungeon_flags & DF_ADJUST_LEVEL_2)
{
if (!min_level) min_level = dun_level * 2;
max_level = dun_level * 2;
- add_level = TRUE;
+ add_level = true;
}
if (add_level) monster_set_level(c_ptr->m_idx, rand_range(min_level, max_level));
@@ -2465,7 +2458,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
m_ptr->mflag |= (MFLAG_NICE);
/* Must repair monsters */
- repair_monsters = TRUE;
+ repair_monsters = true;
}
/* Hack -- see "process_monsters()" */
@@ -2477,7 +2470,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
/* Update the monster */
- update_mon(c_ptr->m_idx, TRUE);
+ update_mon(c_ptr->m_idx, true);
/* Hack -- Count the number of "reproducers" */
@@ -2485,7 +2478,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
/* Hack -- Notice new multi-hued monsters */
- if (r_ptr->flags & RF_ATTR_MULTI) shimmer_monsters = TRUE;
+ if (r_ptr->flags & RF_ATTR_MULTI) shimmer_monsters = true;
/* Count monsters on the level */
{
@@ -2497,9 +2490,9 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
}
/* Unique monsters on saved levels should be "marked" */
- if ((r_ptr->flags & RF_UNIQUE) && get_dungeon_save(dummy))
+ if ((r_ptr->flags & RF_UNIQUE) && get_dungeon_save_extension())
{
- r_ptr->on_saved = TRUE;
+ r_ptr->on_saved = true;
}
/* Processs hooks */
@@ -2522,7 +2515,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
/*
* Attempt to place a "group" of monsters around the given location
*/
-static bool_ place_monster_group(int y, int x, int r_idx, bool_ slp, int status)
+static bool place_monster_group(int y, int x, int r_idx, bool slp, int status)
{
auto const &r_info = game->edit_data.r_info;
@@ -2607,42 +2600,37 @@ static bool_ place_monster_group(int y, int x, int r_idx, bool_ slp, int status)
/* Success */
- return (TRUE);
+ return true;
}
/*
* Hack -- help pick an escort type
*/
-static int place_monster_idx = 0;
+static monster_race const *place_monster_ptr = nullptr;
/*
* Hack -- help pick an escort type
*/
-static bool_ place_monster_okay(int r_idx)
+static bool place_monster_okay(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[place_monster_idx];
- auto z_ptr = &r_info[r_idx];
-
/* Hack - Escorts have to have the same dungeon flag */
- if (monster_dungeon(place_monster_idx) != monster_dungeon(r_idx)) return (FALSE);
+ if (monster_dungeon(place_monster_ptr) != monster_dungeon(r_ptr)) return false;
/* Require similar "race" */
- if (z_ptr->d_char != r_ptr->d_char) return (FALSE);
+ if (r_ptr->d_char != place_monster_ptr->d_char) return false;
/* Skip more advanced monsters */
- if (z_ptr->level > r_ptr->level) return (FALSE);
+ if (r_ptr->level > place_monster_ptr->level) return false;
/* Skip unique monsters */
- if (z_ptr->flags & RF_UNIQUE) return (FALSE);
+ if (r_ptr->flags & RF_UNIQUE) return false;
/* Paranoia -- Skip identical monsters */
- if (place_monster_idx == r_idx) return (FALSE);
+ if (place_monster_ptr == r_ptr) return false;
/* Okay */
- return (TRUE);
+ return true;
}
@@ -2651,7 +2639,7 @@ static bool_ place_monster_okay(int r_idx)
*
* Note that certain monsters are now marked as requiring "friends".
* These monsters, if successfully placed, and if the "grp" parameter
- * is TRUE, will be surrounded by a "group" of identical monsters.
+ * is true, will be surrounded by a "group" of identical monsters.
*
* Note that certain monsters are now marked as requiring an "escort",
* which is a collection of monsters with similar "race" but lower level.
@@ -2664,21 +2652,21 @@ static bool_ place_monster_okay(int r_idx)
* Note the use of the new "monster allocation table" code to restrict
* the "get_mon_num()" function to "legal" escort types.
*/
-bool_ place_monster_aux(int y, int x, int r_idx, bool_ slp, bool_ grp, int status)
+bool place_monster_aux(int y, int x, int r_idx, bool slp, bool grp, int status)
{
auto const &r_info = game->edit_data.r_info;
int i;
auto r_ptr = &r_info[r_idx];
- bool_ (*old_get_mon_num_hook)(int r_idx);
+ bool (*old_get_monster_hook)(monster_race const *);
/* Place one monster, or fail */
- if (!place_monster_one(y, x, r_idx, pick_ego_monster(r_ptr), slp, status)) return (FALSE);
+ if (!place_monster_one(y, x, r_idx, pick_ego_monster(r_ptr), slp, status)) return false;
/* Require the "group" flag */
- if (!grp) return (TRUE);
+ if (!grp) return true;
/* Friends for certain monsters */
@@ -2692,13 +2680,13 @@ bool_ place_monster_aux(int y, int x, int r_idx, bool_ slp, bool_ grp, int statu
/* Escorts for certain monsters */
if (r_ptr->flags & RF_ESCORT)
{
- old_get_mon_num_hook = get_mon_num_hook;
+ old_get_monster_hook = get_monster_hook;
/* Set the escort index */
- place_monster_idx = r_idx;
+ place_monster_ptr = &r_info[r_idx];
/* Set the escort hook */
- get_mon_num_hook = place_monster_okay;
+ get_monster_hook = place_monster_okay;
/* Prepare allocation table */
get_mon_num_prep();
@@ -2714,7 +2702,7 @@ bool_ place_monster_aux(int y, int x, int r_idx, bool_ slp, bool_ grp, int statu
/* Require empty grids */
if (!cave_empty_bold(ny, nx)) continue;
- set_mon_num2_hook(ny, nx);
+ set_monster_aux_hook(ny, nx);
/* Prepare allocation table */
get_mon_num_prep();
@@ -2723,7 +2711,7 @@ bool_ place_monster_aux(int y, int x, int r_idx, bool_ slp, bool_ grp, int statu
z = get_mon_num(r_ptr->level);
/* Reset restriction */
- get_mon_num2_hook = NULL;
+ get_monster_aux_hook = NULL;
/* Prepare allocation table */
get_mon_num_prep();
@@ -2744,14 +2732,14 @@ bool_ place_monster_aux(int y, int x, int r_idx, bool_ slp, bool_ grp, int statu
}
/* Reset restriction */
- get_mon_num_hook = old_get_mon_num_hook;
+ get_monster_hook = old_get_monster_hook;
/* Prepare allocation table */
get_mon_num_prep();
}
/* Success */
- return (TRUE);
+ return true;
}
@@ -2760,12 +2748,12 @@ bool_ place_monster_aux(int y, int x, int r_idx, bool_ slp, bool_ grp, int statu
*
* Attempt to find a monster appropriate to the "monster_level"
*/
-bool_ place_monster(int y, int x, bool_ slp, bool_ grp)
+bool place_monster(int y, int x, bool slp, bool grp)
{
int r_idx;
/* Set monster restriction */
- set_mon_num2_hook(y, x);
+ set_monster_aux_hook(y, x);
/* Prepare allocation table */
get_mon_num_prep();
@@ -2774,23 +2762,23 @@ bool_ place_monster(int y, int x, bool_ slp, bool_ grp)
r_idx = get_mon_num(monster_level);
/* Reset restriction */
- get_mon_num2_hook = NULL;
+ get_monster_aux_hook = NULL;
/* Prepare allocation table */
get_mon_num_prep();
/* Handle failure */
- if (!r_idx) return (FALSE);
+ if (!r_idx) return false;
/* Attempt to place the monster */
- if (place_monster_aux(y, x, r_idx, slp, grp, MSTATUS_ENEMY)) return (TRUE);
+ if (place_monster_aux(y, x, r_idx, slp, grp, MSTATUS_ENEMY)) return true;
/* Oops */
- return (FALSE);
+ return false;
}
-bool_ alloc_horde(int y, int x)
+bool alloc_horde(int y, int x)
{
auto const &r_info = game->edit_data.r_info;
@@ -2799,7 +2787,7 @@ bool_ alloc_horde(int y, int x)
monster_type *m_ptr;
int attempts = 1000;
- set_mon_num2_hook(y, x);
+ set_monster_aux_hook(y, x);
/* Prepare allocation table */
get_mon_num_prep();
@@ -2810,7 +2798,7 @@ bool_ alloc_horde(int y, int x)
r_idx = get_mon_num(monster_level);
/* Handle failure */
- if (!r_idx) return (FALSE);
+ if (!r_idx) return false;
r_ptr = &r_info[r_idx];
@@ -2819,22 +2807,22 @@ bool_ alloc_horde(int y, int x)
break;
}
- get_mon_num2_hook = NULL;
+ get_monster_aux_hook = NULL;
/* Prepare allocation table */
get_mon_num_prep();
- if (attempts < 1) return FALSE;
+ if (attempts < 1) return false;
attempts = 1000;
while (--attempts)
{
/* Attempt to place the monster */
- if (place_monster_aux(y, x, r_idx, FALSE, FALSE, MSTATUS_ENEMY)) break;
+ if (place_monster_aux(y, x, r_idx, false, false, MSTATUS_ENEMY)) break;
}
- if (attempts < 1) return FALSE;
+ if (attempts < 1) return false;
m_ptr = &m_list[hack_m_idx_ii];
@@ -2846,7 +2834,7 @@ bool_ alloc_horde(int y, int x)
summon_specific(m_ptr->fy, m_ptr->fx, dun_level, SUMMON_KIN);
}
- return TRUE;
+ return true;
}
/*
@@ -2858,7 +2846,7 @@ bool_ alloc_horde(int y, int x)
*
* Use "monster_level" for the monster level
*/
-bool_ alloc_monster(int dis, bool_ slp)
+bool alloc_monster(int dis, bool slp)
{
int y, x;
int attempts_left = 10000;
@@ -2884,7 +2872,7 @@ bool_ alloc_monster(int dis, bool_ slp)
msg_print("Warning! Could not allocate a new monster. Small level?");
}
- return (FALSE);
+ return false;
}
@@ -2896,19 +2884,19 @@ bool_ alloc_monster(int dis, bool_ slp)
{
msg_print("Monster horde.");
}
- return (TRUE);
+ return true;
}
}
else
{
/* Attempt to place the monster, allow groups */
- if (place_monster(y, x, slp, TRUE)) return (TRUE);
+ if (place_monster(y, x, slp, true)) return true;
}
/* Nope */
- return (FALSE);
+ return false;
}
@@ -2923,188 +2911,159 @@ static int summon_specific_type = 0;
/*
* Hack -- help decide if a monster race is "okay" to summon
*/
-static bool_ summon_specific_okay(int r_idx)
+static bool summon_specific_okay(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
- bool_ okay = FALSE;
-
/* Hack - Only summon dungeon monsters */
- if (!monster_dungeon(r_idx)) return (FALSE);
+ if (!monster_dungeon(r_ptr)) return false;
/* Hack -- no specific type specified */
- if (!summon_specific_type) return (TRUE);
+ if (!summon_specific_type) return true;
/* Check our requirements */
switch (summon_specific_type)
{
case SUMMON_ANT:
{
- okay = ((r_ptr->d_char == 'a') &&
+ return ((r_ptr->d_char == 'a') &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_SPIDER:
{
- okay = ((r_ptr->d_char == 'S') &&
+ return ((r_ptr->d_char == 'S') &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_HOUND:
{
- okay = (((r_ptr->d_char == 'C') || (r_ptr->d_char == 'Z')) &&
+ return (((r_ptr->d_char == 'C') || (r_ptr->d_char == 'Z')) &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_HYDRA:
{
- okay = ((r_ptr->d_char == 'M') &&
+ return ((r_ptr->d_char == 'M') &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_ANGEL:
{
- okay = ((r_ptr->d_char == 'A') &&
+ return ((r_ptr->d_char == 'A') &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_DEMON:
{
- okay = ((r_ptr->flags & RF_DEMON) &&
+ return ((r_ptr->flags & RF_DEMON) &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_UNDEAD:
{
- okay = ((r_ptr->flags & RF_UNDEAD) &&
+ return ((r_ptr->flags & RF_UNDEAD) &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_DRAGON:
{
- okay = ((r_ptr->flags & RF_DRAGON) &&
+ return ((r_ptr->flags & RF_DRAGON) &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_HI_UNDEAD:
{
- okay = ((r_ptr->d_char == 'L') ||
+ return ((r_ptr->d_char == 'L') ||
(r_ptr->d_char == 'V') ||
(r_ptr->d_char == 'W'));
- break;
}
case SUMMON_HI_DRAGON:
{
- okay = (r_ptr->d_char == 'D');
- break;
+ return (r_ptr->d_char == 'D');
}
case SUMMON_WRAITH:
{
- okay = (r_ptr->d_char == 'W');
- break;
+ return (r_ptr->d_char == 'W');
}
case SUMMON_GHOST:
{
- okay = (r_ptr->d_char == 'G');
- break;
+ return (r_ptr->d_char == 'G');
}
case SUMMON_UNIQUE:
{
- okay = (r_ptr->flags & RF_UNIQUE) ? TRUE : FALSE;
- break;
+ return bool(r_ptr->flags & RF_UNIQUE);
}
case SUMMON_BIZARRE1:
{
- okay = ((r_ptr->d_char == 'm') &&
+ return ((r_ptr->d_char == 'm') &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_BIZARRE2:
{
- okay = ((r_ptr->d_char == 'b') &&
+ return ((r_ptr->d_char == 'b') &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_BIZARRE3:
{
- okay = ((r_ptr->d_char == 'Q') &&
+ return ((r_ptr->d_char == 'Q') &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_BIZARRE4:
{
- okay = ((r_ptr->d_char == 'v') &&
+ return ((r_ptr->d_char == 'v') &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_BIZARRE5:
{
- okay = ((r_ptr->d_char == '$') &&
+ return ((r_ptr->d_char == '$') &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_BIZARRE6:
{
- okay = (((r_ptr->d_char == '!') ||
+ return (((r_ptr->d_char == '!') ||
(r_ptr->d_char == '?') ||
(r_ptr->d_char == '=') ||
(r_ptr->d_char == '$') ||
(r_ptr->d_char == '|')) &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_HI_DEMON:
{
- okay = ((r_ptr->flags & RF_DEMON) &&
+ return ((r_ptr->flags & RF_DEMON) &&
(r_ptr->d_char == 'U') &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_KIN:
{
- okay = ((r_ptr->d_char == summon_kin_type) &&
+ return ((r_ptr->d_char == summon_kin_type) &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_DAWN:
{
- okay = ((strstr(r_ptr->name, "the Dawn")) &&
+ return ((strstr(r_ptr->name, "the Dawn")) &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_ANIMAL:
{
- okay = ((r_ptr->flags & RF_ANIMAL) &&
+ return ((r_ptr->flags & RF_ANIMAL) &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_ANIMAL_RANGER:
{
- okay = ((r_ptr->flags & RF_ANIMAL) &&
+ return ((r_ptr->flags & RF_ANIMAL) &&
(strchr("abcflqrwBCIJKMRS", r_ptr->d_char)) &&
!(r_ptr->flags & RF_DRAGON) &&
!(r_ptr->flags & RF_EVIL) &&
@@ -3112,108 +3071,93 @@ static bool_ summon_specific_okay(int r_idx)
!(r_ptr->flags & RF_DEMON) &&
!r_ptr->spells &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_HI_UNDEAD_NO_UNIQUES:
{
- okay = (((r_ptr->d_char == 'L') ||
+ return (((r_ptr->d_char == 'L') ||
(r_ptr->d_char == 'V') ||
(r_ptr->d_char == 'W')) &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_HI_DRAGON_NO_UNIQUES:
{
- okay = ((r_ptr->d_char == 'D') &&
+ return ((r_ptr->d_char == 'D') &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_NO_UNIQUES:
{
- okay = (!(r_ptr->flags & RF_UNIQUE));
- break;
+ return (!(r_ptr->flags & RF_UNIQUE));
}
case SUMMON_PHANTOM:
{
- okay = ((strstr(r_ptr->name, "Phantom")) &&
+ return ((strstr(r_ptr->name, "Phantom")) &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_ELEMENTAL:
{
- okay = ((strstr(r_ptr->name, "lemental")) &&
+ return ((strstr(r_ptr->name, "lemental")) &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_THUNDERLORD:
{
- okay = (r_ptr->flags & RF_THUNDERLORD) ? TRUE : FALSE;
- break;
+ return bool(r_ptr->flags & RF_THUNDERLORD);
}
case SUMMON_BLUE_HORROR:
{
- okay = ((strstr(r_ptr->name, "lue horror")) &&
+ return ((strstr(r_ptr->name, "lue horror")) &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_BUG:
{
- okay = ((strstr(r_ptr->name, "Software bug")) &&
+ return ((strstr(r_ptr->name, "Software bug")) &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_RNG:
{
- okay = ((strstr(r_ptr->name, "Random Number Generator")) &&
+ return ((strstr(r_ptr->name, "Random Number Generator")) &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_MINE:
{
- okay = (r_ptr->flags & RF_NEVER_MOVE) ? TRUE : FALSE;
- break;
+ return (r_ptr->flags & RF_NEVER_MOVE) ? true : false;
}
case SUMMON_HUMAN:
{
- okay = ((r_ptr->d_char == 'p') &&
+ return ((r_ptr->d_char == 'p') &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_SHADOWS:
{
- okay = ((r_ptr->d_char == 'G') &&
+ return ((r_ptr->d_char == 'G') &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
case SUMMON_QUYLTHULG:
{
- okay = ((r_ptr->d_char == 'Q') &&
+ return ((r_ptr->d_char == 'Q') &&
!(r_ptr->flags & RF_UNIQUE));
- break;
}
}
- /* Result */
- return (okay);
+ return false;
}
/*
* Place a monster (of the specified "type") near the given
- * location. Return TRUE if a monster was actually summoned.
+ * location. Return true if a monster was actually summoned.
*
* We will attempt to place the monster up to 10 times before giving up.
*
@@ -3236,11 +3180,11 @@ static bool_ summon_specific_okay(int r_idx)
* Note that this function may not succeed, though this is very rare.
*/
int summon_specific_level = 0;
-bool_ summon_specific(int y1, int x1, int lev, int type)
+bool summon_specific(int y1, int x1, int lev, int type)
{
int i, x, y, r_idx;
- bool_ Group_ok = TRUE;
- bool_ (*old_get_mon_num_hook)(int r_idx);
+ bool Group_ok = true;
+ bool (*old_get_monster_hook)(monster_race const *);
/* Look for a location */
for (i = 0; i < 20; ++i)
@@ -3259,56 +3203,51 @@ bool_ summon_specific(int y1, int x1, int lev, int type)
if (cave[y][x].feat == FEAT_MINOR_GLYPH) continue;
/* Nor on the between */
- if (cave[y][x].feat == FEAT_BETWEEN) return (FALSE);
-
- /* ... nor on the Pattern */
- if ((cave[y][x].feat >= FEAT_PATTERN_START) &&
- (cave[y][x].feat <= FEAT_PATTERN_XTRA2))
- continue;
+ if (cave[y][x].feat == FEAT_BETWEEN) return false;
/* Okay */
break;
}
/* Failure */
- if (i == 20) return (FALSE);
+ if (i == 20) return false;
/* Save the "summon" type */
summon_specific_type = type;
/* Backup the old hook */
- old_get_mon_num_hook = get_mon_num_hook;
+ old_get_monster_hook = get_monster_hook;
/* Require "okay" monsters */
- get_mon_num_hook = summon_specific_okay;
+ get_monster_hook = summon_specific_okay;
/* Prepare allocation table */
get_mon_num_prep();
/* Pick a monster, using the level calculation */
- summon_hack = TRUE;
+ summon_hack = true;
r_idx = get_mon_num((dun_level + lev) / 2 + 5);
- summon_hack = FALSE;
+ summon_hack = false;
/* Reset restriction */
- get_mon_num_hook = old_get_mon_num_hook;
+ get_monster_hook = old_get_monster_hook;
/* Prepare allocation table */
get_mon_num_prep();
/* Handle failure */
- if (!r_idx) return (FALSE);
+ if (!r_idx) return false;
if ((type == SUMMON_DAWN) || (type == SUMMON_BLUE_HORROR))
{
- Group_ok = FALSE;
+ Group_ok = false;
}
/* Attempt to place the monster (awake, allow groups) */
- if (!place_monster_aux(y, x, r_idx, FALSE, Group_ok, MSTATUS_ENEMY)) return (FALSE);
+ if (!place_monster_aux(y, x, r_idx, false, Group_ok, MSTATUS_ENEMY)) return false;
if (summon_specific_level)
{
monster_set_level(place_monster_result, summon_specific_level);
@@ -3316,15 +3255,15 @@ bool_ summon_specific(int y1, int x1, int lev, int type)
}
/* Success */
- return (TRUE);
+ return true;
}
-bool_ summon_specific_friendly(int y1, int x1, int lev, int type, bool_ Group_ok)
+bool summon_specific_friendly(int y1, int x1, int lev, int type, bool Group_ok)
{
int i, x, y, r_idx;
- bool_ (*old_get_mon_num_hook)(int r_idx);
+ bool (*old_get_monster_hook)(monster_race const *);
/* Look for a location */
for (i = 0; i < 20; ++i)
@@ -3343,27 +3282,22 @@ bool_ summon_specific_friendly(int y1, int x1, int lev, int type, bool_ Group_ok
if (cave[y][x].feat == FEAT_MINOR_GLYPH) continue;
/* Nor on the between */
- if (cave[y][x].feat == FEAT_BETWEEN) return (FALSE);
-
- /* ... nor on the Pattern */
- if ((cave[y][x].feat >= FEAT_PATTERN_START) &&
- (cave[y][x].feat <= FEAT_PATTERN_XTRA2))
- continue;
+ if (cave[y][x].feat == FEAT_BETWEEN) return false;
/* Okay */
break;
}
/* Failure */
- if (i == 20) return (FALSE);
+ if (i == 20) return false;
- old_get_mon_num_hook = get_mon_num_hook;
+ old_get_monster_hook = get_monster_hook;
/* Save the "summon" type */
summon_specific_type = type;
/* Require "okay" monsters */
- get_mon_num_hook = summon_specific_okay;
+ get_monster_hook = summon_specific_okay;
/* Prepare allocation table */
get_mon_num_prep();
@@ -3372,16 +3306,16 @@ bool_ summon_specific_friendly(int y1, int x1, int lev, int type, bool_ Group_ok
r_idx = get_mon_num((dun_level + lev) / 2 + 5);
/* Reset restriction */
- get_mon_num_hook = old_get_mon_num_hook;
+ get_monster_hook = old_get_monster_hook;
/* Prepare allocation table */
get_mon_num_prep();
/* Handle failure */
- if (!r_idx) return (FALSE);
+ if (!r_idx) return false;
/* Attempt to place the monster (awake, allow groups) */
- if (!place_monster_aux(y, x, r_idx, FALSE, Group_ok, MSTATUS_PET)) return (FALSE);
+ if (!place_monster_aux(y, x, r_idx, false, Group_ok, MSTATUS_PET)) return false;
if (summon_specific_level)
{
monster_set_level(place_monster_result, summon_specific_level);
@@ -3389,7 +3323,7 @@ bool_ summon_specific_friendly(int y1, int x1, int lev, int type, bool_ Group_ok
}
/* Success */
- return (TRUE);
+ return true;
}
@@ -3426,7 +3360,7 @@ void monster_swap(int y1, int x1, int y2, int x2)
m_ptr->fx = x2;
/* Update monster */
- update_mon(m1, TRUE);
+ update_mon(m1, true);
}
/* Player 1 */
@@ -3463,7 +3397,7 @@ void monster_swap(int y1, int x1, int y2, int x2)
m_ptr->fx = x1;
/* Update monster */
- update_mon(m2, TRUE);
+ update_mon(m2, true);
}
/* Player 2 */
@@ -3500,21 +3434,13 @@ void monster_swap(int y1, int x1, int y2, int x2)
/*
* Hack -- help decide if a monster race is "okay" to summon
*/
-static bool_ mutate_monster_okay(int r_idx)
+static bool mutate_monster_okay(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
- bool_ okay = FALSE;
-
/* Hack - Only summon dungeon monsters */
- if (!monster_dungeon(r_idx)) return (FALSE);
+ if (!monster_dungeon(r_ptr)) return false;
- okay = ((r_ptr->d_char == summon_kin_type) && !(r_ptr->flags & RF_UNIQUE)
+ return ((r_ptr->d_char == summon_kin_type) && !(r_ptr->flags & RF_UNIQUE)
&& (r_ptr->level >= dun_level));
-
- return okay;
}
@@ -3523,17 +3449,17 @@ static bool_ mutate_monster_okay(int r_idx)
*
* Note that "reproduction" REQUIRES empty space.
*/
-bool_ multiply_monster(int m_idx, bool_ charm, bool_ clone)
+bool multiply_monster(int m_idx, bool charm, bool clone)
{
monster_type *m_ptr = &m_list[m_idx];
auto const r_ptr = m_ptr->race();
- bool_ result = FALSE;
+ bool result = false;
if (no_breeds)
{
msg_print("It tries to breed but it fails!");
- return FALSE;
+ return false;
}
/* Try up to 18 times */
@@ -3552,13 +3478,13 @@ bool_ multiply_monster(int m_idx, bool_ charm, bool_ clone)
/* It can mutate into a nastier monster */
if ((rand_int(100) < 3) && (!clone))
{
- bool_ (*old_get_mon_num_hook)(int r_idx);
+ bool (*old_get_monster_hook)(monster_race const *);
/* Backup the old hook */
- old_get_mon_num_hook = get_mon_num_hook;
+ old_get_monster_hook = get_monster_hook;
/* Require "okay" monsters */
- get_mon_num_hook = mutate_monster_okay;
+ get_monster_hook = mutate_monster_okay;
/* Prepare allocation table */
get_mon_num_prep();
@@ -3569,14 +3495,14 @@ bool_ multiply_monster(int m_idx, bool_ charm, bool_ clone)
new_race = get_mon_num(dun_level + 5);
/* Reset restriction */
- get_mon_num_hook = old_get_mon_num_hook;
+ get_monster_hook = old_get_monster_hook;
/* Prepare allocation table */
get_mon_num_prep();
}
/* Create a new monster (awake, no groups) */
- result = place_monster_aux(y, x, new_race, FALSE, FALSE, (charm) ? MSTATUS_PET : MSTATUS_ENEMY);
+ result = place_monster_aux(y, x, new_race, false, false, (charm) ? MSTATUS_PET : MSTATUS_ENEMY);
/* Done */
break;
@@ -3597,8 +3523,8 @@ bool_ multiply_monster(int m_idx, bool_ charm, bool_ clone)
*
* Technically should attempt to treat "Beholder"'s as jelly's
*/
-bool_ hack_message_pain_may_silent = FALSE;
-void message_pain_hook(cptr message, cptr name)
+bool hack_message_pain_may_silent = false;
+void message_pain_hook(const char *message, const char *name)
{
std::string buf;
buf += name;
diff --git a/src/monster2.hpp b/src/monster2.hpp
index ddd0b6bc..e1a9395b 100644
--- a/src/monster2.hpp
+++ b/src/monster2.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "monster_race_fwd.hpp"
#include "monster_type_fwd.hpp"
#include "object_type_fwd.hpp"
@@ -9,42 +9,42 @@
s32b monster_exp(s16b level);
void monster_set_level(int m_idx, int level);
s32b modify_aux(s32b a, s32b b, char mod);
-void monster_msg_simple(cptr s);
-bool_ mego_ok(monster_race const *r_ptr, int ego);
-void monster_check_experience(int m_idx, bool_ silent);
-void monster_gain_exp(int m_idx, u32b exp, bool_ silent);
+void monster_msg_simple(const char *s);
+bool mego_ok(monster_race const *r_ptr, int ego);
+void monster_check_experience(int m_idx, bool silent);
+void monster_gain_exp(int m_idx, u32b exp);
std::shared_ptr<monster_race> race_info_idx(int r_idx, int ego);
void delete_monster_idx(int i);
void delete_monster(int y, int x);
void compact_monsters(int size);
void wipe_m_list();
s16b m_pop();
-errr get_mon_num_prep();
+void get_mon_num_prep();
s16b get_mon_num(int level);
-void monster_desc(char *desc, monster_type *m_ptr, int mode);
+void monster_desc(char *desc, const monster_type *m_ptr, int mode);
void monster_race_desc(char *desc, int r_idx, int ego);
-void update_mon(int m_idx, bool_ full);
-void update_monsters(bool_ full);
+void update_mon(int m_idx, bool full);
+void update_monsters(bool full);
void monster_carry(monster_type *m_ptr, int m_idx, object_type *q_ptr);
-extern bool_ bypass_r_ptr_max_num ;
-bool_ place_monster_aux(int y, int x, int r_idx, bool_ slp, bool_ grp, int status);
-bool_ place_monster(int y, int x, bool_ slp, bool_ grp);
-bool_ alloc_horde(int y, int x);
-bool_ alloc_monster(int dis, bool_ slp);
+extern bool bypass_r_ptr_max_num ;
+bool place_monster_aux(int y, int x, int r_idx, bool slp, bool grp, int status);
+bool place_monster(int y, int x, bool slp, bool grp);
+bool alloc_horde(int y, int x);
+bool alloc_monster(int dis, bool slp);
extern int summon_specific_level;
-bool_ summon_specific(int y1, int x1, int lev, int type);
+bool summon_specific(int y1, int x1, int lev, int type);
void monster_swap(int y1, int x1, int y2, int x2);
-bool_ multiply_monster(int m_idx, bool_ charm, bool_ clone);
-extern bool_ hack_message_pain_may_silent;
+bool multiply_monster(int m_idx, bool charm, bool clone);
+extern bool hack_message_pain_may_silent;
void message_pain(int m_idx, int dam);
void update_smart_learn(int m_idx, int what);
-bool_ summon_specific_friendly(int y1, int x1, int lev, int type, bool_ Group_ok);
-extern bool_ place_monster_one_no_drop;
-s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status);
+bool summon_specific_friendly(int y1, int x1, int lev, int type, bool Group_ok);
+extern bool place_monster_one_no_drop;
+s16b place_monster_one(int y, int x, int r_idx, int ego, bool slp, int status);
s16b player_place(int y, int x);
void monster_drop_carried_objects(monster_type *m_ptr);
-bool_ monster_dungeon(int r_idx);
-bool_ monster_quest(int r_idx);
-void set_mon_num_hook();
-void set_mon_num2_hook(int y, int x);
-bool_ monster_can_cross_terrain(byte feat, std::shared_ptr<monster_race> r_ptr);
+bool monster_dungeon(monster_race const *r_ptr);
+bool monster_quest(monster_race const *r_ptr);
+void reset_get_monster_hook();
+void set_monster_aux_hook(int y, int x);
+bool monster_can_cross_terrain(byte feat, std::shared_ptr<monster_race> r_ptr);
diff --git a/src/monster3.cc b/src/monster3.cc
index 6dd1f74e..84cb1d64 100644
--- a/src/monster3.cc
+++ b/src/monster3.cc
@@ -24,17 +24,16 @@
#include "skills.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "xtra2.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
/*
* Is the mon,ster in friendly state(pet, friend, ..)
* -1 = enemy, 0 = neutral, 1 = friend
*/
-int is_friend(monster_type *m_ptr)
+int is_friend(monster_type const *m_ptr)
{
switch (m_ptr->status)
{
@@ -59,27 +58,40 @@ int is_friend(monster_type *m_ptr)
}
/* Should they attack each others */
-bool_ is_enemy(monster_type *m_ptr, monster_type *t_ptr)
+bool is_enemy(monster_type *m_ptr, monster_type *t_ptr)
{
auto const &r_info = game->edit_data.r_info;
auto r_ptr = &r_info[m_ptr->r_idx];
auto rt_ptr = &r_info[t_ptr->r_idx];
- int s1 = is_friend(m_ptr), s2 = is_friend(t_ptr);
-
/* Monsters hates breeders */
- if ((m_ptr->status != MSTATUS_NEUTRAL) && (rt_ptr->spells & SF_MULTIPLY) && (num_repro > MAX_REPRO * 2 / 3) && (r_ptr->d_char != rt_ptr->d_char)) return TRUE;
- if ((t_ptr->status != MSTATUS_NEUTRAL) && (r_ptr->spells & SF_MULTIPLY) && (num_repro > MAX_REPRO * 2 / 3) && (r_ptr->d_char != rt_ptr->d_char)) return TRUE;
+ if ((m_ptr->status != MSTATUS_NEUTRAL) &&
+ (rt_ptr->spells & SF_MULTIPLY) &&
+ (num_repro > MAX_REPRO * 2 / 3) &&
+ (r_ptr->d_char != rt_ptr->d_char)) {
+ return true;
+ }
+ if ((t_ptr->status != MSTATUS_NEUTRAL) &&
+ (r_ptr->spells & SF_MULTIPLY) &&
+ (num_repro > MAX_REPRO * 2 / 3) &&
+ (r_ptr->d_char != rt_ptr->d_char)) {
+ return true;
+ }
- /* No special conditions, lets test normal flags */
- if (s1 && s2 && (s1 == -s2)) return TRUE;
+ /* No special conditions, test normal flags */
+ int const s1 = is_friend(m_ptr);
+ int const s2 = is_friend(t_ptr);
+ if (s1 && s2 && (s1 == -s2))
+ {
+ return true;
+ }
- /* Not ennemy */
- return (FALSE);
+ /* Not enemy */
+ return false;
}
-bool_ change_side(monster_type *m_ptr)
+bool change_side(monster_type *m_ptr)
{
auto const r_ptr = m_ptr->race();
@@ -103,19 +115,18 @@ bool_ change_side(monster_type *m_ptr)
inc_piety(GOD_YAVANNA, -m_ptr->level * 4);
break;
case MSTATUS_COMPANION:
- return FALSE;
- break;
+ return false;
}
/* changed */
- return TRUE;
+ return true;
}
/* Multiply !! */
-bool_ ai_multiply(int m_idx)
+bool ai_multiply(int m_idx)
{
monster_type *m_ptr = &m_list[m_idx];
int k, y, x, oy = m_ptr->fy, ox = m_ptr->fx;
- bool_ is_frien = (is_friend(m_ptr) > 0);
+ bool is_frien = (is_friend(m_ptr) > 0);
/* Count the adjacent monsters */
for (k = 0, y = oy - 1; y <= oy + 1; y++)
@@ -128,28 +139,29 @@ bool_ ai_multiply(int m_idx)
if (is_friend(m_ptr) > 0)
{
- is_frien = TRUE;
+ is_frien = true;
}
else
{
- is_frien = FALSE;
+ is_frien = false;
}
/* Hack -- multiply slower in crowded areas */
if ((k < 4) && (!k || !rand_int(k * MON_MULT_ADJ)))
{
/* Try to multiply */
- if (multiply_monster(m_idx, (is_frien), FALSE))
+ if (multiply_monster(m_idx, (is_frien), false))
{
/* Multiplying takes energy */
- return TRUE;
+ return true;
}
}
- return FALSE;
+
+ return false;
}
/* Possessor incarnates */
-bool_ ai_possessor(int m_idx, int o_idx)
+void ai_possessor(int m_idx, int o_idx)
{
auto &r_info = game->edit_data.r_info;
@@ -163,7 +175,10 @@ bool_ ai_possessor(int m_idx, int o_idx)
monster_desc(m_name, m_ptr, 0x00);
monster_race_desc(m_name2, r2_idx, 0);
- if (m_ptr->ml) msg_format("%^s incarnates into a %s!", m_name, m_name2);
+ if (m_ptr->ml)
+ {
+ msg_format("%^s incarnates into a %s!", m_name, m_name2);
+ }
/* Remove the old one */
delete_object_idx(o_idx);
@@ -217,7 +232,7 @@ bool_ ai_possessor(int m_idx, int o_idx)
if (r_ptr->spells & SF_MULTIPLY) num_repro++;
/* Hack -- Notice new multi-hued monsters */
- if (r_ptr->flags & RF_ATTR_MULTI) shimmer_monsters = TRUE;
+ if (r_ptr->flags & RF_ATTR_MULTI) shimmer_monsters = true;
/* Hack -- Count the monsters on the level */
r_ptr->cur_num++;
@@ -226,9 +241,7 @@ bool_ ai_possessor(int m_idx, int o_idx)
m_ptr->possessor = r_idx;
/* Update the monster */
- update_mon(m_idx, TRUE);
-
- return TRUE;
+ update_mon(m_idx, true);
}
void ai_deincarnate(int m_idx)
@@ -294,7 +307,7 @@ void ai_deincarnate(int m_idx)
if (r_ptr->spells & SF_MULTIPLY) num_repro++;
/* Hack -- Notice new multi-hued monsters */
- if (r_ptr->flags & RF_ATTR_MULTI) shimmer_monsters = TRUE;
+ if (r_ptr->flags & RF_ATTR_MULTI) shimmer_monsters = true;
/* Hack -- Count the monsters on the level */
r_ptr->cur_num++;
@@ -303,32 +316,37 @@ void ai_deincarnate(int m_idx)
m_ptr->possessor = 0;
/* Update the monster */
- update_mon(m_idx, TRUE);
+ update_mon(m_idx, true);
}
/* Returns if a new companion is allowed */
-bool_ can_create_companion()
+bool can_create_companion()
{
- int i, mcnt = 0;
+ int mcnt = 0;
- for (i = m_max - 1; i >= 1; i--)
+ for (int i = m_max - 1; i >= 1; i--)
{
/* Access the monster */
monster_type *m_ptr = &m_list[i];
/* Ignore "dead" monsters */
- if (!m_ptr->r_idx) continue;
+ if (!m_ptr->r_idx)
+ {
+ continue;
+ }
- if (m_ptr->status == MSTATUS_COMPANION) mcnt++;
+ if (m_ptr->status == MSTATUS_COMPANION)
+ {
+ mcnt++;
+ }
}
- if (mcnt < (1 + get_skill_scale(SKILL_LORE, 6))) return (TRUE);
- else return (FALSE);
+ return mcnt < (1 + get_skill_scale(SKILL_LORE, 6));
}
/* Player controlled monsters */
-bool_ do_control_walk()
+bool do_control_walk()
{
/* Get a "repeated" direction */
if (p_ptr->control)
@@ -343,26 +361,37 @@ bool_ do_control_walk()
/* Actually move the monster */
p_ptr->control_dir = dir;
}
- return TRUE;
+
+ return true;
}
else
- return FALSE;
+ {
+ return false;
+ }
}
-bool_ do_control_inven()
+bool do_control_inven()
{
- if (!p_ptr->control) return FALSE;
+ if (!p_ptr->control)
+ {
+ return false;
+ }
+
screen_save();
prt("Carried items", 0, 0);
show_monster_inven(p_ptr->control);
inkey();
screen_load();
- return TRUE;
+
+ return true;
}
-bool_ do_control_pickup()
+bool do_control_pickup()
{
- if (!p_ptr->control) return FALSE;
+ if (!p_ptr->control)
+ {
+ return false;
+ }
monster_type *m_ptr = &m_list[p_ptr->control];
@@ -387,7 +416,7 @@ bool_ do_control_pickup()
excise_object_idx(this_o_idx);
/* Forget mark */
- o_ptr->marked = FALSE;
+ o_ptr->marked = false;
/* Forget location */
o_ptr->iy = o_ptr->ix = 0;
@@ -408,38 +437,41 @@ bool_ do_control_pickup()
msg_print("You pick up all objects on the floor.");
}
- return TRUE;
+ return true;
}
-bool_ do_control_drop()
+bool do_control_drop()
{
monster_type *m_ptr = &m_list[p_ptr->control];
- if (!p_ptr->control) return FALSE;
+ if (!p_ptr->control) return false;
monster_drop_carried_objects(m_ptr);
- return TRUE;
+ return true;
}
-bool_ do_control_magic()
+bool do_control_magic()
{
auto const &r_info = game->edit_data.r_info;
int i;
- bool_ flag, redraw;
+ bool flag, redraw;
int ask;
char choice;
char out_val[160];
auto r_ptr = &r_info[m_list[p_ptr->control].r_idx];
int label;
- if (!p_ptr->control) return FALSE;
+ if (!p_ptr->control)
+ {
+ return false;
+ }
if (get_check("Do you want to abandon the creature?"))
{
if (get_check("Abandon it permanently?"))
delete_monster_idx(p_ptr->control);
p_ptr->control = 0;
- return TRUE;
+ return true;
}
/* Extract available monster powers */
@@ -450,15 +482,15 @@ bool_ do_control_magic()
if (!num)
{
msg_print("You have no powers you can use.");
- return (TRUE);
+ return true;
}
/* Nothing chosen yet */
- flag = FALSE;
+ flag = false;
monster_power const *power = nullptr;
/* No redraw yet */
- redraw = FALSE;
+ redraw = false;
/* Get the last label */
label = (num <= 26) ? I2A(num - 1) : I2D(num - 1 - 26);
@@ -484,11 +516,10 @@ bool_ do_control_magic()
strcpy(dummy, "");
/* Show list */
- redraw = TRUE;
+ redraw = true;
/* Save the screen */
- character_icky = TRUE;
- Term_save();
+ screen_save_no_flush();
prt ("", y++, x);
@@ -527,11 +558,10 @@ bool_ do_control_magic()
else
{
/* Hide list */
- redraw = FALSE;
+ redraw = false;
/* Restore the screen */
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
}
/* Redo asking */
@@ -557,7 +587,7 @@ bool_ do_control_magic()
else
{
/* Can't uppercase digits XXX XXX XXX */
- ask = FALSE;
+ ask = false;
i = choice - '0' + 26;
}
@@ -585,14 +615,13 @@ bool_ do_control_magic()
}
/* Stop the loop */
- flag = TRUE;
+ flag = true;
}
/* Restore the screen */
if (redraw)
{
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
}
/* Take a turn */
@@ -601,11 +630,12 @@ bool_ do_control_magic()
energy_use = 100;
monst_spell_monst_spell = power->monster_spell_index;
}
- return TRUE;
+
+ return true;
}
/* Finds the controlled monster and "reconnect" to it */
-bool_ do_control_reconnect()
+bool do_control_reconnect()
{
int i;
@@ -620,10 +650,10 @@ bool_ do_control_reconnect()
if (m_ptr->mflag & MFLAG_CONTROL)
{
p_ptr->control = i;
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
/*
diff --git a/src/monster3.hpp b/src/monster3.hpp
index ac26b102..23f707ee 100644
--- a/src/monster3.hpp
+++ b/src/monster3.hpp
@@ -1,20 +1,22 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "monster_type_fwd.hpp"
+#include <cstdio>
+
void dump_companions(FILE *outfile);
void do_cmd_companion();
-bool_ do_control_reconnect();
-bool_ do_control_drop();
-bool_ do_control_magic();
-bool_ do_control_pickup();
-bool_ do_control_inven();
-bool_ do_control_walk();
-bool_ can_create_companion();
+bool do_control_reconnect();
+bool do_control_drop();
+bool do_control_magic();
+bool do_control_pickup();
+bool do_control_inven();
+bool do_control_walk();
+bool can_create_companion();
void ai_deincarnate(int m_idx);
-bool_ ai_possessor(int m_idx, int o_idx);
-bool_ ai_multiply(int m_idx);
-bool_ change_side(monster_type *m_ptr);
-int is_friend(monster_type *m_ptr);
-bool_ is_enemy(monster_type *m_ptr, monster_type *t_ptr);
+void ai_possessor(int m_idx, int o_idx);
+bool ai_multiply(int m_idx);
+bool change_side(monster_type *m_ptr);
+int is_friend(const monster_type *m_ptr);
+bool is_enemy(monster_type *m_ptr, monster_type *t_ptr);
diff --git a/src/monster_blow.hpp b/src/monster_blow.hpp
index 6e0ee6e5..085c7224 100644
--- a/src/monster_blow.hpp
+++ b/src/monster_blow.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* Monster blow descriptor.
diff --git a/src/monster_ego.hpp b/src/monster_ego.hpp
index b578d03e..7ce9d439 100644
--- a/src/monster_ego.hpp
+++ b/src/monster_ego.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "monster_blow.hpp"
#include "monster_race_flag_set.hpp"
#include "monster_spell_flag_set.hpp"
@@ -13,7 +13,7 @@
struct monster_ego
{
const char *name = nullptr; /* Name */
- bool_ before = false; /* Display ego before or after */
+ bool before = false; /* Display ego before or after */
std::array<monster_blow, 4> blow { }; /* Up to four blows per round */
byte blowm[4][2] = {
diff --git a/src/monster_power.hpp b/src/monster_power.hpp
index 440d5ba1..393fec1a 100644
--- a/src/monster_power.hpp
+++ b/src/monster_power.hpp
@@ -2,15 +2,15 @@
#include "monster_power_fwd.hpp"
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* Monster powers that players can use via e.g. Symbiosis.
*/
struct monster_power
{
- u32b monster_spell_index;
- cptr name; /* Name of it */
- int mana; /* Mana needed */
- bool_ great; /* Need the use of great spells */
+ u32b monster_spell_index;
+ const char *name; /* Name of it */
+ int mana; /* Mana needed */
+ bool great; /* Need the use of great spells */
};
diff --git a/src/monster_race.hpp b/src/monster_race.hpp
index eb398a3d..b7d54fac 100644
--- a/src/monster_race.hpp
+++ b/src/monster_race.hpp
@@ -1,7 +1,7 @@
#pragma once
#include "body.hpp"
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "monster_blow.hpp"
#include "monster_race_flag_set.hpp"
#include "monster_spell_flag_set.hpp"
@@ -75,7 +75,7 @@ struct monster_race
s16b r_pkills = 0; /* Count monsters killed in this life */
- bool_ on_saved = 0; /* Is the (unique) on a saved level ? */
+ bool on_saved = 0; /* Is the (unique) on a saved level ? */
obj_theme drops; /* The drops type */
diff --git a/src/monster_type.hpp b/src/monster_type.hpp
index ed6d3d2a..bc7b4e79 100644
--- a/src/monster_type.hpp
+++ b/src/monster_type.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "monster_blow.hpp"
#include "monster_race_fwd.hpp"
@@ -52,7 +52,7 @@ struct monster_type
s32b mflag = 0; /* Extra monster flags */
- bool_ ml = FALSE; /* Monster is "visible" */
+ bool ml = false; /* Monster is "visible" */
std::vector<s16b> hold_o_idxs { }; /* Objects being held */
diff --git a/src/move_info_type.hpp b/src/move_info_type.hpp
index 5f8aa3d8..fac24f70 100644
--- a/src/move_info_type.hpp
+++ b/src/move_info_type.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* Movement typse
@@ -11,5 +11,5 @@ struct move_info_type
s16b to_search;
s16b to_stealth;
s16b to_percep;
- cptr name;
+ const char *name;
};
diff --git a/src/music.hpp b/src/music.hpp
index 5f37c570..125d5e60 100644
--- a/src/music.hpp
+++ b/src/music.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* Music descriptor.
diff --git a/src/notes.cc b/src/notes.cc
index 17990992..50e0844d 100644
--- a/src/notes.cc
+++ b/src/notes.cc
@@ -14,34 +14,35 @@
#include "player_class.hpp"
#include "player_type.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
+#include <boost/filesystem/path.hpp>
+#include <fmt/format.h>
+
+namespace fs = boost::filesystem;
+
+/**
+ * Get note path name
+ */
+static fs::path note_path()
+{
+ char buf[1024];
+ path_build(buf, sizeof(buf), ANGBAND_DIR_NOTE, name_file_note(game->player_base).c_str());
+ return fs::path(buf);
+}
+
/*
* Show the notes file on the screen
*/
void show_notes_file()
{
- char basename[13];
- char buf[1024];
- char caption[10 + 13];
-
- /* Hack -- extract first 8 characters of name and append an extension */
- strnfmt(basename, sizeof(basename), "%.8s.nte", game->player_base.c_str());
- basename[sizeof(basename) - 1] = '\0';
-
- /* Build the path */
- path_build(buf, sizeof(buf), ANGBAND_DIR_NOTE, basename);
+ auto p = note_path();
/* Use a caption, forcing direct access to the note file */
- sprintf(caption, "Note file %s", basename);
+ auto caption = fmt::format("Note file {}", p.filename().c_str());
/* Invoke show_file */
- show_file(buf, caption);
-
- /* Done */
- return;
+ show_file(p.c_str(), caption.c_str());
}
/*
@@ -50,19 +51,8 @@ void show_notes_file()
*/
void output_note(const char *final_note)
{
- FILE *fff;
- char basename[13];
- char buf[1024];
-
- /* Hack -- extract first 8 characters of name and append an extension */
- strnfmt(basename, sizeof(basename), "%.8s.nte", game->player_base.c_str());
- basename[sizeof(basename) - 1] = '\0';
-
- /* Build the path */
- path_build(buf, sizeof(buf), ANGBAND_DIR_NOTE, basename);
-
/* Open notes file */
- fff = my_fopen(buf, "a");
+ FILE *fff = my_fopen(note_path().c_str(), "a");
/* Failure */
if (!fff) return;
@@ -72,9 +62,6 @@ void output_note(const char *final_note)
/* Close the handle */
my_fclose(fff);
-
- /* Done */
- return;
}
diff --git a/src/obj_theme.hpp b/src/obj_theme.hpp
index d10d17fa..c3a3d312 100644
--- a/src/obj_theme.hpp
+++ b/src/obj_theme.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* Object theme. Probability in percent for each class of
diff --git a/src/object1.cc b/src/object1.cc
index 3fb2ef26..157637a9 100644
--- a/src/object1.cc
+++ b/src/object1.cc
@@ -13,7 +13,6 @@
#include "cave_type.hpp"
#include "cmd2.hpp"
#include "cmd6.hpp"
-#include "dungeon.hpp"
#include "dungeon_info_type.hpp"
#include "ego_item_type.hpp"
#include "feature_type.hpp"
@@ -48,11 +47,10 @@
#include "store_info_type.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "wilderness_type_info.hpp"
#include "xtra1.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
#include <boost/algorithm/string/join.hpp>
@@ -81,301 +79,149 @@ static void apply_flags_set(s16b a_idx, s16b set_idx, object_flag_set *f);
*/
static bool item_tester_full;
-
/*
- * Max sizes of the following arrays
+ * Color arrays
*/
-#define MAX_ROCKS 62 /* Used with rings (min 58) */
-#define MAX_AMULETS 34 /* Used with amulets (min 30) */
-#define MAX_WOODS 35 /* Used with staffs (min 32) */
-#define MAX_METALS 39 /* Used with wands/rods (min 32/30) */
-#define MAX_COLORS 66 /* Used with potions (min 62) */
-#define MAX_SHROOM 20 /* Used with mushrooms (min 20) */
-#define MAX_TITLES 55 /* Used with scrolls (min 55) */
-#define MAX_SYLLABLES 164 /* Used with scrolls (see below) */
+namespace { // anonymous
+
+struct object_colors_t {
+
+ std::vector<byte> rings {
+ TERM_GREEN, TERM_VIOLET, TERM_L_BLUE, TERM_L_BLUE, TERM_L_GREEN,
+ TERM_RED, TERM_WHITE, TERM_RED, TERM_SLATE, TERM_WHITE,
+ TERM_GREEN, TERM_L_GREEN, TERM_RED, TERM_L_DARK, TERM_L_GREEN,
+ TERM_UMBER, TERM_BLUE, TERM_GREEN, TERM_WHITE, TERM_L_WHITE,
+ TERM_L_RED, TERM_L_WHITE, TERM_WHITE, TERM_L_WHITE, TERM_L_WHITE,
+ TERM_L_RED, TERM_RED, TERM_BLUE, TERM_YELLOW, TERM_YELLOW,
+ TERM_L_BLUE, TERM_L_UMBER, TERM_WHITE, TERM_L_UMBER, TERM_YELLOW,
+ TERM_L_DARK, TERM_L_WHITE, TERM_GREEN, TERM_L_BLUE, TERM_L_DARK,
+ TERM_YELLOW, TERM_VIOLET,
+ TERM_UMBER, TERM_L_WHITE, TERM_WHITE, TERM_UMBER,
+ TERM_BLUE, TERM_GREEN, TERM_YELLOW, TERM_ORANGE,
+ TERM_YELLOW, TERM_ORANGE, TERM_L_GREEN, TERM_YELLOW,
+ TERM_RED, TERM_WHITE, TERM_UMBER, TERM_L_DARK, TERM_L_WHITE,
+ TERM_WHITE, TERM_BLUE, TERM_L_WHITE
+ };
+
+ std::vector<byte> amulets {
+ TERM_YELLOW, TERM_L_UMBER, TERM_WHITE, TERM_L_WHITE, TERM_WHITE,
+ TERM_L_DARK, TERM_WHITE, TERM_ORANGE, TERM_L_UMBER, TERM_SLATE,
+ TERM_GREEN, TERM_YELLOW, TERM_L_BLUE, TERM_L_BLUE, TERM_L_WHITE,
+ TERM_L_UMBER, TERM_VIOLET, TERM_L_BLUE, TERM_BLUE, TERM_L_WHITE,
+ TERM_UMBER, TERM_L_BLUE, TERM_SLATE, TERM_RED, TERM_L_GREEN,
+ TERM_WHITE, TERM_L_DARK, TERM_L_WHITE, TERM_WHITE, TERM_L_GREEN,
+ TERM_GREEN, TERM_VIOLET, TERM_L_WHITE, TERM_UMBER
+ };
+
+ std::vector<byte> staves {
+ TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER,
+ TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER,
+ TERM_L_UMBER, TERM_L_UMBER, TERM_UMBER, TERM_L_UMBER, TERM_UMBER,
+ TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_RED,
+ TERM_RED, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_UMBER,
+ TERM_GREEN, TERM_L_UMBER, TERM_L_UMBER, TERM_L_WHITE, TERM_UMBER,
+ TERM_YELLOW, TERM_SLATE, TERM_UMBER, TERM_L_WHITE, TERM_L_UMBER
+ };
+
+ std::vector<byte> wands {
+ TERM_L_BLUE, TERM_L_DARK, TERM_WHITE, TERM_UMBER, TERM_YELLOW,
+ TERM_SLATE, TERM_L_WHITE, TERM_L_WHITE, TERM_L_WHITE, TERM_RED,
+ TERM_L_WHITE, TERM_L_WHITE, TERM_L_WHITE, TERM_WHITE, TERM_WHITE,
+ TERM_L_WHITE, TERM_L_WHITE, TERM_L_BLUE, TERM_L_UMBER, TERM_YELLOW,
+ TERM_L_UMBER, TERM_L_WHITE, TERM_L_WHITE, TERM_L_WHITE, TERM_L_WHITE,
+ TERM_L_BLUE, TERM_L_BLUE, TERM_UMBER, TERM_L_UMBER, TERM_L_UMBER,
+ TERM_WHITE, TERM_SLATE, TERM_SLATE, TERM_WHITE, TERM_VIOLET,
+ TERM_L_RED, TERM_L_BLUE, TERM_BLUE, TERM_RED
+ };
+
+ std::vector<byte> rods = wands;
+
+ std::vector<byte> food {
+ TERM_BLUE, TERM_L_DARK, TERM_L_DARK, TERM_UMBER, TERM_BLUE,
+ TERM_GREEN, TERM_RED, TERM_YELLOW, TERM_L_WHITE, TERM_GREEN,
+ TERM_SLATE, TERM_L_BLUE, TERM_L_GREEN, TERM_VIOLET, TERM_RED,
+ TERM_SLATE, TERM_L_UMBER, TERM_WHITE, TERM_WHITE, TERM_UMBER
+ };
+
+ std::vector<byte> potions {
+ TERM_WHITE, TERM_L_UMBER, TERM_GREEN, TERM_MULTI,
+ TERM_L_BLUE, TERM_BLUE, TERM_BLUE, TERM_L_DARK, TERM_UMBER, TERM_UMBER,
+ TERM_L_WHITE, TERM_L_GREEN, TERM_WHITE, TERM_L_UMBER, TERM_RED, TERM_L_BLUE,
+ TERM_BLUE, TERM_GREEN, TERM_RED, TERM_YELLOW, TERM_GREEN,
+ TERM_GREEN, TERM_SLATE, TERM_SLATE, TERM_L_WHITE, TERM_VIOLET,
+ TERM_L_BLUE, TERM_L_GREEN, TERM_RED, TERM_BLUE, TERM_RED,
+ TERM_GREEN, TERM_VIOLET, TERM_L_WHITE, TERM_ORANGE, TERM_ORANGE,
+ TERM_L_RED, TERM_L_RED, TERM_VIOLET, TERM_VIOLET, TERM_VIOLET,
+ TERM_RED, TERM_RED, TERM_L_WHITE, TERM_L_DARK, TERM_ORANGE,
+ TERM_VIOLET, TERM_RED, TERM_WHITE, TERM_YELLOW, TERM_VIOLET,
+ TERM_L_RED, TERM_RED, TERM_L_RED, TERM_YELLOW, TERM_GREEN,
+ TERM_MULTI, TERM_RED, TERM_YELLOW, TERM_YELLOW,
+ TERM_L_UMBER, TERM_UMBER, TERM_L_DARK, TERM_RED, TERM_WHITE, TERM_L_BLUE
+ };
+
+ std::vector<byte> scrolls =
+ std::vector<byte>(55, TERM_WHITE); // All scrolls are white.
-/*
- * Rings (adjectives and colors)
- */
-
-static cptr ring_adj[MAX_ROCKS] =
-{
- "Alexandrite", "Amethyst", "Aquamarine", "Azurite", "Beryl",
- "Bloodstone", "Calcite", "Carnelian", "Corundum", "Diamond",
- "Emerald", "Fluorite", "Garnet", "Granite", "Jade",
- "Jasper", "Lapis Lazuli", "Malachite", "Marble", "Moonstone",
- "Onyx", "Opal", "Pearl", "Quartz", "Quartzite",
- "Rhodonite", "Ruby", "Sapphire", "Tiger Eye", "Topaz",
- "Turquoise", "Zircon", "Platinum", "Bronze", "Gold",
- "Obsidian", "Silver", "Tortoise Shell", "Mithril", "Jet",
- "Engagement", "Adamantite",
- "Wire", "Dilithium", "Bone", "Wooden",
- "Spikard", "Serpent", "Wedding", "Double",
- "Plain", "Brass", "Scarab", "Shining",
- "Rusty", "Transparent", "Copper", "Black Opal", "Nickel",
- "Glass", "Fluorspar", "Agate",
};
-static byte ring_col[MAX_ROCKS] =
-{
- TERM_GREEN, TERM_VIOLET, TERM_L_BLUE, TERM_L_BLUE, TERM_L_GREEN,
- TERM_RED, TERM_WHITE, TERM_RED, TERM_SLATE, TERM_WHITE,
- TERM_GREEN, TERM_L_GREEN, TERM_RED, TERM_L_DARK, TERM_L_GREEN,
- TERM_UMBER, TERM_BLUE, TERM_GREEN, TERM_WHITE, TERM_L_WHITE,
- TERM_L_RED, TERM_L_WHITE, TERM_WHITE, TERM_L_WHITE, TERM_L_WHITE,
- TERM_L_RED, TERM_RED, TERM_BLUE, TERM_YELLOW, TERM_YELLOW,
- TERM_L_BLUE, TERM_L_UMBER, TERM_WHITE, TERM_L_UMBER, TERM_YELLOW,
- TERM_L_DARK, TERM_L_WHITE, TERM_GREEN, TERM_L_BLUE, TERM_L_DARK,
- TERM_YELLOW, TERM_VIOLET,
- TERM_UMBER, TERM_L_WHITE, TERM_WHITE, TERM_UMBER,
- TERM_BLUE, TERM_GREEN, TERM_YELLOW, TERM_ORANGE,
- TERM_YELLOW, TERM_ORANGE, TERM_L_GREEN, TERM_YELLOW,
- TERM_RED, TERM_WHITE, TERM_UMBER, TERM_L_DARK, TERM_L_WHITE,
- TERM_WHITE, TERM_BLUE, TERM_L_WHITE
-};
-
-
-/*
- * Amulets (adjectives and colors)
- */
-
-static cptr amulet_adj[MAX_AMULETS] =
-{
- "Amber", "Driftwood", "Coral", "Agate", "Ivory",
- "Obsidian", "Bone", "Brass", "Bronze", "Pewter",
- "Tortoise Shell", "Golden", "Azure", "Crystal", "Silver",
- "Copper", "Amethyst", "Mithril", "Sapphire", "Dragon Tooth",
- "Carved Oak", "Sea Shell", "Flint Stone", "Ruby", "Scarab",
- "Origami Paper", "Meteoric Iron", "Platinum", "Glass", "Beryl",
- "Malachite", "Adamantite", "Mother-of-pearl", "Runed"
-};
-
-static byte amulet_col[MAX_AMULETS] =
-{
- TERM_YELLOW, TERM_L_UMBER, TERM_WHITE, TERM_L_WHITE, TERM_WHITE,
- TERM_L_DARK, TERM_WHITE, TERM_ORANGE, TERM_L_UMBER, TERM_SLATE,
- TERM_GREEN, TERM_YELLOW, TERM_L_BLUE, TERM_L_BLUE, TERM_L_WHITE,
- TERM_L_UMBER, TERM_VIOLET, TERM_L_BLUE, TERM_BLUE, TERM_L_WHITE,
- TERM_UMBER, TERM_L_BLUE, TERM_SLATE, TERM_RED, TERM_L_GREEN,
- TERM_WHITE, TERM_L_DARK, TERM_L_WHITE, TERM_WHITE, TERM_L_GREEN,
- TERM_GREEN, TERM_VIOLET, TERM_L_WHITE, TERM_UMBER
-};
-
-
-/*
- * Staffs (adjectives and colors)
- */
-
-static cptr staff_adj[MAX_WOODS] =
-{
- "Aspen", "Balsa", "Banyan", "Birch", "Cedar",
- "Cottonwood", "Cypress", "Dogwood", "Elm", "Eucalyptus",
- "Hemlock", "Hickory", "Ironwood", "Locust", "Mahogany",
- "Maple", "Mulberry", "Oak", "Pine", "Redwood",
- "Rosewood", "Spruce", "Sycamore", "Teak", "Walnut",
- "Mistletoe", "Hawthorn", "Bamboo", "Silver", "Runed",
- "Golden", "Ashen", "Gnarled", "Ivory", "Willow"
-};
-
-static byte staff_col[MAX_WOODS] =
-{
- TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER,
- TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER,
- TERM_L_UMBER, TERM_L_UMBER, TERM_UMBER, TERM_L_UMBER, TERM_UMBER,
- TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_RED,
- TERM_RED, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_UMBER,
- TERM_GREEN, TERM_L_UMBER, TERM_L_UMBER, TERM_L_WHITE, TERM_UMBER,
- TERM_YELLOW, TERM_SLATE, TERM_UMBER, TERM_L_WHITE, TERM_L_UMBER
-};
-
-
-/*
- * Wands (adjectives and colors)
- */
-
-static cptr wand_adj[MAX_METALS] =
-{
- "Aluminium", "Cast Iron", "Chromium", "Copper", "Gold",
- "Iron", "Magnesium", "Molybdenum", "Nickel", "Rusty",
- "Silver", "Steel", "Tin", "Titanium", "Tungsten",
- "Zirconium", "Zinc", "Aluminium-Plated", "Copper-Plated", "Gold-Plated",
- "Nickel-Plated", "Silver-Plated", "Steel-Plated", "Tin-Plated", "Zinc-Plated",
- "Mithril-Plated", "Mithril", "Runed", "Bronze", "Brass",
- "Platinum", "Lead", "Lead-Plated", "Ivory" , "Adamantite",
- "Uridium", "Long", "Short", "Hexagonal"
-};
-
-static byte wand_col[MAX_METALS] =
-{
- TERM_L_BLUE, TERM_L_DARK, TERM_WHITE, TERM_UMBER, TERM_YELLOW,
- TERM_SLATE, TERM_L_WHITE, TERM_L_WHITE, TERM_L_WHITE, TERM_RED,
- TERM_L_WHITE, TERM_L_WHITE, TERM_L_WHITE, TERM_WHITE, TERM_WHITE,
- TERM_L_WHITE, TERM_L_WHITE, TERM_L_BLUE, TERM_L_UMBER, TERM_YELLOW,
- TERM_L_UMBER, TERM_L_WHITE, TERM_L_WHITE, TERM_L_WHITE, TERM_L_WHITE,
- TERM_L_BLUE, TERM_L_BLUE, TERM_UMBER, TERM_L_UMBER, TERM_L_UMBER,
- TERM_WHITE, TERM_SLATE, TERM_SLATE, TERM_WHITE, TERM_VIOLET,
- TERM_L_RED, TERM_L_BLUE, TERM_BLUE, TERM_RED
-};
-
-
-/*
- * Rods (adjectives and colors).
- * Efficiency -- copied from wand arrays
- */
-
-static cptr rod_adj[MAX_METALS];
-
-static byte rod_col[MAX_METALS];
-
-
-/*
- * Mushrooms (adjectives and colors)
- */
-
-static cptr food_adj[MAX_SHROOM] =
-{
- "Blue", "Black", "Black Spotted", "Brown", "Dark Blue",
- "Dark Green", "Dark Red", "Yellow", "Furry", "Green",
- "Grey", "Light Blue", "Light Green", "Violet", "Red",
- "Slimy", "Tan", "White", "White Spotted", "Wrinkled",
-};
-
-static byte food_col[MAX_SHROOM] =
-{
- TERM_BLUE, TERM_L_DARK, TERM_L_DARK, TERM_UMBER, TERM_BLUE,
- TERM_GREEN, TERM_RED, TERM_YELLOW, TERM_L_WHITE, TERM_GREEN,
- TERM_SLATE, TERM_L_BLUE, TERM_L_GREEN, TERM_VIOLET, TERM_RED,
- TERM_SLATE, TERM_L_UMBER, TERM_WHITE, TERM_WHITE, TERM_UMBER
-};
-
-
-/*
- * Color adjectives and colors, for potions.
- * Hack -- The first four entries are hard-coded.
- * (water, apple juice, slime mold juice, something)
- */
-
-static cptr potion_adj[MAX_COLORS] =
-{
- "Clear", "Light Brown", "Icky Green", "Strangely Phosphorescent",
- "Azure", "Blue", "Blue Speckled", "Black", "Brown", "Brown Speckled",
- "Bubbling", "Chartreuse", "Cloudy", "Copper Speckled", "Crimson", "Cyan",
- "Dark Blue", "Dark Green", "Dark Red", "Gold Speckled", "Green",
- "Green Speckled", "Grey", "Grey Speckled", "Hazy", "Indigo",
- "Light Blue", "Light Green", "Magenta", "Metallic Blue", "Metallic Red",
- "Metallic Green", "Metallic Purple", "Misty", "Orange", "Orange Speckled",
- "Pink", "Pink Speckled", "Puce", "Purple", "Purple Speckled",
- "Red", "Red Speckled", "Silver Speckled", "Smoky", "Tangerine",
- "Violet", "Vermilion", "White", "Yellow", "Violet Speckled",
- "Pungent", "Clotted Red", "Viscous Pink", "Oily Yellow", "Gloopy Green",
- "Shimmering", "Coagulated Crimson", "Yellow Speckled", "Gold",
- "Manly", "Stinking", "Oily Black", "Ichor", "Ivory White", "Sky Blue",
-};
-
-static byte potion_col[MAX_COLORS] =
-{
- TERM_WHITE, TERM_L_UMBER, TERM_GREEN, TERM_MULTI,
- TERM_L_BLUE, TERM_BLUE, TERM_BLUE, TERM_L_DARK, TERM_UMBER, TERM_UMBER,
- TERM_L_WHITE, TERM_L_GREEN, TERM_WHITE, TERM_L_UMBER, TERM_RED, TERM_L_BLUE,
- TERM_BLUE, TERM_GREEN, TERM_RED, TERM_YELLOW, TERM_GREEN,
- TERM_GREEN, TERM_SLATE, TERM_SLATE, TERM_L_WHITE, TERM_VIOLET,
- TERM_L_BLUE, TERM_L_GREEN, TERM_RED, TERM_BLUE, TERM_RED,
- TERM_GREEN, TERM_VIOLET, TERM_L_WHITE, TERM_ORANGE, TERM_ORANGE,
- TERM_L_RED, TERM_L_RED, TERM_VIOLET, TERM_VIOLET, TERM_VIOLET,
- TERM_RED, TERM_RED, TERM_L_WHITE, TERM_L_DARK, TERM_ORANGE,
- TERM_VIOLET, TERM_RED, TERM_WHITE, TERM_YELLOW, TERM_VIOLET,
- TERM_L_RED, TERM_RED, TERM_L_RED, TERM_YELLOW, TERM_GREEN,
- TERM_MULTI, TERM_RED, TERM_YELLOW, TERM_YELLOW,
- TERM_L_UMBER, TERM_UMBER, TERM_L_DARK, TERM_RED, TERM_WHITE, TERM_L_BLUE
-};
-
-
-/*
- * Syllables for scrolls (must be 1-4 letters each)
- */
-
-static cptr syllables[MAX_SYLLABLES] =
+object_colors_t const &object_colors_0()
{
- "a", "ab", "ag", "aks", "ala", "an", "ankh", "app",
- "arg", "arze", "ash", "aus", "ban", "bar", "bat", "bek",
- "bie", "bin", "bit", "bjor", "blu", "bot", "bu",
- "byt", "comp", "con", "cos", "cre", "dalf", "dan",
- "den", "der", "doe", "dok", "eep", "el", "eng", "er", "ere", "erk",
- "esh", "evs", "fa", "fid", "flit", "for", "fri", "fu", "gan",
- "gar", "glen", "gop", "gre", "ha", "he", "hyd", "i",
- "ing", "ion", "ip", "ish", "it", "ite", "iv", "jo",
- "kho", "kli", "klis", "la", "lech", "man", "mar",
- "me", "mi", "mic", "mik", "mon", "mung", "mur", "nag", "nej",
- "nelg", "nep", "ner", "nes", "nis", "nih", "nin", "o",
- "od", "ood", "org", "orn", "ox", "oxy", "pay", "pet",
- "ple", "plu", "po", "pot", "prok", "re", "rea", "rhov",
- "ri", "ro", "rog", "rok", "rol", "sa", "san", "sat",
- "see", "sef", "seh", "shu", "ski", "sna", "sne", "snik",
- "sno", "so", "sol", "sri", "sta", "sun", "ta", "tab",
- "tem", "ther", "ti", "tox", "trol", "tue", "turs", "u",
- "ulk", "um", "un", "uni", "ur", "val", "viv", "vly",
- "vom", "wah", "wed", "werg", "wex", "whon", "wun", "x",
- "yerg", "yp", "zun", "tri", "blaa", "jah", "bul", "on",
- "foo", "ju", "xuxu"
-};
-
-/*
- * Hold the titles of scrolls, 6 to 14 characters each
- * Also keep an array of scroll colors (always WHITE for now)
- */
-
-static char scroll_adj[MAX_TITLES][16];
+ object_colors_t const *instance = new object_colors_t();
+ return *instance;
+}
-static byte scroll_col[MAX_TITLES];
+} // namespace anonymous
-static byte object_flavor(object_kind const *k_ptr)
+static byte object_flavor(
+ object_colors_t const &object_colors,
+ std::shared_ptr<object_kind> k_ptr)
{
/* Analyze the item */
switch (k_ptr->tval)
{
case TV_AMULET:
{
- return (0x80 + amulet_col[k_ptr->sval]);
+ return 0x80 + object_colors.amulets.at(k_ptr->sval);
}
case TV_RING:
{
- return (0x90 + ring_col[k_ptr->sval]);
+ return 0x90 + object_colors.rings.at(k_ptr->sval);
}
case TV_STAFF:
{
- return (0xA0 + staff_col[k_ptr->sval]);
+ return 0xA0 + object_colors.staves.at(k_ptr->sval);
}
case TV_WAND:
{
- return (0xB0 + wand_col[k_ptr->sval]);
+ return 0xB0 + object_colors.wands.at(k_ptr->sval);
}
case TV_ROD:
{
- return (0xC0 + rod_col[k_ptr->sval]);
+ return 0xC0 + object_colors.rods.at(k_ptr->sval);
}
case TV_SCROLL:
{
- return (0xD0 + scroll_col[k_ptr->sval]);
+ return 0xD0 + object_colors.scrolls.at(k_ptr->sval);
}
case TV_POTION:
case TV_POTION2:
{
- return (0xE0 + potion_col[k_ptr->sval]);
+ return 0xE0 + object_colors.potions.at(k_ptr->sval);
}
case TV_FOOD:
{
if (k_ptr->sval < SV_FOOD_MIN_FOOD)
{
- return (0xF0 + food_col[k_ptr->sval]);
+ return 0xF0 + object_colors.food.at(k_ptr->sval);
}
break;
@@ -393,7 +239,7 @@ static byte object_flavor(object_kind const *k_ptr)
*
* XXX XXX XXX Add "EASY_KNOW" flag to "k_info.txt" file
*/
-static bool_ object_easy_know(object_kind const *k_ptr)
+static bool object_easy_know(std::shared_ptr<object_kind> k_ptr)
{
/* Analyze the "tval" */
switch (k_ptr->tval)
@@ -403,7 +249,7 @@ static bool_ object_easy_know(object_kind const *k_ptr)
case TV_MUSIC_BOOK:
case TV_SYMBIOTIC_BOOK:
{
- return (TRUE);
+ return true;
}
/* Simple items */
@@ -416,7 +262,7 @@ static bool_ object_easy_know(object_kind const *k_ptr)
case TV_SPIKE:
case TV_JUNK:
{
- return (TRUE);
+ return true;
}
/* All Food, Potions, Scrolls, Rods */
@@ -428,8 +274,8 @@ static bool_ object_easy_know(object_kind const *k_ptr)
case TV_ROD_MAIN:
{
if (k_ptr->flags & TR_NORM_ART)
- return ( FALSE );
- return (TRUE);
+ return ( false );
+ return true;
}
/* Some Rings, Amulets, Lites */
@@ -437,34 +283,16 @@ static bool_ object_easy_know(object_kind const *k_ptr)
case TV_AMULET:
case TV_LITE:
{
- if (k_ptr->flags & TR_EASY_KNOW) return (TRUE);
- return (FALSE);
+ if (k_ptr->flags & TR_EASY_KNOW) return true;
+ return false;
}
}
/* Nope */
- return (FALSE);
+ return false;
}
-
-/**
- * Shuffle flavor arrays into a random permutation
- */
-template <std::size_t N>
-static void shuffle_flavors(cptr adj[], byte col[])
-{
- // The classic Fisher-Yates shuffle
- for (std::size_t i = N - 1; i > 0; i--)
- {
- int j = rand_int(i + 1);
- std::swap(adj[i], adj[j]);
- std::swap(col[i], col[j]);
- }
-}
-
-
-
/*
* Prepare the "variable" part of the "k_info" array.
*
@@ -503,109 +331,34 @@ void flavor_init()
/* Hack -- Induce consistant flavors */
set_quick_rng(seed_flavor());
- /* Efficiency -- Rods/Wands share initial array */
- for (std::size_t i = 0; i < MAX_METALS; i++)
- {
- rod_adj[i] = wand_adj[i];
- rod_col[i] = wand_col[i];
- }
-
+ /* Get a copy of the initial colors */
+ auto object_colors = object_colors_0();
/* Object flavors */
- shuffle_flavors<MAX_ROCKS>(ring_adj, ring_col);
- shuffle_flavors<MAX_AMULETS>(amulet_adj, amulet_col);
- shuffle_flavors<MAX_WOODS>(staff_adj, staff_col);
- shuffle_flavors<MAX_METALS>(wand_adj, wand_col);
- shuffle_flavors<MAX_METALS>(rod_adj, rod_col);
- shuffle_flavors<MAX_SHROOM>(food_adj, food_col);
- shuffle_flavors<MAX_COLORS - 4>(potion_adj + 4, potion_col + 4);
-
- /* Scrolls (random titles, always white) */
- for (std::size_t i = 0; i < MAX_TITLES; i++)
- {
- /* Get a new title */
- while (TRUE)
- {
- std::string buf;
-
- /* Collect words until done */
- while (1)
- {
- /* Choose one or two syllables */
- int s = ((rand_int(100) < 30) ? 1 : 2);
-
- /* Add a one or two syllable word */
- std::string tmp;
- for (int q = 0; q < s; q++)
- {
- tmp += syllables[rand_int(MAX_SYLLABLES)];
- }
-
- /* Stop before getting too long */
- if (buf.size() + tmp.size() + 1 > 15)
- {
- break;
- }
-
- /* Add the word with separator */
- if (buf.size() > 0)
- {
- buf += " ";
- }
- buf += tmp;
- }
-
- /* Save the title */
- strcpy(scroll_adj[i], buf.c_str());
-
- /* Assume okay */
- bool_ okay = TRUE;
-
- /* Check for "duplicate" scroll titles */
- for (std::size_t j = 0; j < i; j++)
- {
- cptr hack1 = scroll_adj[j];
- cptr hack2 = scroll_adj[i];
-
- /* Compare first four characters */
- if (*hack1++ != *hack2++) continue;
- if (*hack1++ != *hack2++) continue;
- if (*hack1++ != *hack2++) continue;
- if (*hack1++ != *hack2++) continue;
-
- /* Not okay */
- okay = FALSE;
-
- /* Stop looking */
- break;
- }
-
- /* Break when done */
- if (okay) break;
- }
-
- /* All scrolls are white */
- scroll_col[i] = TERM_WHITE;
- }
+ shuffle(object_colors.rings);
+ shuffle(object_colors.amulets);
+ shuffle(object_colors.staves);
+ shuffle(object_colors.wands);
+ shuffle(object_colors.rods);
+ shuffle(object_colors.food);
+ shuffle(object_colors.scrolls);
+ shuffle(object_colors.potions);
/* Hack -- Use the "complex" RNG */
set_complex_rng();
/* Analyze every object */
- for (auto &k_ref: k_info)
+ for (auto &k_entry: k_info)
{
- auto k_ptr = &k_ref;
-
- /* Skip "empty" objects */
- if (!k_ptr->name) continue;
+ auto const &k_ptr = k_entry.second;
/* Extract "flavor" (if any) */
- k_ptr->flavor = object_flavor(k_ptr);
+ k_ptr->flavor = object_flavor(object_colors, k_ptr);
/* No flavor yields aware */
if ((!k_ptr->flavor) && (k_ptr->tval != TV_ROD_MAIN))
{
- k_ptr->aware = TRUE;
+ k_ptr->aware = true;
}
/* Check for "easily known" */
@@ -618,7 +371,7 @@ void flavor_init()
*
* This involves resetting various things to their "default" state.
*
- * If the "prefs" flag is TRUE, then we will also load the appropriate
+ * If the "prefs" flag is true, then we will also load the appropriate
* "user pref file" based on the current setting of the "use_graphics"
* flag. This is useful for switching "graphics" on/off.
*
@@ -652,11 +405,13 @@ void reset_visuals()
}
/* Extract default attr/char code for objects */
- for (auto &k_ref: k_info)
+ for (auto &k_entry: k_info)
{
+ auto k_ptr = k_entry.second;
+
/* Default attr/char */
- k_ref.x_attr = k_ref.d_attr;
- k_ref.x_char = k_ref.d_char;
+ k_ptr->x_attr = k_ptr->d_attr;
+ k_ptr->x_char = k_ptr->d_char;
}
/* Extract default attr/char code for monsters */
@@ -684,7 +439,7 @@ void reset_visuals()
}
/* Normal symbols */
- process_pref_file("font.prf");
+ process_pref_file(name_file_pref("font"));
}
@@ -779,20 +534,22 @@ static void object_flags_xtra(object_type const *o_ptr, object_flag_set *f)
/*
* Disregard sets when calculating flags?
*/
-bool_ object_flags_no_set = FALSE;
+bool object_flags_no_set = false;
/*
* Obtain the "flags" for an item
*/
object_flag_set object_flags(object_type const *o_ptr)
{
- auto const &k_info = game->edit_data.k_info;
auto const &a_info = game->edit_data.a_info;
- auto k_ptr = &k_info[o_ptr->k_idx];
+ if (!o_ptr->k_ptr)
+ {
+ return object_flag_set();
+ }
/* Base object */
- auto f = k_ptr->flags;
+ auto f = o_ptr->k_ptr->flags;
/* Artifact */
if (o_ptr->name1)
@@ -817,24 +574,20 @@ object_flag_set object_flags(object_type const *o_ptr)
}
/* Return object granted power */
-int object_power(object_type *o_ptr)
+boost::optional<int> object_power(object_type *o_ptr)
{
- auto const &k_info = game->edit_data.k_info;
auto const &a_info = game->edit_data.a_info;
auto const &e_info = game->edit_data.e_info;
- auto k_ptr = &k_info[o_ptr->k_idx];
- int power = -1;
-
/* Base object */
- power = k_ptr->power;
+ auto power = o_ptr->k_ptr->power;
/* Ego-item */
if (o_ptr->name2)
{
auto e_ptr = &e_info[o_ptr->name2];
- if (power == -1)
+ if (!power)
{
power = e_ptr->power;
}
@@ -843,7 +596,7 @@ int object_power(object_type *o_ptr)
{
auto e_ptr = &e_info[o_ptr->name2b];
- if (power == -1)
+ if (!power)
{
power = e_ptr->power;
}
@@ -855,13 +608,13 @@ int object_power(object_type *o_ptr)
{
auto a_ptr = &a_info[o_ptr->name1];
- if (power == -1)
+ if (!power)
{
power = a_ptr->power;
}
}
- return (power);
+ return power;
}
@@ -871,17 +624,16 @@ int object_power(object_type *o_ptr)
*/
object_flag_set object_flags_known(object_type const *o_ptr)
{
- auto const &k_info = game->edit_data.k_info;
auto const &a_info = game->edit_data.a_info;
- auto k_ptr = &k_info[o_ptr->k_idx];
-
/* Must be identified */
if (!object_known_p(o_ptr))
{
return object_flag_set();
}
+ auto k_ptr = o_ptr->k_ptr;
+
/* Base object */
auto flags = k_ptr->flags;
@@ -893,19 +645,11 @@ object_flag_set object_flags_known(object_type const *o_ptr)
{
auto a_ptr = &a_info[o_ptr->name1];
- /* Need full knowledge or spoilers */
- if ((o_ptr->ident & IDENT_MENTAL))
- {
- flags = a_ptr->flags;
+ flags = a_ptr->flags;
- if ((!object_flags_no_set) && (a_ptr->set != -1))
- {
- apply_flags_set(o_ptr->name1, a_ptr->set, &flags);
- }
- }
- else
+ if ((!object_flags_no_set) && (a_ptr->set != -1))
{
- flags = object_flag_set();
+ apply_flags_set(o_ptr->name1, a_ptr->set, &flags);
}
flags |= a_ptr->oflags;
@@ -914,21 +658,10 @@ object_flag_set object_flags_known(object_type const *o_ptr)
/* Random artifact or ego item! */
if (o_ptr->art_flags)
{
- /* Need full knowledge or spoilers */
- if ((o_ptr->ident & IDENT_MENTAL))
- {
- flags |= o_ptr->art_flags;
- }
-
+ flags |= o_ptr->art_flags;
flags |= o_ptr->art_oflags;
}
- /* Full knowledge for *identified* objects */
- if (!(o_ptr->ident & IDENT_MENTAL))
- {
- return flags;
- }
-
/* Extra powers */
object_flags_xtra(o_ptr, &flags);
@@ -1025,29 +758,35 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
auto const &random_artifacts = game->random_artifacts;
static auto const TR_PVAL_MASK = compute_pval_mask();
- bool_ hack_name = FALSE;
+ bool hack_name = false;
- bool_ append_name = FALSE;
+ bool append_name = false;
- bool_ show_weapon = FALSE;
- bool_ show_armour = FALSE;
+ bool show_weapon = false;
+ bool show_armour = false;
- auto k_ptr = &k_info[o_ptr->k_idx];
+ auto k_ptr = o_ptr->k_ptr;
/* Extract some flags */
auto const flags = object_flags(o_ptr);
/* See if the object is "aware" */
- bool_ aware = object_aware_p(o_ptr);
+ bool aware = object_aware_p(o_ptr);
/* See if the object is "known" */
- bool_ known = object_known_p(o_ptr);
+ bool known = object_known_p(o_ptr);
/* Hack -- Extract the sub-type "indexx" */
auto const indexx = o_ptr->sval;
/* Extract default "base" string */
- std::string basenm(k_ptr->name);
+ std::string k_name;
+ if (k_ptr)
+ {
+ k_name = k_ptr->name;
+ }
+
+ std::string basenm(k_name);
/* Assume no "modifier" string */
std::string modstr;
@@ -1061,7 +800,6 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
case TV_JUNK:
case TV_SPIKE:
case TV_FLASK:
- case TV_CHEST:
case TV_INSTRUMENT:
case TV_TOOL:
case TV_DIGGING:
@@ -1082,7 +820,7 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
case TV_SWORD:
case TV_AXE:
{
- show_weapon = TRUE;
+ show_weapon = true;
break;
}
@@ -1096,7 +834,7 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
case TV_HARD_ARMOR:
case TV_DRAG_ARMOR:
{
- show_armour = TRUE;
+ show_armour = true;
break;
}
@@ -1110,18 +848,13 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
/* Amulets (including a few "Specials") */
case TV_AMULET:
{
- /* Color the object */
- modstr = amulet_adj[indexx];
- if (aware) append_name = TRUE;
+ if (aware) append_name = true;
- if (aware || o_ptr->ident & IDENT_STOREB)
- basenm = "& Amulet~";
- else
- basenm = aware ? "& # Amulet~" : "& # Amulet~";
+ basenm = "& Amulet~";
if (known && o_ptr->artifact_name.empty() && artifact_p(o_ptr))
{
- basenm = k_ptr->name;
+ basenm = k_name;
}
break;
@@ -1130,21 +863,19 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
/* Rings (including a few "Specials") */
case TV_RING:
{
- /* Color the object */
- modstr = ring_adj[indexx];
- if (aware) append_name = TRUE;
+ if (aware) append_name = true;
- if (aware || o_ptr->ident & IDENT_STOREB)
- basenm = "& Ring~";
- else
- basenm = aware ? "& # Ring~" : "& # Ring~";
+ basenm = "& Ring~";
/* Hack -- The One Ring */
- if (!aware && (o_ptr->sval == SV_RING_POWER)) modstr = "Plain Gold";
+ if (!aware && (o_ptr->sval == SV_RING_POWER))
+ {
+ modstr = "Plain Gold";
+ }
if (known && o_ptr->artifact_name.empty() && artifact_p(o_ptr))
{
- basenm = k_ptr->name;
+ basenm = k_name;
}
break;
@@ -1152,80 +883,62 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
case TV_STAFF:
{
- /* Color the object */
- modstr = staff_adj[o_ptr->pval2 % MAX_WOODS];
- if (aware) append_name = TRUE;
- if (aware || o_ptr->ident & IDENT_STOREB)
- basenm = "& Staff~";
- else
- basenm = "& # Staff~";
+ if (aware) append_name = true;
+
+ basenm = "& Staff~";
break;
}
case TV_WAND:
{
- /* Color the object */
- modstr = wand_adj[o_ptr->pval2 % MAX_METALS];
- if (aware) append_name = TRUE;
- if (aware || o_ptr->ident & IDENT_STOREB)
- basenm = "& Wand~";
- else
- basenm = "& # Wand~";
+ if (aware) append_name = true;
+
+ basenm = "& Wand~";
break;
}
case TV_ROD:
{
- /* Color the object */
- modstr = rod_adj[indexx];
- if (aware) append_name = TRUE;
- if (aware || o_ptr->ident & IDENT_STOREB)
- basenm = "& Rod Tip~";
- else
- basenm = aware ? "& # Rod Tip~" : "& # Rod Tip~";
+ if (aware) append_name = true;
+
+ basenm = "& Rod Tip~";
+
if (o_ptr->sval == SV_ROD_HOME)
{
basenm = "& Great Rod Tip~ of Home Summoning";
- hack_name = TRUE;
+ hack_name = true;
}
+
break;
}
case TV_ROD_MAIN:
{
- modstr = k_info[lookup_kind(TV_ROD, o_ptr->pval)].name;
+ modstr = k_info.at(lookup_kind(TV_ROD, o_ptr->pval))->name;
break;
}
case TV_SCROLL:
{
- /* Color the object */
- modstr = scroll_adj[indexx];
- if (aware) append_name = TRUE;
- if (aware || o_ptr->ident & IDENT_STOREB)
- basenm = "& Scroll~";
- else
- basenm = aware ? "& Scroll~ titled \"#\"" : "& Scroll~ titled \"#\"";
+ if (aware) append_name = true;
+
+ basenm = "& Scroll~";
break;
}
case TV_POTION:
case TV_POTION2:
{
- /* Color the object */
if ((o_ptr->tval != TV_POTION2) || (o_ptr->sval != SV_POTION2_MIMIC) || (!aware))
{
- modstr = potion_adj[indexx];
- if (aware) append_name = TRUE;
+ if (aware) append_name = true;
}
else
{
modstr = get_mimic_name(o_ptr->pval2);
}
- if (aware || o_ptr->ident & IDENT_STOREB)
- basenm = "& Potion~";
- else
- basenm = aware ? "& # Potion~" : "& # Potion~";
+
+ basenm = "& Potion~";
break;
}
@@ -1234,13 +947,9 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
/* Ordinary food is "boring" */
if (o_ptr->sval >= SV_FOOD_MIN_FOOD) break;
- /* Color the object */
- modstr = food_adj[indexx];
- if (aware) append_name = TRUE;
- if (aware || o_ptr->ident & IDENT_STOREB)
- basenm = "& Mushroom~";
- else
- basenm = aware ? "& # Mushroom~" : "& # Mushroom~";
+ if (aware) append_name = true;
+
+ basenm = "& Mushroom~";
break;
}
@@ -1248,7 +957,7 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
/* Cloak of Mimicry */
case TV_CLOAK:
{
- show_armour = TRUE;
+ show_armour = true;
if (o_ptr->sval == SV_MIMIC_CLOAK)
{
modstr = get_mimic_object_name(o_ptr->pval2);
@@ -1333,7 +1042,7 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
monster_type monster;
monster.r_idx = o_ptr->pval;
monster.ego = o_ptr->pval2;
- monster.ml = TRUE;
+ monster.ml = true;
monster.status = MSTATUS_ENEMY;
char name[80];
@@ -1362,7 +1071,7 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
case TV_DAEMON_BOOK:
case TV_BOOK:
{
- basenm = k_ptr->name;
+ basenm = k_name;
if (o_ptr->sval == 255)
{
modstr = spell_type_name(spell_at(o_ptr->pval));
@@ -1378,7 +1087,7 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
/* Mega Hack */
if ((!hack_name) && known && (k_ptr->flags & TR_FULL_NAME))
{
- basenm = k_ptr->name;
+ basenm = k_name;
}
/* Copy of the base string _without_ a prefix */
@@ -1390,7 +1099,7 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
/* The object "expects" a "number" */
if (starts_with(basenm, "&"))
{
- cptr ego = NULL;
+ std::string ego;
/* Grab any ego-item name */
if (known && (o_ptr->name2 || o_ptr->name2b) && (o_ptr->tval != TV_ROD_MAIN))
@@ -1446,7 +1155,7 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
t += "The ";
}
- else if (ego != NULL)
+ else if (!ego.empty())
{
if (is_a_vowel(ego[0]))
{
@@ -1635,7 +1344,7 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
}
else
{
- t += k_ptr->name;
+ t += k_name;
}
}
@@ -1719,31 +1428,15 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
t += fmt::format(" (E:{}, L:{})", need_exp, o_ptr->elevel);
}
- /* Hack -- Chests must be described in detail */
- if (o_ptr->tval == TV_CHEST)
- {
- /* Not searched yet */
- if (!known)
- {
- /* Nothing */
- }
-
- /* May be "empty" */
- else if (!o_ptr->pval)
- {
- t += " (empty)";
- }
- }
-
/* Display the item like a weapon */
- if (flags & TR_SHOW_MODS) show_weapon = TRUE;
+ if (flags & TR_SHOW_MODS) show_weapon = true;
/* Display the item like a weapon */
- if (o_ptr->to_h && o_ptr->to_d) show_weapon = TRUE;
+ if (o_ptr->to_h && o_ptr->to_d) show_weapon = true;
/* Display the item like armour */
- if (o_ptr->ac) show_armour = TRUE;
+ if (o_ptr->ac) show_armour = true;
/* Dump base weapon info */
switch (o_ptr->tval)
@@ -1976,12 +1669,6 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
{
std::vector<std::string> inscrip;
- /* Sensed stuff */
- if ((o_ptr->ident & (IDENT_SENSE)) && sense_desc[o_ptr->sense] && sense_desc[o_ptr->sense][0] != '\0')
- {
- inscrip.push_back(sense_desc[o_ptr->sense]);
- }
-
/* Hack - Note "cursed" if the item is 'known' and cursed */
if (cursed_p(o_ptr) && known && inscrip.empty())
{
@@ -1997,18 +1684,6 @@ static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode)
inscrip.push_back(o_ptr->inscription.substr(0, pos));
}
- /* Mega-Hack -- note empty wands/staffs */
- if (!known && (o_ptr->ident & (IDENT_EMPTY)))
- {
- inscrip.push_back("empty");
- }
-
- /* Note "tried" if the object has been tested unsuccessfully */
- if (!aware && object_tried_p(o_ptr))
- {
- inscrip.push_back("tried");
- }
-
/* Note the discount, if any */
if ((o_ptr->discount) && o_ptr->inscription.empty())
{
@@ -2051,31 +1726,20 @@ void object_desc(char *buf, object_type const *o_ptr, int pref, int mode)
*/
void object_desc_store(char *buf, object_type *o_ptr, int pref, int mode)
{
- auto &k_info = game->edit_data.k_info;
-
- /* Save the "aware" flag */
- bool_ hack_aware = k_info[o_ptr->k_idx].aware;
-
- /* Save the "known" flag */
- bool_ hack_known = (o_ptr->ident & (IDENT_KNOWN)) ? TRUE : FALSE;
-
-
- /* Set the "known" flag */
- o_ptr->ident |= (IDENT_KNOWN);
-
- /* Force "aware" for description */
- k_info[o_ptr->k_idx].aware = TRUE;
+ /* Save the identification status */
+ bool saved_aware = o_ptr->k_ptr->aware;
+ auto saved_identified = o_ptr->identified;
+ /* Force full identification for description */
+ o_ptr->identified = true;
+ o_ptr->k_ptr->aware = true;
/* Describe the object */
object_desc(buf, o_ptr, pref, mode);
-
- /* Restore "aware" flag */
- k_info[o_ptr->k_idx].aware = hack_aware;
-
- /* Clear the known flag */
- if (!hack_known) o_ptr->ident &= ~(IDENT_KNOWN);
+ /* Restore identification status */
+ o_ptr->k_ptr->aware = saved_aware;
+ o_ptr->identified = saved_identified;
}
@@ -2085,7 +1749,7 @@ void object_desc_store(char *buf, object_type *o_ptr, int pref, int mode)
* Determine the "Activation" (if any) for an artifact
* Return a string, or NULL for "no activation"
*/
-cptr item_activation(object_type *o_ptr)
+const char *item_activation(object_type *o_ptr)
{
auto const &a_info = game->edit_data.a_info;
auto const &e_info = game->edit_data.e_info;
@@ -2122,11 +1786,11 @@ cptr item_activation(object_type *o_ptr)
}
}
- return activation_aux(o_ptr, FALSE, 0);
+ return activation_aux(o_ptr, false, 0);
}
/* Grab the tval desc */
-static bool_ grab_tval_desc(int tval)
+static bool grab_tval_desc(int tval)
{
int tv = 0;
@@ -2135,18 +1799,18 @@ static bool_ grab_tval_desc(int tval)
tv++;
}
- if (!tval_descs[tv].tval) return FALSE;
+ if (!tval_descs[tv].tval) return false;
text_out_c(TERM_L_BLUE, tval_descs[tv].desc);
text_out("\n");
- return TRUE;
+ return true;
}
-static void check_first(bool_ *first)
+static void check_first(bool *first)
{
if (*first) {
- *first = FALSE;
+ *first = false;
}
else
{
@@ -2157,7 +1821,7 @@ static void check_first(bool_ *first)
/*
* Display the damage done with a multiplier
*/
-void output_dam(object_type *o_ptr, int mult, int mult2, cptr against, cptr against2, bool_ *first)
+void output_dam(object_type *o_ptr, int mult, int mult2, const char *against, const char *against2, bool *first)
{
int dam;
@@ -2201,8 +1865,7 @@ void output_dam(object_type *o_ptr, int mult, int mult2, cptr against, cptr agai
void display_weapon_damage(object_type *o_ptr)
{
object_type forge, *old_ptr = &forge;
- bool_ first = TRUE;
- bool_ full = o_ptr->ident & (IDENT_MENTAL);
+ bool first = true;
/* Extract the flags */
auto const flags = object_flags(o_ptr);
@@ -2210,29 +1873,32 @@ void display_weapon_damage(object_type *o_ptr)
/* Ok now the hackish stuff, we replace the current weapon with this one */
object_copy(old_ptr, &p_ptr->inventory[INVEN_WIELD]);
object_copy(&p_ptr->inventory[INVEN_WIELD], o_ptr);
- calc_bonuses(TRUE);
+ calc_bonuses(true);
text_out("\nUsing it you would have ");
text_out_c(TERM_L_GREEN, format("%d ", p_ptr->num_blow));
text_out(format("blow%s and do an average damage per turn of ", (p_ptr->num_blow) ? "s" : ""));
- if (full && (flags & TR_SLAY_ANIMAL)) output_dam(o_ptr, 2, 0, "animals", NULL, &first);
- if (full && (flags & TR_SLAY_EVIL)) output_dam(o_ptr, 2, 0, "evil creatures", NULL, &first);
- if (full && (flags & TR_SLAY_ORC)) output_dam(o_ptr, 3, 0, "orcs", NULL, &first);
- if (full && (flags & TR_SLAY_TROLL)) output_dam(o_ptr, 3, 0, "trolls", NULL, &first);
- if (full && (flags & TR_SLAY_GIANT)) output_dam(o_ptr, 3, 0, "giants", NULL, &first);
- if (full && (flags & TR_KILL_DRAGON)) output_dam(o_ptr, 5, 0, "dragons", NULL, &first);
- else if (full && (flags & TR_SLAY_DRAGON)) output_dam(o_ptr, 3, 0, "dragons", NULL, &first);
- if (full && (flags & TR_KILL_UNDEAD)) output_dam(o_ptr, 5, 0, "undead", NULL, &first);
- else if (full && (flags & TR_SLAY_UNDEAD)) output_dam(o_ptr, 3, 0, "undead", NULL, &first);
- if (full && (flags & TR_KILL_DEMON)) output_dam(o_ptr, 5, 0, "demons", NULL, &first);
- else if (full && (flags & TR_SLAY_DEMON)) output_dam(o_ptr, 3, 0, "demons", NULL, &first);
-
- if (full && (flags & TR_BRAND_FIRE)) output_dam(o_ptr, 3, 6, "non fire resistant creatures", "fire susceptible creatures", &first);
- if (full && (flags & TR_BRAND_COLD)) output_dam(o_ptr, 3, 6, "non cold resistant creatures", "cold susceptible creatures", &first);
- if (full && (flags & TR_BRAND_ELEC)) output_dam(o_ptr, 3, 6, "non lightning resistant creatures", "lightning susceptible creatures", &first);
- if (full && (flags & TR_BRAND_ACID)) output_dam(o_ptr, 3, 6, "non acid resistant creatures", "acid susceptible creatures", &first);
- if (full && (flags & TR_BRAND_POIS)) output_dam(o_ptr, 3, 6, "non poison resistant creatures", "poison susceptible creatures", &first);
+ if (flags & TR_SLAY_ANIMAL) output_dam(o_ptr, 2, 0, "animals", NULL, &first);
+ if (flags & TR_SLAY_EVIL) output_dam(o_ptr, 2, 0, "evil creatures", NULL, &first);
+ if (flags & TR_SLAY_ORC) output_dam(o_ptr, 3, 0, "orcs", NULL, &first);
+ if (flags & TR_SLAY_TROLL) output_dam(o_ptr, 3, 0, "trolls", NULL, &first);
+ if (flags & TR_SLAY_GIANT) output_dam(o_ptr, 3, 0, "giants", NULL, &first);
+
+ if (flags & TR_KILL_DRAGON) output_dam(o_ptr, 5, 0, "dragons", NULL, &first);
+ else if (flags & TR_SLAY_DRAGON) output_dam(o_ptr, 3, 0, "dragons", NULL, &first);
+
+ if (flags & TR_KILL_UNDEAD) output_dam(o_ptr, 5, 0, "undead", NULL, &first);
+ else if (flags & TR_SLAY_UNDEAD) output_dam(o_ptr, 3, 0, "undead", NULL, &first);
+
+ if (flags & TR_KILL_DEMON) output_dam(o_ptr, 5, 0, "demons", NULL, &first);
+ else if (flags & TR_SLAY_DEMON) output_dam(o_ptr, 3, 0, "demons", NULL, &first);
+
+ if (flags & TR_BRAND_FIRE) output_dam(o_ptr, 3, 6, "non fire resistant creatures", "fire susceptible creatures", &first);
+ if (flags & TR_BRAND_COLD) output_dam(o_ptr, 3, 6, "non cold resistant creatures", "cold susceptible creatures", &first);
+ if (flags & TR_BRAND_ELEC) output_dam(o_ptr, 3, 6, "non lightning resistant creatures", "lightning susceptible creatures", &first);
+ if (flags & TR_BRAND_ACID) output_dam(o_ptr, 3, 6, "non acid resistant creatures", "acid susceptible creatures", &first);
+ if (flags & TR_BRAND_POIS) output_dam(o_ptr, 3, 6, "non poison resistant creatures", "poison susceptible creatures", &first);
output_dam(o_ptr, 1, 0, (first) ? "all monsters" : "other monsters", NULL, &first);
@@ -2240,13 +1906,13 @@ void display_weapon_damage(object_type *o_ptr)
/* get our weapon back */
object_copy(&p_ptr->inventory[INVEN_WIELD], old_ptr);
- calc_bonuses(TRUE);
+ calc_bonuses(true);
}
/*
* Display the ammo damage done with a multiplier
*/
-void output_ammo_dam(object_type *o_ptr, int mult, int mult2, cptr against, cptr against2, bool_ *first)
+void output_ammo_dam(object_type *o_ptr, int mult, int mult2, const char *against, const char *against2, bool *first)
{
int dam;
object_type *b_ptr = &p_ptr->inventory[INVEN_BOW];
@@ -2299,9 +1965,8 @@ void output_ammo_dam(object_type *o_ptr, int mult, int mult2, cptr against, cptr
*/
void display_ammo_damage(object_type *o_ptr)
{
- bool_ first = TRUE;
+ bool first = true;
int i;
- bool_ full = o_ptr->ident & (IDENT_MENTAL);
/* Extract the flags */
auto const flags = object_flags(o_ptr);
@@ -2310,23 +1975,27 @@ void display_ammo_damage(object_type *o_ptr)
text_out("\nUsing it you would do an average damage per throw of ");
else
text_out("\nUsing it with your current shooter you would do an average damage per shot of ");
- if (full && (flags & TR_SLAY_ANIMAL)) output_ammo_dam(o_ptr, 2, 0, "animals", NULL, &first);
- if (full && (flags & TR_SLAY_EVIL)) output_ammo_dam(o_ptr, 2, 0, "evil creatures", NULL, &first);
- if (full && (flags & TR_SLAY_ORC)) output_ammo_dam(o_ptr, 3, 0, "orcs", NULL, &first);
- if (full && (flags & TR_SLAY_TROLL)) output_ammo_dam(o_ptr, 3, 0, "trolls", NULL, &first);
- if (full && (flags & TR_SLAY_GIANT)) output_ammo_dam(o_ptr, 3, 0, "giants", NULL, &first);
- if (full && (flags & TR_KILL_DRAGON)) output_ammo_dam(o_ptr, 5, 0, "dragons", NULL, &first);
- else if (full && (flags & TR_SLAY_DRAGON)) output_ammo_dam(o_ptr, 3, 0, "dragons", NULL, &first);
- if (full && (flags & TR_KILL_UNDEAD)) output_ammo_dam(o_ptr, 5, 0, "undeads", NULL, &first);
- else if (full && (flags & TR_SLAY_UNDEAD)) output_ammo_dam(o_ptr, 3, 0, "undeads", NULL, &first);
- if (full && (flags & TR_KILL_DEMON)) output_ammo_dam(o_ptr, 5, 0, "demons", NULL, &first);
- else if (full && (flags & TR_SLAY_DEMON)) output_ammo_dam(o_ptr, 3, 0, "demons", NULL, &first);
-
- if (full && (flags & TR_BRAND_FIRE)) output_ammo_dam(o_ptr, 3, 6, "non fire resistant creatures", "fire susceptible creatures", &first);
- if (full && (flags & TR_BRAND_COLD)) output_ammo_dam(o_ptr, 3, 6, "non cold resistant creatures", "cold susceptible creatures", &first);
- if (full && (flags & TR_BRAND_ELEC)) output_ammo_dam(o_ptr, 3, 6, "non lightning resistant creatures", "lightning susceptible creatures", &first);
- if (full && (flags & TR_BRAND_ACID)) output_ammo_dam(o_ptr, 3, 6, "non acid resistant creatures", "acid susceptible creatures", &first);
- if (full && (flags & TR_BRAND_POIS)) output_ammo_dam(o_ptr, 3, 6, "non poison resistant creatures", "poison susceptible creatures", &first);
+
+ if (flags & TR_SLAY_ANIMAL) output_ammo_dam(o_ptr, 2, 0, "animals", NULL, &first);
+ if (flags & TR_SLAY_EVIL) output_ammo_dam(o_ptr, 2, 0, "evil creatures", NULL, &first);
+ if (flags & TR_SLAY_ORC) output_ammo_dam(o_ptr, 3, 0, "orcs", NULL, &first);
+ if (flags & TR_SLAY_TROLL) output_ammo_dam(o_ptr, 3, 0, "trolls", NULL, &first);
+ if (flags & TR_SLAY_GIANT) output_ammo_dam(o_ptr, 3, 0, "giants", NULL, &first);
+
+ if (flags & TR_KILL_DRAGON) output_ammo_dam(o_ptr, 5, 0, "dragons", NULL, &first);
+ else if (flags & TR_SLAY_DRAGON) output_ammo_dam(o_ptr, 3, 0, "dragons", NULL, &first);
+
+ if (flags & TR_KILL_UNDEAD) output_ammo_dam(o_ptr, 5, 0, "undeads", NULL, &first);
+ else if (flags & TR_SLAY_UNDEAD) output_ammo_dam(o_ptr, 3, 0, "undeads", NULL, &first);
+
+ if (flags & TR_KILL_DEMON) output_ammo_dam(o_ptr, 5, 0, "demons", NULL, &first);
+ else if (flags & TR_SLAY_DEMON) output_ammo_dam(o_ptr, 3, 0, "demons", NULL, &first);
+
+ if (flags & TR_BRAND_FIRE) output_ammo_dam(o_ptr, 3, 6, "non fire resistant creatures", "fire susceptible creatures", &first);
+ if (flags & TR_BRAND_COLD) output_ammo_dam(o_ptr, 3, 6, "non cold resistant creatures", "cold susceptible creatures", &first);
+ if (flags & TR_BRAND_ELEC) output_ammo_dam(o_ptr, 3, 6, "non lightning resistant creatures", "lightning susceptible creatures", &first);
+ if (flags & TR_BRAND_ACID) output_ammo_dam(o_ptr, 3, 6, "non acid resistant creatures", "acid susceptible creatures", &first);
+ if (flags & TR_BRAND_POIS) output_ammo_dam(o_ptr, 3, 6, "non poison resistant creatures", "poison susceptible creatures", &first);
output_ammo_dam(o_ptr, 1, 0, (first) ? "all monsters" : "other monsters", NULL, &first);
text_out(". ");
@@ -2351,8 +2020,6 @@ void display_ammo_damage(object_type *o_ptr)
*/
static void describe_device(object_type *o_ptr)
{
- char buf[128];
-
/* Wands/... of shcool spell */
if (((o_ptr->tval == TV_WAND) || (o_ptr->tval == TV_STAFF)) && object_known_p(o_ptr))
{
@@ -2370,15 +2037,14 @@ static void describe_device(object_type *o_ptr)
});
text_out("\nSpell level: ");
- sprintf(buf, FMTs32b, get_level(o_ptr->pval2, 50));
- text_out_c(TERM_L_BLUE, buf);
+
+ text_out_c(TERM_L_BLUE, fmt::format("{}", get_level(o_ptr->pval2, 50)));
text_out("\nMinimum Magic Device level to increase spell level: ");
- text_out_c(TERM_L_BLUE, format("%d", spell_type_skill_level(spell)));
+ text_out_c(TERM_L_BLUE, fmt::format("{}", spell_type_skill_level(spell)));
text_out("\nSpell fail: ");
- sprintf(buf, FMTs32b, spell_chance_device(spell));
- text_out_c(TERM_GREEN, buf);
+ text_out_c(TERM_GREEN, fmt::format("{}", spell_chance_device(spell)));
text_out("\nSpell info: ");
text_out_c(TERM_YELLOW, spell_type_info(spell));
@@ -2397,7 +2063,7 @@ static void describe_device(object_type *o_ptr)
* Print the level something was found on
*
*/
-static cptr object_out_desc_where_found(s16b level, s16b dungeon)
+static const char *object_out_desc_where_found(s16b level, s16b dungeon)
{
auto const &d_info = game->edit_data.d_info;
auto const &wf_info = game->edit_data.wf_info;
@@ -2431,28 +2097,20 @@ static cptr object_out_desc_where_found(s16b level, s16b dungeon)
/*
* Describe an item
*/
-bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait_for_it)
+bool object_out_desc(object_type *o_ptr, FILE *fff, bool trim_down, bool wait_for_it)
{
auto const &set_info = game->edit_data.set_info;
auto const &st_info = game->edit_data.st_info;
- auto const &k_info = game->edit_data.k_info;
auto const &a_info = game->edit_data.a_info;
- cptr vp[64];
+ const char *vp[64];
byte vc[64];
int vn;
object_flag_set flags;
/* Extract the flags */
- if ((!(o_ptr->ident & (IDENT_MENTAL))) && (!fff))
- {
- flags = o_ptr->art_oflags;
- }
- else
- {
- flags = object_flags(o_ptr);
- }
+ flags = object_flags(o_ptr);
if (fff)
{
@@ -2463,8 +2121,7 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait
else
{
/* Save the screen */
- character_icky = TRUE;
- Term_save();
+ screen_save_no_flush();
/* Set up stuff for text_out */
text_out_hook = text_out_to_screen;
@@ -2479,11 +2136,9 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait
if (object_known_p(o_ptr))
{
- if (o_ptr->k_idx && (!trim_down))
+ if (o_ptr->k_ptr && (!trim_down))
{
- auto k_ptr = &k_info[o_ptr->k_idx];
-
- text_out_c(TERM_ORANGE, k_ptr->text);
+ text_out_c(TERM_ORANGE, o_ptr->k_ptr->text);
text_out("\n");
}
@@ -2507,7 +2162,7 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait
else if (count_bits(o_ptr->pval3) > 1) text_out("It is sentient and can have access to the realms of ");
else text_out("It is sentient and can have access to the realm of ");
- bool_ first = TRUE;
+ bool first = true;
for (std::size_t j = 0; j < flags_groups().size(); j++)
{
if (BIT(j) & o_ptr->pval3)
@@ -2545,10 +2200,10 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait
text_out(" if it is being worn. ");
}
/* Granted power */
- if (object_power(o_ptr) != -1)
+ if (auto power_idx = object_power(o_ptr))
{
text_out("It grants you the power of ");
- text_out(powers_type[object_power(o_ptr)].name);
+ text_out(game->powers.at(*power_idx)->name);
text_out(" if it is being worn. ");
}
@@ -3162,11 +2817,6 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait
{
text_out("It has been blessed by the gods. ");
}
- if (flags & TR_AUTO_ID)
- {
- text_out("It identifies all items for you. ");
- }
-
if (flags & TR_TELEPORT)
{
text_out("It induces random teleportation. ");
@@ -3315,10 +2965,9 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait
}
}
- if (!object_known_p(o_ptr))
+ if (!object_known_p(o_ptr)) {
text_out("\nYou might need to identify the item to know some more about it...");
- else if (!(o_ptr->ident & (IDENT_MENTAL)))
- text_out("\nYou might need to *identify* the item to know more about it...");
+ }
}
/* Copying how others seem to do it. -- neil */
@@ -3393,7 +3042,7 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait
/* Restore the screen */
Term_load();
}
- character_icky = FALSE;
+ character_icky = false;
}
@@ -3401,7 +3050,7 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait
text_out_hook = text_out_to_screen;
/* Gave knowledge */
- return (TRUE);
+ return true;
}
@@ -3435,7 +3084,7 @@ static s16b label_to_inven(int c)
if ((i < 0) || (i > INVEN_PACK)) return ( -1);
/* Empty slots can never be chosen */
- if (!p_ptr->inventory[i].k_idx) return ( -1);
+ if (!p_ptr->inventory[i].k_ptr) return ( -1);
/* Return the index */
return (i);
@@ -3457,7 +3106,7 @@ static s16b label_to_equip(int c)
if ((i < INVEN_WIELD) || (i >= INVEN_TOTAL)) return ( -1);
/* Empty slots can never be chosen */
- if (!p_ptr->inventory[i].k_idx) return ( -1);
+ if (!p_ptr->inventory[i].k_ptr) return ( -1);
/* Return the index */
return (i);
@@ -3480,7 +3129,10 @@ static int get_slot(int slot)
if (p_ptr->body_parts[slot + i - INVEN_WIELD])
{
/* Free ? return the slot */
- if (!p_ptr->inventory[slot + i].k_idx) return (slot + i);
+ if (!p_ptr->inventory[slot + i].k_ptr)
+ {
+ return (slot + i);
+ }
}
else break;
@@ -3495,9 +3147,9 @@ static int get_slot(int slot)
/*
* Determine which equipment slot (if any) an item likes, ignoring the player's
- * current body and stuff if ideal == TRUE
+ * current body and stuff if ideal == true
*/
-s16b wield_slot_ideal(object_type const *o_ptr, bool_ ideal)
+s16b wield_slot_ideal(object_type const *o_ptr, bool ideal)
{
/* Slot for equipment */
switch (o_ptr->tval)
@@ -3579,60 +3231,73 @@ s16b wield_slot_ideal(object_type const *o_ptr, bool_ ideal)
case TV_SHOT:
{
+ auto quiver_ptr = &p_ptr->inventory[INVEN_AMMO];
+ auto launcher_ptr = &p_ptr->inventory[INVEN_BOW];
+
if (ideal)
{
return INVEN_AMMO;
}
- else if (p_ptr->inventory[INVEN_AMMO].k_idx &&
- object_similar(o_ptr, &p_ptr->inventory[INVEN_AMMO]) &&
- p_ptr->inventory[INVEN_AMMO].number + o_ptr->number < MAX_STACK_SIZE)
+ else if (quiver_ptr->k_ptr &&
+ object_similar(o_ptr, quiver_ptr) &&
+ quiver_ptr->number + o_ptr->number < MAX_STACK_SIZE)
{
return get_slot(INVEN_AMMO);
}
- else if ((p_ptr->inventory[INVEN_BOW].k_idx) && (p_ptr->inventory[INVEN_BOW].tval == TV_BOW))
+ else if (launcher_ptr->k_ptr &&
+ (launcher_ptr->tval == TV_BOW) &&
+ (launcher_ptr->sval < 10))
{
- if (p_ptr->inventory[INVEN_BOW].sval < 10)
- return get_slot(INVEN_AMMO);
+ return get_slot(INVEN_AMMO);
}
return -1;
}
case TV_ARROW:
{
+ auto quiver_ptr = &p_ptr->inventory[INVEN_AMMO];
+ auto launcher_ptr = &p_ptr->inventory[INVEN_BOW];
+
if (ideal)
{
return INVEN_AMMO;
}
- else if (p_ptr->inventory[INVEN_AMMO].k_idx &&
- object_similar(o_ptr, &p_ptr->inventory[INVEN_AMMO]) &&
- p_ptr->inventory[INVEN_AMMO].number + o_ptr->number < MAX_STACK_SIZE)
+ else if (quiver_ptr->k_ptr &&
+ object_similar(o_ptr, quiver_ptr) &&
+ quiver_ptr->number + o_ptr->number < MAX_STACK_SIZE)
{
return get_slot(INVEN_AMMO);
}
- else if ((p_ptr->inventory[INVEN_BOW].k_idx) && (p_ptr->inventory[INVEN_BOW].tval == TV_BOW))
+ else if (launcher_ptr->k_ptr &&
+ (launcher_ptr->tval == TV_BOW) &&
+ (launcher_ptr->sval >= 10) &&
+ (launcher_ptr->sval < 20))
{
- if ((p_ptr->inventory[INVEN_BOW].sval >= 10) && (p_ptr->inventory[INVEN_BOW].sval < 20))
- return get_slot(INVEN_AMMO);
+ return get_slot(INVEN_AMMO);
}
return -1;
}
case TV_BOLT:
{
+ auto quiver_ptr = &p_ptr->inventory[INVEN_AMMO];
+ auto launcher_ptr = &p_ptr->inventory[INVEN_BOW];
+
if (ideal)
{
return INVEN_AMMO;
}
- else if (p_ptr->inventory[INVEN_AMMO].k_idx &&
- object_similar(o_ptr, &p_ptr->inventory[INVEN_AMMO]) &&
- p_ptr->inventory[INVEN_AMMO].number + o_ptr->number < MAX_STACK_SIZE)
+ else if (quiver_ptr->k_ptr &&
+ object_similar(o_ptr, quiver_ptr) &&
+ quiver_ptr->number + o_ptr->number < MAX_STACK_SIZE)
{
return get_slot(INVEN_AMMO);
}
- else if ((p_ptr->inventory[INVEN_BOW].k_idx) && (p_ptr->inventory[INVEN_BOW].tval == TV_BOW))
+ else if ((launcher_ptr->k_ptr) &&
+ (launcher_ptr->tval == TV_BOW) &&
+ (launcher_ptr->sval >= 20))
{
- if (p_ptr->inventory[INVEN_BOW].sval >= 20)
- return get_slot(INVEN_AMMO);
+ return get_slot(INVEN_AMMO);
}
return -1;
}
@@ -3667,15 +3332,15 @@ s16b wield_slot_ideal(object_type const *o_ptr, bool_ ideal)
*/
s16b wield_slot(object_type const *o_ptr)
{
- return wield_slot_ideal(o_ptr, FALSE);
+ return wield_slot_ideal(o_ptr, false);
}
/*
* Return a string mentioning how a given item is carried
*/
-static cptr mention_use(int i)
+static const char *mention_use(int i)
{
- cptr p;
+ const char *p;
/* Examine the location */
switch (i)
@@ -3776,9 +3441,9 @@ static cptr mention_use(int i)
* Return a string describing how a given item is being worn.
* Currently, only used for items in the equipment, not inventory.
*/
-cptr describe_use(int i)
+const char *describe_use(int i)
{
- cptr p = nullptr;
+ const char *p = nullptr;
switch (i)
{
@@ -3885,7 +3550,7 @@ static bool item_tester_okay(object_type const *o_ptr, object_filter_t const &fi
}
/* Require an item */
- if (!o_ptr->k_idx)
+ if (!o_ptr->k_ptr)
{
return false;
}
@@ -3903,15 +3568,15 @@ static bool item_tester_okay(object_type const *o_ptr, object_filter_t const &fi
-static void show_equip_aux(bool_ mirror, object_filter_t const &filter);
-static void show_inven_aux(bool_ mirror, object_filter_t const &filter);
+static void show_equip_aux(bool mirror, object_filter_t const &filter);
+static void show_inven_aux(bool mirror, object_filter_t const &filter);
/*
* Choice window "shadow" of the "show_inven()" function
*/
void display_inven()
{
- show_inven_aux(TRUE, object_filter::True());
+ show_inven_aux(true, object_filter::True());
}
@@ -3921,7 +3586,7 @@ void display_inven()
*/
void display_equip()
{
- show_equip_aux(TRUE, object_filter::True());
+ show_equip_aux(true, object_filter::True());
}
@@ -3939,7 +3604,7 @@ byte get_item_letter_color(object_type const *o_ptr)
if (ego_item_p(o_ptr)) color = TERM_L_BLUE;
if (artifact_p(o_ptr)) color = TERM_YELLOW;
if (o_ptr->name1 && ( -1 != a_info[o_ptr->name1].set)) color = TERM_GREEN;
- if (o_ptr->name1 && (a_info[o_ptr->name1].flags & TR_ULTIMATE) && (o_ptr->ident & (IDENT_MENTAL))) color = TERM_VIOLET;
+ if (o_ptr->name1 && (a_info[o_ptr->name1].flags & TR_ULTIMATE)) color = TERM_VIOLET;
return (color);
}
@@ -3950,7 +3615,7 @@ byte get_item_letter_color(object_type const *o_ptr)
*
* Hack -- do not display "trailing" empty slots
*/
-void show_inven_aux(bool_ mirror, const object_filter_t &filter)
+void show_inven_aux(bool mirror, const object_filter_t &filter)
{
int i, j, k, l, z = 0;
int row, col, len, lim;
@@ -3990,7 +3655,10 @@ void show_inven_aux(bool_ mirror, const object_filter_t &filter)
o_ptr = &p_ptr->inventory[i];
/* Skip non-objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Track */
z = i + 1;
@@ -4012,7 +3680,7 @@ void show_inven_aux(bool_ mirror, const object_filter_t &filter)
out_index[k] = i + 1;
/* Describe the object */
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Hack -- enforce max length */
o_name[lim] = '\0';
@@ -4068,7 +3736,10 @@ void show_inven_aux(bool_ mirror, const object_filter_t &filter)
byte a = object_attr(o_ptr);
char c = object_char(o_ptr);
- if (!o_ptr->k_idx) c = ' ';
+ if (!o_ptr->k_ptr)
+ {
+ c = ' ';
+ }
Term_draw(col + 3, row + j, a, c);
}
@@ -4109,7 +3780,7 @@ void show_inven_aux(bool_ mirror, const object_filter_t &filter)
static void show_inven(object_filter_t const &filter)
{
- show_inven_aux(FALSE, filter);
+ show_inven_aux(false, filter);
}
void show_inven_full()
@@ -4121,7 +3792,7 @@ void show_inven_full()
static void show_equip(object_filter_t const &filter)
{
- show_equip_aux(FALSE, filter);
+ show_equip_aux(false, filter);
}
void show_equip_full()
@@ -4134,7 +3805,7 @@ void show_equip_full()
/*
* Display the equipment.
*/
-void show_equip_aux(bool_ mirror, object_filter_t const &filter)
+void show_equip_aux(bool mirror, object_filter_t const &filter)
{
int i, j, k, l;
int row, col, len, lim, idx;
@@ -4186,14 +3857,14 @@ void show_equip_aux(bool_ mirror, object_filter_t const &filter)
/* Inform the player that he/she can't use a shield */
if ((p_ptr->body_parts[i - INVEN_WIELD] == INVEN_ARM) &&
- !o_ptr->k_idx &&
- p_ptr->inventory[i - INVEN_ARM + INVEN_WIELD].k_idx)
+ !o_ptr->k_ptr &&
+ p_ptr->inventory[i - INVEN_ARM + INVEN_WIELD].k_ptr)
{
object_type *q_ptr = &p_ptr->inventory[i - INVEN_ARM + INVEN_WIELD];
char q_name[80];
/* Description */
- object_desc(q_name, q_ptr, TRUE, 3);
+ object_desc(q_name, q_ptr, true, 3);
/* Get weapon flags */
auto const flags = object_flags(q_ptr);
@@ -4218,7 +3889,7 @@ void show_equip_aux(bool_ mirror, object_filter_t const &filter)
}
if ((p_ptr->body_parts[i - INVEN_WIELD] == INVEN_WIELD) &&
- !o_ptr->k_idx)
+ !o_ptr->k_ptr)
{
sprintf(o_name, "(%s)", get_melee_name());
@@ -4239,7 +3910,7 @@ void show_equip_aux(bool_ mirror, object_filter_t const &filter)
idx++;
/* Description */
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Truncate the description */
o_name[lim] = 0;
@@ -4311,7 +3982,10 @@ void show_equip_aux(bool_ mirror, object_filter_t const &filter)
byte a = object_attr(o_ptr);
char c = object_char(o_ptr);
- if (!o_ptr->k_idx) c = ' ';
+ if (!o_ptr->k_ptr)
+ {
+ c = ' ';
+ }
Term_draw(col + 3, row + j, a, c);
}
@@ -4403,7 +4077,7 @@ void toggle_inven_equip()
*
* The item can be negative to mean "item on floor".
*/
-bool_ verify(cptr prompt, int item)
+bool verify(const char *prompt, int item)
{
char o_name[80];
@@ -4415,7 +4089,7 @@ bool_ verify(cptr prompt, int item)
o_ptr = get_object(item);
/* Describe */
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Prompt */
sprintf(out_val, "%s %s? ", prompt, o_name);
@@ -4430,7 +4104,7 @@ bool_ verify(cptr prompt, int item)
*
* The item can be negative to mean "item on floor".
*/
-static bool_ get_item_allow(int item)
+static bool get_item_allow(int item)
{
/* Get object */
auto o_ptr = get_object(item);
@@ -4438,7 +4112,7 @@ static bool_ get_item_allow(int item)
/* No inscription */
if (o_ptr->inscription.empty())
{
- return TRUE;
+ return true;
}
/* Find a '!' */
@@ -4451,7 +4125,7 @@ static bool_ get_item_allow(int item)
if ((s[1] == command_cmd) || (s[1] == '*'))
{
/* Verify the choice */
- if (!verify("Really try", item)) return (FALSE);
+ if (!verify("Really try", item)) return false;
}
/* Find another '!' */
@@ -4459,7 +4133,7 @@ static bool_ get_item_allow(int item)
}
/* Allow it */
- return (TRUE);
+ return true;
}
@@ -4472,7 +4146,7 @@ static bool get_item_okay(int i, object_filter_t const &filter)
/* Illegal items */
if ((i < 0) || (i >= INVEN_TOTAL))
{
- return (FALSE);
+ return false;
}
/* Verify the item */
@@ -4498,7 +4172,7 @@ static int get_tag(int *cp, char tag)
object_type *o_ptr = &p_ptr->inventory[i];
/* Skip non-objects */
- if (!o_ptr->k_idx)
+ if (!o_ptr->k_ptr)
{
continue;
}
@@ -4522,7 +4196,7 @@ static int get_tag(int *cp, char tag)
*cp = i;
/* Success */
- return (TRUE);
+ return true;
}
/* Check the special tags */
@@ -4532,7 +4206,7 @@ static int get_tag(int *cp, char tag)
*cp = i;
/* Success */
- return (TRUE);
+ return true;
}
/* Find another '@' */
@@ -4541,7 +4215,7 @@ static int get_tag(int *cp, char tag)
}
/* No such tag */
- return (FALSE);
+ return false;
}
/*
@@ -4621,7 +4295,7 @@ static void show_floor(int y, int x, object_filter_t const &filter)
o_ptr = &o_list[floor_list[i]];
/* Describe the object */
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Hack -- enforce max length */
o_name[lim] = '\0';
@@ -4688,26 +4362,26 @@ static void show_floor(int y, int x, object_filter_t const &filter)
* This version of get_item() is called by get_item() when
* the easy_floor is on.
*/
-static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter_t const &filter, select_by_name_t const &select_by_name)
+static bool get_item_floor(int *cp, const char *pmt, const char *str, int mode, object_filter_t const &filter, select_by_name_t const &select_by_name)
{
char n1 = 0, n2 = 0, which = ' ';
int j, k, i1, i2, e1, e2;
- bool_ done, item;
+ bool done, item;
- bool_ oops = FALSE;
+ bool oops = false;
- bool_ equip = FALSE;
- bool_ inven = FALSE;
- bool_ floor = FALSE;
- bool_ automat = FALSE;
+ bool equip = false;
+ bool inven = false;
+ bool floor = false;
+ bool automat = false;
- bool_ allow_equip = FALSE;
- bool_ allow_inven = FALSE;
- bool_ allow_floor = FALSE;
+ bool allow_equip = false;
+ bool allow_inven = false;
+ bool allow_floor = false;
- bool_ toggle = FALSE;
+ bool toggle = false;
char tmp_val[160];
char out_val[160];
@@ -4734,7 +4408,7 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter
if (item_tester_okay(o_ptr, filter))
{
/* Success */
- return (TRUE);
+ return true;
}
}
@@ -4742,16 +4416,16 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter
else if (get_item_okay(*cp, filter))
{
/* Success */
- return (TRUE);
+ return true;
}
}
/* Extract args */
- if (mode & (USE_EQUIP)) equip = TRUE;
- if (mode & (USE_INVEN)) inven = TRUE;
- if (mode & (USE_FLOOR)) floor = TRUE;
- if (mode & (USE_AUTO)) automat = TRUE;
+ if (mode & (USE_EQUIP)) equip = true;
+ if (mode & (USE_INVEN)) inven = true;
+ if (mode & (USE_FLOOR)) floor = true;
+ if (mode & (USE_AUTO)) automat = true;
/* Paranoia XXX XXX XXX */
@@ -4759,10 +4433,10 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter
/* Not done */
- done = FALSE;
+ done = false;
/* No item selected */
- item = FALSE;
+ item = false;
/* Full inventory */
@@ -4797,22 +4471,22 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter
int const floor_num = floor_list.size(); // "int" for warning avoidance
/* Accept inventory */
- if (i1 <= i2) allow_inven = TRUE;
+ if (i1 <= i2) allow_inven = true;
/* Accept equipment */
- if (e1 <= e2) allow_equip = TRUE;
+ if (e1 <= e2) allow_equip = true;
/* Accept floor */
- if (!floor_list.empty()) allow_floor = TRUE;
+ if (!floor_list.empty()) allow_floor = true;
/* Require at least one legal choice */
if (!allow_inven && !allow_equip && !allow_floor)
{
/* Oops */
- oops = TRUE;
+ oops = true;
/* Done */
- done = TRUE;
+ done = true;
}
/* Analyze choices */
@@ -4911,7 +4585,7 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter
else if (command_wrk == (USE_FLOOR))
{
j = floor_top;
- k = MIN(floor_top + 23, floor_num) - 1;
+ k = std::min(floor_top + 23, floor_num) - 1;
/* Extract the legal requests */
n1 = I2A(j - floor_top);
@@ -5016,7 +4690,7 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter
{
case ESCAPE:
{
- done = TRUE;
+ done = true;
break;
}
@@ -5078,7 +4752,7 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter
* is only one item, we will always select it.
* If we aren't examining the floor and there is only
* one item, we will select it if floor_query_flag
- * is FALSE.
+ * is false.
*/
if (floor_num == 1)
{
@@ -5090,14 +4764,14 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter
/* Allow player to "refuse" certain actions */
if (!get_item_allow(k))
{
- done = TRUE;
+ done = true;
break;
}
/* Accept that choice */
(*cp) = k;
- item = TRUE;
- done = TRUE;
+ item = true;
+ done = true;
break;
}
@@ -5147,14 +4821,14 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter
/* Allow player to "refuse" certain actions */
if (!get_item_allow(k))
{
- done = TRUE;
+ done = true;
break;
}
/* Accept that choice */
(*cp) = k;
- item = TRUE;
- done = TRUE;
+ item = true;
+ done = true;
break;
}
@@ -5184,14 +4858,14 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter
/* Allow player to "refuse" certain actions */
if (!get_item_allow(k))
{
- done = TRUE;
+ done = true;
break;
}
/* Accept that choice */
(*cp) = k;
- item = TRUE;
- done = TRUE;
+ item = true;
+ done = true;
}
break;
}
@@ -5206,14 +4880,14 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter
/* Allow player to "refuse" certain actions */
if (!get_item_allow(k))
{
- done = TRUE;
+ done = true;
break;
}
/* Accept that choice */
(*cp) = k;
- item = TRUE;
- done = TRUE;
+ item = true;
+ done = true;
break;
}
@@ -5228,8 +4902,8 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter
if (auto i = select_by_name(filter))
{
(*cp) = *i;
- item = TRUE;
- done = TRUE;
+ item = true;
+ done = true;
}
break;
}
@@ -5293,21 +4967,21 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter
/* Verify the item */
if (ver && !verify("Try", k))
{
- done = TRUE;
+ done = true;
break;
}
/* Allow player to "refuse" certain actions */
if (!get_item_allow(k))
{
- done = TRUE;
+ done = true;
break;
}
/* Accept that choice */
(*cp) = k;
- item = TRUE;
- done = TRUE;
+ item = true;
+ done = true;
break;
}
}
@@ -5359,7 +5033,7 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter
/*
* Let the user select an item, save its "index"
*
- * Return TRUE only if an acceptable item was chosen by the user.
+ * Return true only if an acceptable item was chosen by the user.
*
* The selected item must satisfy the "item_tester_hook()" function,
* if that hook is set, and the "item_tester_tval", if that value is set.
@@ -5383,29 +5057,29 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter
* and prompt for its use.
*
* If a legal item is selected from the inventory, we save it in "cp"
- * directly (0 to 35), and return TRUE.
+ * directly (0 to 35), and return true.
*
* If a legal item is selected from the floor, we save it in "cp" as
- * a negative (-1 to -511), and return TRUE.
+ * a negative (-1 to -511), and return true.
*
* If no item is available, we do nothing to "cp", and we display a
- * warning message, using "str" if available, and return FALSE.
+ * warning message, using "str" if available, and return false.
*
- * If no item is selected, we do nothing to "cp", and return FALSE.
+ * If no item is selected, we do nothing to "cp", and return false.
*
* Global "p_ptr->command_new" is used when viewing the inventory or equipment
* to allow the user to enter a command while viewing those screens, and
* also to induce "auto-enter" of stores, and other such stuff.
*
* Global "p_ptr->command_wrk" is used to choose between equip/inven listings.
- * If it is TRUE then we are viewing inventory, else equipment.
+ * If it is true then we are viewing inventory, else equipment.
*
* We always erase the prompt when we are done, leaving a blank line,
* or a warning message, if appropriate, if no items are available.
*/
-bool_ get_item(int *cp, cptr pmt, cptr str, int mode, object_filter_t const &filter, select_by_name_t const &select_by_name)
+bool get_item(int *cp, const char *pmt, const char *str, int mode, object_filter_t const &filter, select_by_name_t const &select_by_name)
{
- automatizer_create = FALSE;
+ automatizer_create = false;
return get_item_floor(cp, pmt, str, mode, filter, select_by_name);
}
@@ -5414,12 +5088,12 @@ bool_ get_item(int *cp, cptr pmt, cptr str, int mode, object_filter_t const &fil
*/
static bool item_tester_hook_getable(object_type const *o_ptr)
{
- if (!inven_carry_okay(o_ptr)) return (FALSE);
+ if (!inven_carry_okay(o_ptr)) return false;
- if ((o_ptr->tval == TV_HYPNOS) && (!get_skill(SKILL_SYMBIOTIC))) return FALSE;
+ if ((o_ptr->tval == TV_HYPNOS) && (!get_skill(SKILL_SYMBIOTIC))) return false;
/* Assume yes */
- return (TRUE);
+ return true;
}
/*
@@ -5465,10 +5139,6 @@ int wear_ammo(object_type *o_ptr)
{
/* Warn the player */
msg_print("Oops! It feels deathly cold!");
-
- /* Note the curse */
- o_ptr->ident |= (IDENT_SENSE);
- o_ptr->sense = SENSE_CURSED;
}
/* Recalculate bonuses */
@@ -5519,7 +5189,7 @@ void pickup_ammo()
/* Describe the object */
char o_name[80];
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Message */
msg_format("You have %s (%c).", o_name, index_to_label(slot));
@@ -5569,14 +5239,12 @@ void object_pickup(int this_o_idx)
/* Access the item */
o_ptr = &o_list[this_o_idx];
- if (p_ptr->auto_id)
- {
- object_aware(o_ptr);
- object_known(o_ptr);
- }
+ /* Auto-identify */
+ object_aware(o_ptr);
+ object_known(o_ptr);
/* Describe the object */
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Note that the pack is too full */
if (!inven_carry_okay(o_ptr) && !object_similar(o_ptr, &p_ptr->inventory[INVEN_AMMO]))
@@ -5606,7 +5274,7 @@ void object_pickup(int this_o_idx)
}
else
{
- slot = inven_carry(o_ptr, FALSE);
+ slot = inven_carry(o_ptr, false);
}
/* Sanity check */
@@ -5618,16 +5286,13 @@ void object_pickup(int this_o_idx)
object_track(o_ptr);
/* Describe the object */
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Message */
msg_format("You have %s (%c).", o_name, index_to_label(slot));
/* Delete the object */
delete_object_idx(this_o_idx);
-
- /* Sense object. */
- sense_inventory();
}
}
}
@@ -5651,7 +5316,7 @@ static void absorb_gold(cave_type const *c_ptr)
if (o_ptr->tval == TV_GOLD)
{
char goldname[80];
- object_desc(goldname, o_ptr, TRUE, 3);
+ object_desc(goldname, o_ptr, true, 3);
/* Message */
msg_format("You have found %ld gold pieces worth of %s.",
(long)o_ptr->pval, goldname);
@@ -5687,21 +5352,14 @@ static void sense_floor(cave_type const *c_ptr)
}
}
- /* Mega Hack -- If we have auto-Id, do an ID sweep *before* squleching,
- * so that we don't have to walk over things twice to get them
- * squelched. --dsb */
- if (p_ptr->auto_id)
+ // Do an ID sweep *before* squleching so that we don't
+ // have to walk over things twice to get them squelched.
+ for (auto const o_idx: floor_object_idxs)
{
- for (auto const o_idx: floor_object_idxs)
- {
- object_type *o_ptr = get_object(o_idx);
- object_aware(o_ptr);
- object_known(o_ptr);
- }
+ object_type *o_ptr = get_object(o_idx);
+ object_aware(o_ptr);
+ object_known(o_ptr);
}
-
- /* Sense floor tile */
- sense_objects(floor_object_idxs);
}
void py_pickup_floor(int pickup)
@@ -5737,7 +5395,7 @@ void py_pickup_floor(int pickup)
{
/* Describe */
char o_name[80] = "";
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Message */
msg_format("You see %s.", o_name);
@@ -5745,13 +5403,13 @@ void py_pickup_floor(int pickup)
else
{
/* Are we actually going to pick up? */
- bool_ do_pickup = TRUE;
+ bool do_pickup = true;
/* Hack -- query every item */
if (options->carry_query_flag || !can_carry_heavy(&o_list[floor_o_idx]))
{
char o_name[80] = "";
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
if (!inven_carry_okay(o_ptr) && !object_similar(o_ptr, &p_ptr->inventory[INVEN_AMMO]))
{
@@ -5784,19 +5442,19 @@ void py_pickup_floor(int pickup)
else
{
/* Prompt for the item to pick up */
- cptr q = "Get which item? ";
- cptr s = "You have no room in your pack for any of the items here.";
+ const char *q = "Get which item? ";
+ const char *s = "You have no room in your pack for any of the items here.";
int item;
if (get_item(&item, q, s, (USE_FLOOR), item_tester_hook_getable))
{
s16b this_o_idx = 0 - item;
- bool_ do_pickup = TRUE;
+ bool do_pickup = true;
if (!can_carry_heavy(&o_list[this_o_idx]))
{
/* Describe the object */
char o_name[80] = "";
- object_desc(o_name, &o_list[this_o_idx], TRUE, 3);
+ object_desc(o_name, &o_list[this_o_idx], true, 3);
/* Prompt */
char out_val[160];
@@ -5844,7 +5502,7 @@ static void gain_flag_group(object_type *o_ptr)
{
char o_name[80];
- object_desc(o_name, o_ptr, FALSE, 0);
+ object_desc(o_name, o_ptr, false, 0);
msg_format("%s gains access to the %s realm.", o_name, flags_groups()[grp].name);
}
}
@@ -5917,7 +5575,7 @@ static void gain_flag_group_flag(object_type *o_ptr)
// Describe what happened
char o_name[80];
- object_desc(o_name, o_ptr, FALSE, 0);
+ object_desc(o_name, o_ptr, false, 0);
msg_format("%s gains a new power from the %s realm.", o_name, flags_groups()[grp].name);
// We're done.
@@ -5986,12 +5644,12 @@ void object_gain_level(object_type *o_ptr)
/*
* Item sets fcts
*/
-bool_ wield_set(s16b a_idx, s16b set_idx, bool_ silent)
+bool wield_set(s16b a_idx, s16b set_idx, bool silent)
{
auto &set_info = game->edit_data.set_info;
auto const &a_info = game->edit_data.a_info;
- if ( -1 == a_info[a_idx].set) return (FALSE);
+ if ( -1 == a_info[a_idx].set) return false;
auto s_ptr = &set_info[set_idx];
@@ -6007,7 +5665,7 @@ bool_ wield_set(s16b a_idx, s16b set_idx, bool_ silent)
if (!s_ptr->arts[i].present)
{
s_ptr->num_use++;
- s_ptr->arts[i].present = TRUE;
+ s_ptr->arts[i].present = true;
if (s_ptr->num_use > s_ptr->num)
{
msg_print("ERROR!! s_ptr->num_use > s_ptr->use");
@@ -6016,18 +5674,18 @@ bool_ wield_set(s16b a_idx, s16b set_idx, bool_ silent)
{
cmsg_format(TERM_GREEN, "%s item set completed.", s_ptr->name.c_str());
}
- return (TRUE);
+ return true;
}
- return (FALSE);
+ return false;
}
-bool_ takeoff_set(s16b a_idx, s16b set_idx)
+bool takeoff_set(s16b a_idx, s16b set_idx)
{
auto &set_info = game->edit_data.set_info;
auto const &a_info = game->edit_data.a_info;
- if ( -1 == a_info[a_idx].set) return (FALSE);
+ if ( -1 == a_info[a_idx].set) return false;
auto s_ptr = &set_info[set_idx];
@@ -6042,7 +5700,7 @@ bool_ takeoff_set(s16b a_idx, s16b set_idx)
if (s_ptr->arts[i].present)
{
- s_ptr->arts[i].present = FALSE;
+ s_ptr->arts[i].present = false;
assert(s_ptr->num_use > 0);
s_ptr->num_use--;
@@ -6052,10 +5710,10 @@ bool_ takeoff_set(s16b a_idx, s16b set_idx)
cmsg_format(TERM_GREEN, "%s item set not complete anymore.", s_ptr->name.c_str());
}
- return (TRUE);
+ return true;
}
- return (FALSE);
+ return false;
}
void apply_set(s16b a_idx, s16b set_idx)
@@ -6117,81 +5775,87 @@ static void apply_flags_set(s16b a_idx, s16b set_idx, object_flag_set *f)
}
}
-/*
- * Return the "attr" for a given item.
- * Use "flavor" if available.
- * Default to user definitions.
- */
-
byte object_attr(object_type const *o_ptr)
{
- auto const &k_info = game->edit_data.k_info;
auto const &random_artifacts = game->random_artifacts;
+ auto k_ptr = o_ptr->k_ptr;
+
if (o_ptr->tval == TV_RANDART)
{
return random_artifacts[o_ptr->sval].attr;
}
- else if (k_info[o_ptr->k_idx].flavor)
+ else if (!k_ptr)
+ {
+ return 0;
+ }
+ else if (k_ptr->flavor)
{
- return misc_to_attr[k_info[o_ptr->k_idx].flavor];
+ return misc_to_attr[k_ptr->flavor];
}
else
{
- return k_info[o_ptr->k_idx].x_attr;
+ return k_ptr->x_attr;
}
}
-byte object_attr_default(object_type *o_ptr)
+byte object_attr_default(object_type const *o_ptr)
{
- auto const &k_info = game->edit_data.k_info;
auto const &random_artifacts = game->random_artifacts;
+ auto k_ptr = o_ptr->k_ptr;
+
if (o_ptr->tval == TV_RANDART)
{
return random_artifacts[o_ptr->sval].attr;
}
- else if (k_info[o_ptr->k_idx].flavor)
+ else if (!k_ptr)
+ {
+ return 0;
+ }
+ else if (k_ptr->flavor)
{
- return misc_to_attr[k_info[o_ptr->k_idx].flavor];
+ return misc_to_attr[k_ptr->flavor];
}
else
{
- return k_info[o_ptr->k_idx].d_attr;
+ return k_ptr->d_attr;
}
}
-/*
- * Return the "char" for a given item.
- * Use "flavor" if available.
- * Default to user definitions.
- */
-
char object_char(object_type const *o_ptr)
{
- auto const &k_info = game->edit_data.k_info;
+ auto k_ptr = o_ptr->k_ptr;
- if (k_info[o_ptr->k_idx].flavor)
+ if (!k_ptr)
+ {
+ return '\0';
+ }
+ else if (k_ptr->flavor)
{
- return misc_to_char[k_info[o_ptr->k_idx].flavor];
+ return misc_to_char[k_ptr->flavor];
}
else
{
- return k_info[o_ptr->k_idx].x_char;
+ return k_ptr->x_char;
}
}
char object_char_default(object_type const *o_ptr)
{
- auto const &k_info = game->edit_data.k_info;
+ auto k_ptr = o_ptr->k_ptr;
- if (k_info[o_ptr->k_idx].flavor)
+ if (!k_ptr)
{
- return misc_to_char[k_info[o_ptr->k_idx].flavor];
+ return '\0';
+ }
+ else if (k_ptr->flavor)
+ {
+ return misc_to_char[k_ptr->flavor];
}
else
{
- return k_info[o_ptr->k_idx].d_char;
+ return k_ptr->d_char;
}
}
@@ -6200,13 +5864,11 @@ char object_char_default(object_type const *o_ptr)
*/
bool artifact_p(object_type const *o_ptr)
{
- auto const &k_info = game->edit_data.k_info;
-
return
(o_ptr->tval == TV_RANDART) ||
(o_ptr->name1 ? true : false) ||
(!o_ptr->artifact_name.empty()) ||
- ((k_info[o_ptr->k_idx].flags & TR_NORM_ART) ? true : false);
+ ((o_ptr->k_ptr && (o_ptr->k_ptr->flags & TR_NORM_ART)) ? true : false);
}
/**
@@ -6214,7 +5876,7 @@ bool artifact_p(object_type const *o_ptr)
*/
bool ego_item_p(object_type const *o_ptr)
{
- return o_ptr->name2 || (o_ptr->name2b ? TRUE : FALSE);
+ return o_ptr->name2 || (o_ptr->name2b ? true : false);
}
/*
@@ -6226,9 +5888,9 @@ bool is_ego_p(object_type const *o_ptr, s16b ego)
}
/**
- * Is the given object identified as cursed?
+ * Is the given object cursed?
*/
bool cursed_p(object_type const *o_ptr)
{
- return o_ptr->ident & (IDENT_CURSED);
+ return bool(o_ptr->art_flags & TR_CURSED);
}
diff --git a/src/object1.hpp b/src/object1.hpp
index 8b9d6dc9..f02747db 100644
--- a/src/object1.hpp
+++ b/src/object1.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_filter.hpp"
#include "object_flag_set.hpp"
@@ -12,35 +12,35 @@ typedef std::function<boost::optional<int>(object_filter_t const &filter)> selec
byte get_item_letter_color(object_type const *o_ptr);
void object_pickup(int this_o_idx);
void apply_set(s16b a_idx, s16b set_idx);
-bool_ takeoff_set(s16b a_idx, s16b set_idx);
-bool_ wield_set(s16b a_idx, s16b set_idx, bool_ silent);
-bool_ verify(cptr prompt, int item);
+bool takeoff_set(s16b a_idx, s16b set_idx);
+bool wield_set(s16b a_idx, s16b set_idx, bool silent);
+bool verify(const char *prompt, int item);
void flavor_init();
void reset_visuals();
-int object_power(object_type *o_ptr);
-extern bool_ object_flags_no_set;
+boost::optional<int> object_power(object_type *o_ptr);
+extern bool object_flags_no_set;
object_flag_set object_flags(object_type const *o_ptr);
object_flag_set object_flags_known(object_type const *o_ptr);
s32b calc_object_need_exp(object_type const *o_ptr);
void object_desc(char *buf, object_type const *o_ptr, int pref, int mode);
void object_desc_store(char *buf, object_type *o_ptr, int pref, int mode);
-bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait_for_it);
+bool object_out_desc(object_type *o_ptr, FILE *fff, bool trim_down, bool wait_for_it);
char index_to_label(int i);
-s16b wield_slot_ideal(object_type const *o_ptr, bool_ ideal);
+s16b wield_slot_ideal(object_type const *o_ptr, bool ideal);
s16b wield_slot(object_type const *o_ptr);
-cptr describe_use(int i);
+const char *describe_use(int i);
void display_inven();
void display_equip();
void show_inven_full();
void show_equip_full();
void toggle_inven_equip();
-bool_ get_item(int *cp, cptr pmt, cptr str, int mode, object_filter_t const &filter = object_filter::True(), select_by_name_t const &select_by_name = select_by_name_t());
-cptr item_activation(object_type *o_ptr);
+bool get_item(int *cp, const char *pmt, const char *str, int mode, object_filter_t const &filter = object_filter::True(), select_by_name_t const &select_by_name = select_by_name_t());
+const char *item_activation(object_type *o_ptr);
void py_pickup_floor(int pickup);
void object_gain_level(object_type *o_ptr);
byte object_attr(object_type const *o_ptr);
-byte object_attr_default(object_type *o_ptr);
+byte object_attr_default(object_type const *o_ptr);
char object_char(object_type const *o_ptr);
char object_char_default(object_type const *o_ptr);
bool artifact_p(object_type const *o_ptr);
diff --git a/src/object2.cc b/src/object2.cc
index 2d6ea672..600e28a2 100644
--- a/src/object2.cc
+++ b/src/object2.cc
@@ -56,13 +56,15 @@
*/
s32b calc_total_weight()
{
- int i;
s32b total;
- for (i = total = 0; i < INVEN_TOTAL; i++)
+ for (int i = total = 0; i < INVEN_TOTAL; i++)
{
object_type *o_ptr = &p_ptr->inventory[i];
- if (o_ptr->k_idx) total += o_ptr->weight * o_ptr->number;
+ if (o_ptr->k_ptr)
+ {
+ total += o_ptr->weight * o_ptr->number;
+ }
}
return total;
}
@@ -239,10 +241,7 @@ static void compact_objects_aux(int i1, int i2)
*/
void compact_objects(int size)
{
- auto const &k_info = game->edit_data.k_info;
-
int i, y, x, num;
-
int cur_lev, cur_dis, chance;
/* Compact */
@@ -269,11 +268,10 @@ void compact_objects(int size)
for (i = 1; i < o_max; i++)
{
object_type *o_ptr = &o_list[i];
-
- auto k_ptr = &k_info[o_ptr->k_idx];
+ auto const &k_ptr = o_ptr->k_ptr;
/* Skip dead objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr) continue;
/* High level objects are "immune" as long as we're not desperate enough */
if (k_ptr->level > cur_lev) continue;
@@ -352,7 +350,10 @@ void compact_objects(int size)
object_type *o_ptr = &o_list[i];
/* Skip real objects */
- if (o_ptr->k_idx) continue;
+ if (o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Move last object into open hole */
compact_objects_aux(o_max - 1, i);
@@ -364,6 +365,31 @@ void compact_objects(int size)
+/*
+ * Rescue artifacts from destruction if the "preserve" option is
+ * turned on.
+ */
+void rescue_artifact(object_type *o_ptr)
+{
+ auto &a_info = game->edit_data.a_info;
+
+ if (artifact_p(o_ptr) && !object_known_p(o_ptr))
+ {
+ /* Mega-Hack -- Preserve the artifact */
+ if (o_ptr->tval == TV_RANDART)
+ {
+ game->random_artifacts[o_ptr->sval].generated = false;
+ }
+ else if (o_ptr->k_ptr->flags & TR_NORM_ART)
+ {
+ o_ptr->k_ptr->artifact = false;
+ }
+ else
+ {
+ a_info[o_ptr->name1].cur_num = 0;
+ }
+ }
+}
/*
* Delete all the items when player leaves the level
@@ -378,39 +404,21 @@ void compact_objects(int size)
*/
void wipe_o_list()
{
- auto &k_info = game->edit_data.k_info;
- auto &a_info = game->edit_data.a_info;
-
- int i;
-
/* Delete the existing objects */
- for (i = 1; i < o_max; i++)
+ for (int i = 1; i < o_max; i++)
{
object_type *o_ptr = &o_list[i];
/* Skip dead objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Mega-Hack -- preserve artifacts */
if (!character_dungeon || options->preserve)
{
- /* Hack -- Preserve unknown artifacts */
- if (artifact_p(o_ptr) && !object_known_p(o_ptr))
- {
- /* Mega-Hack -- Preserve the artifact */
- if (o_ptr->tval == TV_RANDART)
- {
- game->random_artifacts[o_ptr->sval].generated = FALSE;
- }
- else if (k_info[o_ptr->k_idx].flags & TR_NORM_ART)
- {
- k_info[o_ptr->k_idx].artifact = FALSE;
- }
- else
- {
- a_info[o_ptr->name1].cur_num = 0;
- }
- }
+ rescue_artifact(o_ptr);
}
/* Monster */
@@ -488,7 +496,10 @@ s16b o_pop()
o_ptr = &o_list[i];
/* Skip live objects */
- if (o_ptr->k_idx) continue;
+ if (o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Count objects */
o_cnt++;
@@ -513,12 +524,13 @@ s16b o_pop()
errr get_obj_num_prep()
{
auto &alloc = game->alloc;
+ auto const &k_info = game->edit_data.k_info;
/* Scan the allocation table */
for (auto &&entry: alloc.kind_table)
{
/* Accept objects which pass the restriction, if any */
- if (!get_obj_num_hook || (*get_obj_num_hook)(entry.index))
+ if (!get_object_hook || (*get_object_hook)(k_info.at(entry.index).get()))
{
/* Accept this object */
entry.prob2 = entry.prob1;
@@ -555,12 +567,10 @@ errr get_obj_num_prep()
*/
s16b get_obj_num(int level)
{
- auto const &k_info = game->edit_data.k_info;
auto &alloc = game->alloc;
std::size_t i, j;
int p;
- int k_idx;
long value, total;
@@ -590,15 +600,6 @@ s16b get_obj_num(int level)
/* Default */
entry.prob3 = 0;
- /* Access the index */
- k_idx = entry.index;
-
- /* Access the actual kind */
- auto k_ptr = &k_info[k_idx];
-
- /* Hack -- prevent embedded chests */
- if (opening_chest && (k_ptr->tval == TV_CHEST)) continue;
-
/* Accept */
entry.prob3 = entry.prob2;
@@ -706,18 +707,16 @@ s16b get_obj_num(int level)
*/
void object_known(object_type *o_ptr)
{
+ auto previously_known = object_known_p(o_ptr);
- /* No Sensing */
- o_ptr->sense = SENSE_NONE;
-
- /* Clear the "Felt" info */
- o_ptr->ident &= ~(IDENT_SENSE);
+ /* Mark the item as identified */
+ o_ptr->identified = true;
- /* Clear the "Empty" info */
- o_ptr->ident &= ~(IDENT_EMPTY);
-
- /* Now we know about the item */
- o_ptr->ident |= (IDENT_KNOWN);
+ /* If the status changed, then we invoke the hook */
+ if (!previously_known)
+ {
+ identify_hooks(o_ptr);
+ }
}
@@ -729,10 +728,8 @@ void object_known(object_type *o_ptr)
*/
bool object_known_p(object_type const *o_ptr)
{
- auto const &k_info = game->edit_data.k_info;
-
- return ((o_ptr->ident & (IDENT_KNOWN)) ||
- (k_info[o_ptr->k_idx].easy_know && k_info[o_ptr->k_idx].aware));
+ return (o_ptr->identified ||
+ (o_ptr->k_ptr && o_ptr->k_ptr->easy_know && o_ptr->k_ptr->aware));
}
@@ -742,10 +739,8 @@ bool object_known_p(object_type const *o_ptr)
*/
void object_aware(object_type *o_ptr)
{
- auto &k_info = game->edit_data.k_info;
-
/* Fully aware of the effects */
- k_info[o_ptr->k_idx].aware = TRUE;
+ o_ptr->k_ptr->aware = true;
}
/**
@@ -753,105 +748,10 @@ void object_aware(object_type *o_ptr)
*/
bool object_aware_p(object_type const *o_ptr)
{
- auto const &k_info = game->edit_data.k_info;
-
- return k_info[o_ptr->k_idx].aware;
-}
-
-
-/*
- * Something has been "sampled"
- */
-void object_tried(object_type *o_ptr)
-{
- auto &k_info = game->edit_data.k_info;
-
- /* Mark it as tried (even if "aware") */
- k_info[o_ptr->k_idx].tried = TRUE;
+ return o_ptr->k_ptr && o_ptr->k_ptr->aware;
}
-/**
- * Has the given object been "tried"?
- */
-bool object_tried_p(object_type const *o_ptr)
-{
- auto const &k_info = game->edit_data.k_info;
-
- return k_info[o_ptr->k_idx].tried;
-}
-
-
-/*
- * Return the "value" of an "unknown" item
- * Make a guess at the value of non-aware items
- */
-static s32b object_value_base(object_type const *o_ptr)
-{
- auto const &r_info = game->edit_data.r_info;
- auto const &k_info = game->edit_data.k_info;
-
- auto k_ptr = &k_info[o_ptr->k_idx];
-
- /* Aware item -- use template cost */
- if ((object_aware_p(o_ptr)) && (o_ptr->tval != TV_EGG)) return (k_ptr->cost);
-
- /* Analyze the type */
- switch (o_ptr->tval)
- {
- /* Un-aware Food */
- case TV_FOOD:
- return (5L);
-
- /* Un-aware Potions */
- case TV_POTION2:
- return (20L);
-
- /* Un-aware Potions */
- case TV_POTION:
- return (20L);
-
- /* Un-aware Scrolls */
- case TV_SCROLL:
- return (20L);
-
- /* Un-aware Staffs */
- case TV_STAFF:
- return (70L);
-
- /* Un-aware Wands */
- case TV_WAND:
- return (50L);
-
- /* Un-aware Rods */
- case TV_ROD:
- return (90L);
-
- /* Un-aware Rings */
- case TV_RING:
- return (45L);
-
- /* Un-aware Amulets */
- case TV_AMULET:
- return (45L);
-
- /* Eggs */
- case TV_EGG:
- {
- auto r_ptr = &r_info[o_ptr->pval2];
-
- /* Pay the monster level */
- return (r_ptr->level * 100) + 100;
-
- /* Done */
- break;
- }
- }
-
- /* Paranoia -- Oops */
- return (0L);
-}
-
/* Return the value of the flags the object has... */
s32b flag_cost(object_type const *o_ptr, int plusses)
{
@@ -964,15 +864,15 @@ s32b flag_cost(object_type const *o_ptr, int plusses)
if (flags & TR_DRAIN_EXP) total -= 12500;
if (flags & TR_TELEPORT)
{
- if (o_ptr->ident & IDENT_CURSED)
+ if (o_ptr->art_flags & TR_CURSED)
total -= 7500;
else
total += 250;
}
if (flags & TR_AGGRAVATE) total -= 10000;
if (flags & TR_BLESSED) total += 750;
- if ((flags & TR_CURSED) && (o_ptr->ident & IDENT_CURSED)) total -= 5000;
- if ((flags & TR_HEAVY_CURSE) && (o_ptr->ident & IDENT_CURSED)) total -= 12500;
+ if (flags & TR_CURSED) total -= 5000;
+ if (flags & TR_HEAVY_CURSE) total -= 12500;
if (flags & TR_PERMA_CURSE) total -= 15000;
if (flags & TR_FEATHER) total += 1250;
if (flags & TR_FLY) total += 10000;
@@ -1049,8 +949,6 @@ s32b flag_cost(object_type const *o_ptr, int plusses)
else if (type == ACT_MAP_LIGHT) total += 500;
else if (type == ACT_DETECT_ALL) total += 1000;
else if (type == ACT_DETECT_XTRA) total += 12500;
- else if (type == ACT_ID_FULL) total += 10000;
- else if (type == ACT_ID_PLAIN) total += 1250;
else if (type == ACT_RUNE_EXPLO) total += 4000;
else if (type == ACT_RUNE_PROT) total += 10000;
else if (type == ACT_SATIATE) total += 2000;
@@ -1096,20 +994,22 @@ s32b object_value_real(object_type const *o_ptr)
auto const &a_info = game->edit_data.a_info;
auto const &e_info = game->edit_data.e_info;
- s32b value;
-
- auto k_ptr = &k_info[o_ptr->k_idx];
-
if (o_ptr->tval == TV_RANDART)
{
return game->random_artifacts[o_ptr->sval].cost;
}
+ /* Get the object kind */
+ auto k_ptr = o_ptr->k_ptr;
+
/* Hack -- "worthless" items */
- if (!k_ptr->cost) return (0L);
+ if (!k_ptr->cost)
+ {
+ return (0L);
+ }
/* Base cost */
- value = k_ptr->cost;
+ s32b value = k_ptr->cost;
/* Extract some flags */
auto const flags = object_flags(o_ptr);
@@ -1292,7 +1192,7 @@ s32b object_value_real(object_type const *o_ptr)
if (tip_idx > 0)
{
/* Add its cost */
- value += k_info[tip_idx].cost;
+ value += k_info.at(tip_idx)->cost;
}
/* Done */
@@ -1396,51 +1296,30 @@ s32b object_value_real(object_type const *o_ptr)
* Return the price of an item including plusses (and charges)
*
* This function returns the "value" of the given item (qty one)
- *
- * Never notice "unknown" bonuses or properties, including "curses",
- * since that would give the player information he did not have.
- *
- * Note that discounted items stay discounted forever, even if
- * the discount is "forgotten" by the player via memory loss.
*/
s32b object_value(object_type const *o_ptr)
{
- s32b value;
-
-
- /* Unknown items -- acquire a base value */
- if (object_known_p(o_ptr))
+ /* Cursed items -- worthless */
+ if (cursed_p(o_ptr))
{
- /* Cursed items -- worthless */
- if (cursed_p(o_ptr)) return (0L);
-
- /* Real value (see above) */
- value = object_value_real(o_ptr);
- }
-
- /* Known items -- acquire the actual value */
- else
- {
- /* Hack -- Felt cursed items */
- if ((o_ptr->ident & (IDENT_SENSE)) && cursed_p(o_ptr)) return (0L);
-
- /* Base value (see above) */
- value = object_value_base(o_ptr);
+ return (0L);
}
+ /* Real value */
+ s32b value = object_value_real(o_ptr);
/* Apply discount (if any) */
- if (o_ptr->discount) value -= (value * o_ptr->discount / 100L);
-
+ if (o_ptr->discount)
+ {
+ value -= (value * o_ptr->discount / 100L);
+ }
/* Return the final value */
- return (value);
+ return value;
}
-
-
/*
* Determine if an item can "absorb" a second item
*
@@ -1459,19 +1338,22 @@ s32b object_value(object_type const *o_ptr)
*
* Chests, and activatable items, never stack (for various reasons).
*/
-bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr)
+bool object_similar(object_type const *o_ptr, object_type const *j_ptr)
{
int total = o_ptr->number + j_ptr->number;
+ /* Require identical object types */
+ if (o_ptr->k_ptr != j_ptr->k_ptr)
+ {
+ return false;
+ }
+
/* Extract the flags */
auto const o_flags = object_flags(o_ptr);
auto const j_flags = object_flags(j_ptr);
- /* Require identical object types */
- if (o_ptr->k_idx != j_ptr->k_idx) return (0);
-
if ((o_flags & TR_SPELL_CONTAIN) || (j_flags & TR_SPELL_CONTAIN))
- return FALSE;
+ return false;
/* Analyze the items */
switch (o_ptr->tval)
@@ -1479,65 +1361,58 @@ bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr)
/* School Book */
case TV_BOOK:
{
- if (!object_known_p(o_ptr) || !object_known_p(j_ptr)) return FALSE;
+ if (!object_known_p(o_ptr) || !object_known_p(j_ptr)) return false;
/* Beware artifatcs should not combibne with "lesser" thing */
- if (artifact_p(o_ptr) != artifact_p(j_ptr)) return (FALSE);
+ if (artifact_p(o_ptr) != artifact_p(j_ptr)) return false;
/* Do not combine different ego or normal ones */
- if (ego_item_p(o_ptr) != ego_item_p(j_ptr)) return (FALSE);
+ if (ego_item_p(o_ptr) != ego_item_p(j_ptr)) return false;
/* Random books should stack if they are identical */
if ((o_ptr->sval == 255) && (j_ptr->sval == 255))
{
if (o_ptr->pval != j_ptr->pval)
- return (FALSE);
+ return false;
}
- return (TRUE);
- }
-
- /* Chests */
- case TV_CHEST:
- {
- /* Never okay */
- return (0);
+ return true;
}
case TV_RANDART:
{
- return FALSE;
+ return false;
}
case TV_INSTRUMENT:
{
- return FALSE;
+ return false;
}
case TV_HYPNOS:
case TV_EGG:
{
- return FALSE;
+ return false;
}
/* Totems */
case TV_TOTEM:
{
- if ((o_ptr->pval == j_ptr->pval) && (o_ptr->pval2 == j_ptr->pval2)) return TRUE;
- return FALSE;
+ if ((o_ptr->pval == j_ptr->pval) && (o_ptr->pval2 == j_ptr->pval2)) return true;
+ return false;
}
/* Corpses*/
case TV_CORPSE:
{
- return FALSE;
+ return false;
}
/* Food and Potions and Scrolls */
case TV_POTION:
case TV_POTION2:
{
- if (o_ptr->pval2 != j_ptr->pval2) return FALSE;
+ if (o_ptr->pval2 != j_ptr->pval2) return false;
/* Assume okay */
break;
@@ -1545,40 +1420,37 @@ bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr)
case TV_SCROLL:
{
- if (o_ptr->pval != j_ptr->pval) return FALSE;
- if (o_ptr->pval2 != j_ptr->pval2) return FALSE;
+ if (o_ptr->pval != j_ptr->pval) return false;
+ if (o_ptr->pval2 != j_ptr->pval2) return false;
break;
}
/* Staffs */
case TV_STAFF:
{
- /* Require either knowledge or known empty for both staffs. */
- if ((!(o_ptr->ident & (IDENT_EMPTY)) &&
- !object_known_p(o_ptr)) ||
- (!(j_ptr->ident & (IDENT_EMPTY)) &&
- !object_known_p(j_ptr))) return (0);
+ /* Require knowledge for both staffs. */
+ if ((!object_known_p(o_ptr)) || (!object_known_p(j_ptr))) return (false);
/* Require identical charges, since staffs are bulky. */
- if (o_ptr->pval != j_ptr->pval) return (0);
+ if (o_ptr->pval != j_ptr->pval) return (false);
/* Do not combine recharged ones with non recharged ones. */
- if ((o_flags & TR_RECHARGED) != (j_flags & TR_RECHARGED)) return (0);
+ if ((o_flags & TR_RECHARGED) != (j_flags & TR_RECHARGED)) return (false);
/* Do not combine different spells */
- if (o_ptr->pval2 != j_ptr->pval2) return (0);
+ if (o_ptr->pval2 != j_ptr->pval2) return (false);
/* Do not combine different base levels */
- if (o_ptr->pval3 != j_ptr->pval3) return (0);
+ if (o_ptr->pval3 != j_ptr->pval3) return (false);
/* Beware artifatcs should not combibne with "lesser" thing */
- if (o_ptr->name1 != j_ptr->name1) return (0);
+ if (o_ptr->name1 != j_ptr->name1) return (false);
/* Do not combine different ego or normal ones */
- if (o_ptr->name2 != j_ptr->name2) return (0);
+ if (o_ptr->name2 != j_ptr->name2) return (false);
/* Do not combine different ego or normal ones */
- if (o_ptr->name2b != j_ptr->name2b) return (0);
+ if (o_ptr->name2b != j_ptr->name2b) return (false);
/* Assume okay */
break;
@@ -1587,30 +1459,26 @@ bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr)
/* Wands */
case TV_WAND:
{
-
- /* Require either knowledge or known empty for both wands. */
- if ((!(o_ptr->ident & (IDENT_EMPTY)) &&
- !object_known_p(o_ptr)) ||
- (!(j_ptr->ident & (IDENT_EMPTY)) &&
- !object_known_p(j_ptr))) return (0);
+ /* Require knowledge for both wands. */
+ if ((!object_known_p(o_ptr)) || !object_known_p(j_ptr)) return (false);
/* Beware artifatcs should not combibne with "lesser" thing */
- if (o_ptr->name1 != j_ptr->name1) return (0);
+ if (o_ptr->name1 != j_ptr->name1) return (false);
/* Do not combine recharged ones with non recharged ones. */
- if ((o_flags & TR_RECHARGED) != (j_flags & TR_RECHARGED)) return (0);
+ if ((o_flags & TR_RECHARGED) != (j_flags & TR_RECHARGED)) return (false);
/* Do not combine different spells */
- if (o_ptr->pval2 != j_ptr->pval2) return (0);
+ if (o_ptr->pval2 != j_ptr->pval2) return (false);
/* Do not combine different base levels */
- if (o_ptr->pval3 != j_ptr->pval3) return (0);
+ if (o_ptr->pval3 != j_ptr->pval3) return (false);
/* Do not combine different ego or normal ones */
- if (o_ptr->name2 != j_ptr->name2) return (0);
+ if (o_ptr->name2 != j_ptr->name2) return (false);
/* Do not combine different ego or normal ones */
- if (o_ptr->name2b != j_ptr->name2b) return (0);
+ if (o_ptr->name2b != j_ptr->name2b) return (false);
/* Assume okay */
break;
@@ -1626,7 +1494,7 @@ bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr)
/* Rods */
case TV_ROD_MAIN:
{
- return FALSE;
+ return false;
break;
}
@@ -1659,10 +1527,10 @@ bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr)
case TV_LITE:
{
/* Require full knowledge of both items */
- if (!object_known_p(o_ptr) || !object_known_p(j_ptr)) return (0);
+ if (!object_known_p(o_ptr) || !object_known_p(j_ptr)) return (false);
/* Require identical "turns of light" */
- if (o_ptr->timeout != j_ptr->timeout) return (FALSE);
+ if (o_ptr->timeout != j_ptr->timeout) return false;
/* Fall through */
}
@@ -1673,27 +1541,27 @@ bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr)
case TV_SHOT:
{
/* Require identical knowledge of both items */
- if (object_known_p(o_ptr) != object_known_p(j_ptr)) return (0);
+ if (object_known_p(o_ptr) != object_known_p(j_ptr)) return (false);
/* Require identical "bonuses" */
- if (o_ptr->to_h != j_ptr->to_h) return (FALSE);
- if (o_ptr->to_d != j_ptr->to_d) return (FALSE);
- if (o_ptr->to_a != j_ptr->to_a) return (FALSE);
+ if (o_ptr->to_h != j_ptr->to_h) return false;
+ if (o_ptr->to_d != j_ptr->to_d) return false;
+ if (o_ptr->to_a != j_ptr->to_a) return false;
/* Require identical "pval" code */
- if (o_ptr->pval != j_ptr->pval) return (FALSE);
+ if (o_ptr->pval != j_ptr->pval) return false;
/* Require identical exploding status code */
- if (o_ptr->pval2 != j_ptr->pval2) return (FALSE);
+ if (o_ptr->pval2 != j_ptr->pval2) return false;
/* Require identical "artifact" names */
- if (o_ptr->name1 != j_ptr->name1) return (FALSE);
+ if (o_ptr->name1 != j_ptr->name1) return false;
/* Require identical "ego-item" names */
- if (o_ptr->name2 != j_ptr->name2) return (FALSE);
+ if (o_ptr->name2 != j_ptr->name2) return false;
/* Do not combine different ego or normal ones */
- if (o_ptr->name2b != j_ptr->name2b) return (FALSE);
+ if (o_ptr->name2b != j_ptr->name2b) return false;
/* Hack -- Never stack "powerful" items */
/*
@@ -1701,17 +1569,17 @@ bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr)
-- wilh
*/
/* #if 0 */
- if (o_ptr->xtra1 || j_ptr->xtra1) return (FALSE);
+ if (o_ptr->xtra1 || j_ptr->xtra1) return false;
/* #endif */
/* Hack -- Never stack recharging items */
if ((o_ptr->timeout || j_ptr->timeout) &&
- (o_ptr->tval != TV_LITE)) return (FALSE);
+ (o_ptr->tval != TV_LITE)) return false;
/* Require identical "values" */
- if (o_ptr->ac != j_ptr->ac) return (FALSE);
- if (o_ptr->dd != j_ptr->dd) return (FALSE);
- if (o_ptr->ds != j_ptr->ds) return (FALSE);
+ if (o_ptr->ac != j_ptr->ac) return false;
+ if (o_ptr->dd != j_ptr->dd) return false;
+ if (o_ptr->ds != j_ptr->ds) return false;
/* Probably okay */
break;
@@ -1720,7 +1588,7 @@ bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr)
/* UHH ugly hack for the mushroom quest, sorry */
case TV_FOOD:
{
- if (o_ptr->pval2 != j_ptr->pval2) return (FALSE);
+ if (o_ptr->pval2 != j_ptr->pval2) return false;
break;
}
@@ -1728,7 +1596,7 @@ bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr)
default:
{
/* Require knowledge */
- if (!object_known_p(o_ptr) || !object_known_p(j_ptr)) return (0);
+ if (!object_known_p(o_ptr) || !object_known_p(j_ptr)) return (false);
/* Probably okay */
break;
@@ -1739,24 +1607,21 @@ bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr)
/* Hack -- Identical art_flags! */
if (o_ptr->art_flags != j_ptr->art_flags)
{
- return (0);
+ return (false);
}
- /* Hack -- Require identical "cursed" status */
- if ((o_ptr->ident & (IDENT_CURSED)) != (j_ptr->ident & (IDENT_CURSED))) return (0);
-
/* Hack -- require semi-matching "inscriptions" */
if ((!o_ptr->inscription.empty()) && (!j_ptr->inscription.empty()) && (o_ptr->inscription != j_ptr->inscription))
{
- return (0);
+ return (false);
}
/* Maximal "stacking" limit */
- if (total >= MAX_STACK_SIZE) return (0);
+ if (total >= MAX_STACK_SIZE) return (false);
/* They match, so they must be similar */
- return (TRUE);
+ return true;
}
@@ -1773,17 +1638,6 @@ void object_absorb(object_type *o_ptr, object_type *j_ptr)
/* Hack -- blend "known" status */
if (object_known_p(j_ptr)) object_known(o_ptr);
- /* Hack -- clear "storebought" if only one has it */
- if (((o_ptr->ident & IDENT_STOREB) || (j_ptr->ident & IDENT_STOREB)) &&
- (!((o_ptr->ident & IDENT_STOREB) && (j_ptr->ident & IDENT_STOREB))))
- {
- if (j_ptr->ident & IDENT_STOREB) j_ptr->ident &= 0xEF;
- if (o_ptr->ident & IDENT_STOREB) o_ptr->ident &= 0xEF;
- }
-
- /* Hack -- blend "mental" status */
- if (j_ptr->ident & (IDENT_MENTAL)) o_ptr->ident |= (IDENT_MENTAL);
-
/* Hack -- blend "inscriptions" */
if (!j_ptr->inscription.empty())
{
@@ -1810,12 +1664,12 @@ s16b lookup_kind(int tval, int sval)
{
auto const &k_info = game->edit_data.k_info;
- for (std::size_t k = 1; k < k_info.size(); k++)
+ for (auto const &k_entry: k_info)
{
- auto k_ptr = &k_info[k];
+ auto const &k_ptr = k_entry.second;
if ((k_ptr->tval == tval) && (k_ptr->sval == sval))
{
- return k;
+ return k_entry.first;
}
}
@@ -1851,7 +1705,7 @@ void object_copy(object_type *o_ptr, object_type *j_ptr)
* Initialize the experience of an object which is a
* "sentient" object.
*/
-static void init_obj_exp(object_type *o_ptr, object_kind const *k_ptr)
+static void init_obj_exp(object_type *o_ptr, std::shared_ptr<object_kind const> k_ptr)
{
o_ptr->elevel = (k_ptr->level / 10) + 1;
o_ptr->exp = player_exp[o_ptr->elevel - 1];
@@ -1864,14 +1718,13 @@ static void init_obj_exp(object_type *o_ptr, object_kind const *k_ptr)
void object_prep(object_type *o_ptr, int k_idx)
{
auto const &k_info = game->edit_data.k_info;
-
- auto k_ptr = &k_info[k_idx];
+ auto k_ptr = k_info.at(k_idx);
/* Clear the record */
object_wipe(o_ptr);
/* Save the kind index */
- o_ptr->k_idx = k_idx;
+ o_ptr->k_ptr = k_ptr;
/* Efficiency -- tval/sval */
o_ptr->tval = k_ptr->tval;
@@ -1900,7 +1753,7 @@ void object_prep(object_type *o_ptr, int k_idx)
/* Hack -- cursed items are always "cursed" */
if (k_ptr->flags & TR_CURSED)
{
- o_ptr->ident |= (IDENT_CURSED);
+ o_ptr->art_flags |= TR_CURSED;
}
/* Hack give a basic exp/exp level to an object that needs it */
@@ -2023,7 +1876,7 @@ static void finalize_randart(object_type* o_ptr, int lev)
o_ptr->xtra2 = activation_info[ra_ptr->activation].spell;
ra_ptr->level = lev;
- ra_ptr->generated = TRUE;
+ ra_ptr->generated = true;
return;
}
}
@@ -2039,7 +1892,7 @@ static void object_mention(object_type *o_ptr)
char o_name[80];
/* Describe */
- object_desc_store(o_name, o_ptr, FALSE, 0);
+ object_desc_store(o_name, o_ptr, false, 0);
/* Artifact */
if (artifact_p(o_ptr))
@@ -2075,7 +1928,7 @@ static void random_artifact_power(object_type *o_ptr)
auto flags = &o_ptr->art_flags;
// Choose ability
- auto try_choose = [&o_ptr, &flags](int choice) {
+ auto try_choose = [&flags](int choice) {
switch (choice)
{
case 0:
@@ -2181,13 +2034,13 @@ void random_artifact_resistance(object_type * o_ptr)
*
* Note -- see "make_artifact()" and "apply_magic()"
*/
-static bool_ make_artifact_special(object_type *o_ptr)
+static bool make_artifact_special(object_type *o_ptr)
{
auto const &k_info = game->edit_data.k_info;
auto const &a_info = game->edit_data.a_info;
/* No artifacts in the town */
- if (!dun_level) return (FALSE);
+ if (!dun_level) return false;
/* Check the artifact list (just the "specials") */
for (std::size_t i = 0; i < a_info.size(); i++)
@@ -2221,12 +2074,13 @@ static bool_ make_artifact_special(object_type *o_ptr)
/* Find the base object */
int k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
+ auto const &k_ptr = k_info.at(k_idx);
/* XXX XXX Enforce minimum "object" level (loosely) */
- if (k_info[k_idx].level > object_level)
+ if (k_ptr->level > object_level)
{
/* Acquire the "out-of-depth factor" */
- int d = (k_info[k_idx].level - object_level) * 5;
+ int d = (k_ptr->level - object_level) * 5;
/* Roll for out-of-depth creation */
if (rand_int(d) != 0) continue;
@@ -2244,15 +2098,15 @@ static bool_ make_artifact_special(object_type *o_ptr)
/* Hack give a basic exp/exp level to an object that needs it */
if (flags & TR_LEVELS)
{
- init_obj_exp(o_ptr, &k_info[k_idx]);
+ init_obj_exp(o_ptr, k_ptr);
}
/* Success */
- return (TRUE);
+ return true;
}
/* Failure */
- return (FALSE);
+ return false;
}
@@ -2263,16 +2117,15 @@ static bool_ make_artifact_special(object_type *o_ptr)
*
* Note -- see "make_artifact_special()" and "apply_magic()"
*/
-static bool_ make_artifact(object_type *o_ptr)
+static bool make_artifact(object_type *o_ptr)
{
auto const &a_info = game->edit_data.a_info;
- auto const &k_info = game->edit_data.k_info;
/* No artifacts in the town */
- if (!dun_level) return (FALSE);
+ if (!dun_level) return false;
/* Paranoia -- no "plural" artifacts */
- if (o_ptr->number != 1) return (FALSE);
+ if (o_ptr->number != 1) return false;
/* Check the artifact list (skip the "specials") */
for (std::size_t i = 0; i < a_info.size(); i++)
@@ -2320,15 +2173,15 @@ static bool_ make_artifact(object_type *o_ptr)
/* Hack give a basic exp/exp level to an object that needs it */
if (flags & TR_LEVELS)
{
- init_obj_exp(o_ptr, &k_info[o_ptr->k_idx]);
+ init_obj_exp(o_ptr, o_ptr->k_ptr);
}
/* Success */
- return (TRUE);
+ return true;
}
/* Failure */
- return (FALSE);
+ return false;
}
/*
@@ -2336,15 +2189,13 @@ static bool_ make_artifact(object_type *o_ptr)
*
* This routine should only be called by "apply_magic()"
*/
-static bool_ make_ego_item(object_type *o_ptr, bool_ good)
+static bool make_ego_item(object_type *o_ptr, bool good)
{
- auto const &k_info = game->edit_data.k_info;
auto const &e_info = game->edit_data.e_info;
- bool_ ret = FALSE;
- auto k_ptr = &k_info[o_ptr->k_idx];
+ bool ret = false;
- if (artifact_p(o_ptr) || o_ptr->name2) return (FALSE);
+ if (artifact_p(o_ptr) || o_ptr->name2) return false;
std::vector<size_t> ok_ego;
@@ -2352,17 +2203,20 @@ static bool_ make_ego_item(object_type *o_ptr, bool_ good)
for (size_t i = 0; i < e_info.size(); i++)
{
auto e_ptr = &e_info[i];
- bool_ ok = FALSE;
+ bool ok = false;
/* Skip "empty" items */
- if (!e_ptr->name) continue;
+ if (e_ptr->name.empty())
+ {
+ continue;
+ }
/* Must have the correct fields */
for (size_t j = 0; j < 6; j++)
{
if (e_ptr->tval[j] == o_ptr->tval)
{
- if ((e_ptr->min_sval[j] <= o_ptr->sval) && (e_ptr->max_sval[j] >= o_ptr->sval)) ok = TRUE;
+ if ((e_ptr->min_sval[j] <= o_ptr->sval) && (e_ptr->max_sval[j] >= o_ptr->sval)) ok = true;
}
if (ok) break;
@@ -2378,10 +2232,15 @@ static bool_ make_ego_item(object_type *o_ptr, bool_ good)
if ((!good) && e_ptr->cost) continue;
/* Must posses the good flags */
+ auto k_ptr = o_ptr->k_ptr;
if ((k_ptr->flags & e_ptr->need_flags) != e_ptr->need_flags)
+ {
continue;
+ }
if (k_ptr->flags & e_ptr->forbid_flags)
+ {
continue;
+ }
/* ok */
ok_ego.push_back(i);
@@ -2416,7 +2275,7 @@ static bool_ make_ego_item(object_type *o_ptr, bool_ good)
o_ptr->name2 = j;
/* Success */
- ret = TRUE;
+ ret = true;
break;
}
@@ -2462,7 +2321,7 @@ static bool_ make_ego_item(object_type *o_ptr, bool_ good)
o_ptr->name2b = j;
/* Success */
- ret = TRUE;
+ ret = true;
break;
}
}
@@ -2502,13 +2361,13 @@ static void a_m_aux_1(object_type *o_ptr, int level, int power)
if (power > 1)
{
/* Make ego item */
- if (rand_int(RANDART_WEAPON) == 1) create_artifact(o_ptr, FALSE, TRUE);
- else make_ego_item(o_ptr, TRUE);
+ if (rand_int(RANDART_WEAPON) == 1) create_artifact(o_ptr, false, true);
+ else make_ego_item(o_ptr, true);
}
else if (power < -1)
{
/* Make ego item */
- make_ego_item(o_ptr, FALSE);
+ make_ego_item(o_ptr, false);
}
/* Good */
@@ -2543,7 +2402,10 @@ static void a_m_aux_1(object_type *o_ptr, int level, int power)
}
/* Cursed (if "bad") */
- if (o_ptr->to_h + o_ptr->to_d < 0) o_ptr->ident |= (IDENT_CURSED);
+ if (o_ptr->to_h + o_ptr->to_d < 0)
+ {
+ o_ptr->art_flags |= TR_CURSED;
+ }
}
/* Some special cases */
@@ -2615,13 +2477,13 @@ static void a_m_aux_2(object_type *o_ptr, int level, int power)
if (power > 1)
{
/* Make ego item */
- if (rand_int(RANDART_ARMOR) == 1) create_artifact(o_ptr, FALSE, TRUE);
- else make_ego_item(o_ptr, TRUE);
+ if (rand_int(RANDART_ARMOR) == 1) create_artifact(o_ptr, false, true);
+ else make_ego_item(o_ptr, true);
}
else if (power < -1)
{
/* Make ego item */
- make_ego_item(o_ptr, FALSE);
+ make_ego_item(o_ptr, false);
}
/* Good */
@@ -2652,7 +2514,10 @@ static void a_m_aux_2(object_type *o_ptr, int level, int power)
}
/* Cursed (if "bad") */
- if (o_ptr->to_a < 0) o_ptr->ident |= (IDENT_CURSED);
+ if (o_ptr->to_a < 0)
+ {
+ o_ptr->art_flags |= TR_CURSED;
+ }
}
/* Analyze type */
@@ -2666,7 +2531,7 @@ static void a_m_aux_2(object_type *o_ptr, int level, int power)
}
else if (o_ptr->sval == SV_MIMIC_CLOAK)
{
- s32b mimic = find_random_mimic_shape(level, TRUE);
+ s32b mimic = find_random_mimic_shape(level, true);
o_ptr->pval2 = mimic;
}
break;
@@ -2738,13 +2603,13 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
if (power > 1)
{
/* Make ego item */
- if (rand_int(RANDART_JEWEL) == 1) create_artifact(o_ptr, FALSE, TRUE);
- else make_ego_item(o_ptr, TRUE);
+ if (rand_int(RANDART_JEWEL) == 1) create_artifact(o_ptr, false, true);
+ else make_ego_item(o_ptr, true);
}
else if (power < -1)
{
/* Make ego item */
- make_ego_item(o_ptr, FALSE);
+ make_ego_item(o_ptr, false);
}
/* Apply magic (good or bad) according to type */
@@ -2766,7 +2631,7 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
if (power < 0)
{
/* Cursed */
- o_ptr->ident |= (IDENT_CURSED);
+ o_ptr->art_flags |= TR_CURSED;
/* Reverse pval */
o_ptr->pval = 0 - (o_ptr->pval);
@@ -2786,7 +2651,7 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
if (power < 0)
{
/* Cursed */
- o_ptr->ident |= (IDENT_CURSED);
+ o_ptr->art_flags |= TR_CURSED;
/* Reverse pval */
o_ptr->pval = 0 - (o_ptr->pval);
@@ -2808,7 +2673,7 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
if (power < 0)
{
/* Cursed */
- o_ptr->ident |= (IDENT_CURSED);
+ o_ptr->art_flags |= TR_CURSED;
/* Reverse pval */
o_ptr->pval = 0 - (o_ptr->pval);
@@ -2830,7 +2695,7 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
if (power < 0)
{
/* Cursed */
- o_ptr->ident |= (IDENT_CURSED);
+ o_ptr->art_flags |= TR_CURSED;
/* Reverse pval */
o_ptr->pval = 0 - (o_ptr->pval);
@@ -2879,7 +2744,7 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
case SV_RING_STUPIDITY:
{
/* Cursed */
- o_ptr->ident |= (IDENT_CURSED);
+ o_ptr->art_flags |= TR_CURSED;
/* Penalize */
o_ptr->pval = 0 - (1 + m_bonus(5, level));
@@ -2891,7 +2756,7 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
case SV_RING_WOE:
{
/* Cursed */
- o_ptr->ident |= (IDENT_CURSED);
+ o_ptr->art_flags |= TR_CURSED;
/* Penalize */
o_ptr->to_a = 0 - (5 + m_bonus(10, level));
@@ -2910,7 +2775,7 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
if (power < 0)
{
/* Cursed */
- o_ptr->ident |= (IDENT_CURSED);
+ o_ptr->art_flags |= TR_CURSED;
/* Reverse bonus */
o_ptr->to_d = 0 - (o_ptr->to_d);
@@ -2929,7 +2794,7 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
if (power < 0)
{
/* Cursed */
- o_ptr->ident |= (IDENT_CURSED);
+ o_ptr->art_flags |= TR_CURSED;
/* Reverse tohit */
o_ptr->to_h = 0 - (o_ptr->to_h);
@@ -2948,7 +2813,7 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
if (power < 0)
{
/* Cursed */
- o_ptr->ident |= (IDENT_CURSED);
+ o_ptr->art_flags |= TR_CURSED;
/* Reverse toac */
o_ptr->to_a = 0 - (o_ptr->to_a);
@@ -2968,7 +2833,7 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
if (power < 0)
{
/* Cursed */
- o_ptr->ident |= (IDENT_CURSED);
+ o_ptr->art_flags |= TR_CURSED;
/* Reverse bonuses */
o_ptr->to_h = 0 - (o_ptr->to_h);
@@ -3028,7 +2893,7 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
if (power < 0)
{
/* Cursed */
- o_ptr->ident |= (IDENT_CURSED);
+ o_ptr->art_flags |= TR_CURSED;
/* Reverse bonuses */
o_ptr->pval = 0 - (o_ptr->pval);
@@ -3047,7 +2912,7 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
if (power < 0)
{
/* Cursed */
- o_ptr->ident |= (IDENT_CURSED);
+ o_ptr->art_flags |= TR_CURSED;
/* Reverse bonuses */
o_ptr->pval = 0 - (o_ptr->pval);
@@ -3061,7 +2926,7 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
{
if (power < 0)
{
- o_ptr->ident |= (IDENT_CURSED);
+ o_ptr->art_flags |= TR_CURSED;
}
break;
}
@@ -3096,7 +2961,7 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
case SV_AMULET_DOOM:
{
/* Cursed */
- o_ptr->ident |= (IDENT_CURSED);
+ o_ptr->art_flags |= TR_CURSED;
/* Penalize */
o_ptr->pval = 0 - (randint(5) + m_bonus(5, level));
@@ -3163,22 +3028,26 @@ static int get_stick_max_level(byte tval, int level, int spl)
static void a_m_aux_4(object_type *o_ptr, int level, int power)
{
auto const &r_info = game->edit_data.r_info;
- auto const &k_info = game->edit_data.k_info;
s32b bonus_lvl, max_lvl;
- auto k_ptr = &k_info[o_ptr->k_idx];
/* Very good */
if (power > 1)
{
/* Make ego item */
- if ((rand_int(RANDART_JEWEL) == 1) && (o_ptr->tval == TV_LITE)) create_artifact(o_ptr, FALSE, TRUE);
- else make_ego_item(o_ptr, TRUE);
+ if ((rand_int(RANDART_JEWEL) == 1) && (o_ptr->tval == TV_LITE))
+ {
+ create_artifact(o_ptr, false, true);
+ }
+ else
+ {
+ make_ego_item(o_ptr, true);
+ }
}
else if (power < -1)
{
/* Make ego item */
- make_ego_item(o_ptr, FALSE);
+ make_ego_item(o_ptr, false);
}
/* Apply magic (good or bad) according to type */
@@ -3218,9 +3087,9 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power)
/* Hack -- random fuel */
if (flags & TR_FUEL_LITE)
{
- if (k_info[o_ptr->k_idx].pval2 > 0)
+ if (o_ptr->k_ptr->pval2 > 0)
{
- o_ptr->timeout = randint(k_info[o_ptr->k_idx].pval2);
+ o_ptr->timeout = randint(o_ptr->k_ptr->pval2);
}
}
@@ -3250,7 +3119,7 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power)
{
/* Hack -- choose a monster */
int r_idx, count = 0;
- bool_ OK = FALSE;
+ bool OK = false;
while ((!OK) && (count < 1000))
{
@@ -3260,7 +3129,7 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power)
if (r_ptr->flags & RF_HAS_EGG)
{
o_ptr->pval2 = r_idx;
- OK = TRUE;
+ OK = true;
}
count++;
}
@@ -3299,6 +3168,8 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power)
case TV_WAND:
{
+ auto k_ptr = o_ptr->k_ptr;
+
/* Decide the spell, pval == -1 means to bypass spell selection */
if (o_ptr->pval != -1)
{
@@ -3329,6 +3200,8 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power)
case TV_STAFF:
{
+ auto k_ptr = o_ptr->k_ptr;
+
/* Decide the spell, pval == -1 means to bypass spell selection */
if (o_ptr->pval != -1)
{
@@ -3358,16 +3231,6 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power)
break;
}
- case TV_CHEST:
- {
- /* Hack -- skip ruined chests */
- if (k_info[o_ptr->k_idx].level <= 0) break;
-
- /* Hack - set pval2 to the number of objects in it */
- if (o_ptr->pval)
- o_ptr->pval2 = (o_ptr->sval % SV_CHEST_MIN_LARGE) * 2;
- break;
- }
case TV_POTION:
if (o_ptr->sval == SV_POTION_BLOOD)
{
@@ -3383,7 +3246,7 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power)
case TV_POTION2:
if (o_ptr->sval == SV_POTION2_MIMIC)
{
- s32b mimic = find_random_mimic_shape(level, FALSE);
+ s32b mimic = find_random_mimic_shape(level, false);
o_ptr->pval2 = mimic;
}
break;
@@ -3426,7 +3289,7 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power)
}
/* Add a random glag to the ego item */
-void add_random_ego_flag(object_type *o_ptr, ego_flag_set const &fego, bool_ *limit_blows)
+void add_random_ego_flag(object_type *o_ptr, ego_flag_set const &fego, bool *limit_blows)
{
if (fego & ETR_SUSTAIN)
{
@@ -3858,21 +3721,22 @@ void add_random_ego_flag(object_type *o_ptr, ego_flag_set const &fego, bool_ *li
* "good" and "great" arguments are false. As a total hack, if "great" is
* true, then the item gets 3 extra "attempts" to become an artifact.
*/
-void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ great, boost::optional<int> force_power)
+void apply_magic(object_type *o_ptr, int lev, bool okay, bool good, bool great, boost::optional<int> force_power)
{
- auto &k_info = game->edit_data.k_info;
auto &a_info = game->edit_data.a_info;
auto const &e_info = game->edit_data.e_info;
int i, rolls;
- auto k_ptr = &k_info[o_ptr->k_idx];
+ auto k_ptr = o_ptr->k_ptr;
/* Aply luck */
lev += luck( -7, 7);
/* Spell in it? No! */
if (k_ptr->flags & TR_SPELL_CONTAIN)
+ {
o_ptr->pval2 = -1;
+ }
/* Important to do before all else, be sure to have the basic obvious flags set */
o_ptr->art_oflags = k_ptr->oflags;
@@ -3883,7 +3747,7 @@ void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ grea
/* Ahah! we tried to trick us !! */
if (k_ptr->artifact ||
((k_ptr->flags & TR_SPECIAL_GENE) &&
- (!k_allow_special[o_ptr->k_idx])))
+ (!k_ptr->allow_special)))
{
object_prep(o_ptr, lookup_kind(k_ptr->btval, k_ptr->bsval));
if (wizard) msg_print("We've been tricked!");
@@ -3910,7 +3774,7 @@ void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ grea
charge_stick(o_ptr);
}
- k_ptr->artifact = TRUE;
+ k_ptr->artifact = true;
if (options->cheat_peek || p_ptr->precognition)
{
@@ -3985,7 +3849,10 @@ void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ grea
for (i = 0; i < rolls; i++)
{
/* Roll for an artifact */
- if (make_artifact(o_ptr)) break;
+ if (make_artifact(o_ptr))
+ {
+ break;
+ }
}
/* Mega hack -- to lazy to do it properly with hooks :) */
@@ -4017,9 +3884,6 @@ void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ grea
o_ptr->weight = a_ptr->weight;
o_ptr->number = 1;
- /* Hack -- extract the "cursed" flag */
- if (a_ptr->flags & TR_CURSED) o_ptr->ident |= (IDENT_CURSED);
-
/* Mega-Hack -- increase the rating */
rating += 10;
@@ -4027,7 +3891,7 @@ void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ grea
if (a_ptr->cost > 50000L) rating += 10;
/* Set the good item flag */
- good_item_flag = TRUE;
+ good_item_flag = true;
/* Cheat -- peek at the item */
if (options->cheat_peek || p_ptr->precognition)
@@ -4125,7 +3989,7 @@ void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ grea
else if (o_ptr->name2)
{
int j;
- bool_ limit_blows = FALSE;
+ bool limit_blows = false;
s16b e_idx;
e_idx = o_ptr->name2;
@@ -4155,9 +4019,6 @@ try_an_other_ego:
/* get flags */
auto const flags = object_flags(o_ptr);
- /* Hack -- acquire "cursed" flag */
- if (flags & TR_CURSED) o_ptr->ident |= (IDENT_CURSED);
-
/* Hack -- obtain bonuses */
if (e_ptr->max_to_h > 0) o_ptr->to_h += randint(e_ptr->max_to_h);
if (e_ptr->max_to_h < 0) o_ptr->to_h -= randint( -e_ptr->max_to_h);
@@ -4194,12 +4055,15 @@ try_an_other_ego:
/* Examine real objects */
- if (o_ptr->k_idx)
+ if (o_ptr->k_ptr)
{
- object_kind *k_ptr = &k_info[o_ptr->k_idx];
+ auto k_ptr = o_ptr->k_ptr;
/* Hack -- acquire "cursed" flag */
- if (k_ptr->flags & TR_CURSED) o_ptr->ident |= (IDENT_CURSED);
+ if (k_ptr->flags & TR_CURSED)
+ {
+ o_ptr->art_flags |= TR_CURSED;
+ }
/* Extract some flags */
auto const flags = object_flags(o_ptr);
@@ -4262,14 +4126,10 @@ bool init_match_theme(obj_theme const &theme)
/*
* Maga-Hack -- match certain types of object only.
*/
-static bool kind_is_theme(obj_theme const *theme, int k_idx)
+static bool kind_is_theme(obj_theme const *theme, object_kind const *k_ptr)
{
- auto const &k_info = game->edit_data.k_info;
-
assert(theme != nullptr);
- auto k_ptr = &k_info[k_idx];
-
s32b prob = 0;
/*
@@ -4280,7 +4140,7 @@ static bool kind_is_theme(obj_theme const *theme, int k_idx)
*/
if (theme->treasure + theme->combat + theme->magic + theme->tools == 0)
{
- return TRUE;
+ return true;
}
@@ -4304,9 +4164,6 @@ static bool kind_is_theme(obj_theme const *theme, int k_idx)
theme->magic + theme->tools);
break;
}
- case TV_CHEST:
- prob = theme->treasure;
- break;
case TV_CROWN:
prob = theme->treasure;
break;
@@ -4439,68 +4296,67 @@ static bool kind_is_theme(obj_theme const *theme, int k_idx)
}
/* Roll to see if it can be made */
- if (rand_int(100) < prob) return (TRUE);
+ if (rand_int(100) < prob)
+ {
+ return true;
+ }
/* Not a match */
- return (FALSE);
+ return false;
}
/*
* Determine if an object must not be generated.
*/
-bool_ kind_is_legal(int k_idx)
+bool kind_is_legal(object_kind const *k_ptr)
{
- auto const &k_info = game->edit_data.k_info;
-
- auto k_ptr = &k_info[k_idx];
-
- if (!kind_is_theme(match_theme, k_idx)) return FALSE;
+ if (!kind_is_theme(match_theme, k_ptr))
+ {
+ return false;
+ }
if (k_ptr->flags & TR_SPECIAL_GENE)
{
- if (k_allow_special[k_idx]) return TRUE;
- else return FALSE;
+ return k_ptr->allow_special;
}
/* No 2 times the same normal artifact */
if ((k_ptr->flags & TR_NORM_ART) && (k_ptr->artifact))
{
- return FALSE;
+ return false;
}
if (k_ptr->tval == TV_CORPSE)
{
- if (k_ptr->sval != SV_CORPSE_SKULL && k_ptr->sval != SV_CORPSE_SKELETON &&
- k_ptr->sval != SV_CORPSE_HEAD && k_ptr->sval != SV_CORPSE_CORPSE)
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
+ return (k_ptr->sval != SV_CORPSE_SKULL && k_ptr->sval != SV_CORPSE_SKELETON &&
+ k_ptr->sval != SV_CORPSE_HEAD && k_ptr->sval != SV_CORPSE_CORPSE);
}
- if (k_ptr->tval == TV_HYPNOS) return FALSE;
+ if (k_ptr->tval == TV_HYPNOS)
+ {
+ return false;
+ }
/* Used only for the Nazgul rings */
- if ((k_ptr->tval == TV_RING) && (k_ptr->sval == SV_RING_SPECIAL)) return FALSE;
+ if ((k_ptr->tval == TV_RING) && (k_ptr->sval == SV_RING_SPECIAL))
+ {
+ return false;
+ }
/* Assume legal */
- return TRUE;
+ return true;
}
/*
* Hack -- determine if a template is "good"
*/
-static bool_ kind_is_good(int k_idx)
+static bool kind_is_good(object_kind const *k_ptr)
{
- auto const &k_info = game->edit_data.k_info;
-
- auto k_ptr = &k_info[k_idx];
-
- if (!kind_is_legal(k_idx)) return FALSE;
+ if (!kind_is_legal(k_ptr))
+ {
+ return false;
+ }
/* Analyze the item type */
switch (k_ptr->tval)
@@ -4516,8 +4372,7 @@ static bool_ kind_is_good(int k_idx)
case TV_HELM:
case TV_CROWN:
{
- if (k_ptr->to_a < 0) return (FALSE);
- return (TRUE);
+ return k_ptr->to_a >= 0;
}
/* Weapons -- Good unless damaged */
@@ -4530,74 +4385,68 @@ static bool_ kind_is_good(int k_idx)
case TV_MSTAFF:
case TV_BOOMERANG:
{
- if (k_ptr->to_h < 0) return (FALSE);
- if (k_ptr->to_d < 0) return (FALSE);
- return (TRUE);
+ if (k_ptr->to_h < 0) return false;
+ if (k_ptr->to_d < 0) return false;
+ return true;
}
/* Ammo -- Arrows/Bolts are good */
case TV_BOLT:
case TV_ARROW:
{
- return (TRUE);
+ return true;
}
/* Rods - Silver and better are good */
case TV_ROD_MAIN:
{
- if (k_ptr->sval >= SV_ROD_SILVER) return (TRUE);
- return FALSE;
+ return (k_ptr->sval >= SV_ROD_SILVER);
}
/* Expensive rod tips are good */
case TV_ROD:
{
- if (k_ptr->cost >= 4500) return TRUE;
- return FALSE;
+ return (k_ptr->cost >= 4500);
}
/* The Tomes are good */
case TV_BOOK:
{
- if (k_ptr->sval <= SV_BOOK_MAX_GOOD) return (TRUE);
- return FALSE;
+ return (k_ptr->sval <= SV_BOOK_MAX_GOOD);
}
/* Rings -- Rings of Speed are good */
case TV_RING:
{
- if (k_ptr->sval == SV_RING_SPEED) return (TRUE);
- return (FALSE);
+ return (k_ptr->sval == SV_RING_SPEED);
}
/* Amulets -- Some are good */
case TV_AMULET:
{
- if (k_ptr->sval == SV_AMULET_THE_MAGI) return (TRUE);
- if (k_ptr->sval == SV_AMULET_DEVOTION) return (TRUE);
- if (k_ptr->sval == SV_AMULET_WEAPONMASTERY) return (TRUE);
- if (k_ptr->sval == SV_AMULET_TRICKERY) return (TRUE);
- if (k_ptr->sval == SV_AMULET_RESISTANCE) return (TRUE);
- if (k_ptr->sval == SV_AMULET_REFLECTION) return (TRUE);
- if (k_ptr->sval == SV_AMULET_TELEPATHY) return (TRUE);
- return (FALSE);
+ if (k_ptr->sval == SV_AMULET_THE_MAGI) return true;
+ if (k_ptr->sval == SV_AMULET_DEVOTION) return true;
+ if (k_ptr->sval == SV_AMULET_WEAPONMASTERY) return true;
+ if (k_ptr->sval == SV_AMULET_TRICKERY) return true;
+ if (k_ptr->sval == SV_AMULET_RESISTANCE) return true;
+ if (k_ptr->sval == SV_AMULET_REFLECTION) return true;
+ if (k_ptr->sval == SV_AMULET_TELEPATHY) return true;
+ return false;
}
}
/* Assume not good */
- return (FALSE);
+ return false;
}
/*
* Determine if template is suitable for building a randart -- dsb
*/
-bool_ kind_is_artifactable(int k_idx)
+bool kind_is_artifactable(object_kind const *k_ptr)
{
auto const &ra_info = game->edit_data.ra_info;
- auto const &k_info = game->edit_data.k_info;
- auto k_ptr = &k_info[k_idx];
- if (kind_is_good(k_idx))
+ if (kind_is_good(k_ptr))
{
// Consider the item artifactable if there is at least one
// randart power which could be added to the item.
@@ -4608,13 +4457,13 @@ bool_ kind_is_artifactable(int k_idx)
if (filter.tval != k_ptr->tval) continue;
if (filter.min_sval > k_ptr->sval) continue;
if (filter.max_sval < k_ptr->sval) continue;
- return TRUE;
+ return true;
}
}
}
/* No match. Too bad. */
- return FALSE;
+ return false;
}
@@ -4632,14 +4481,12 @@ bool_ kind_is_artifactable(int k_idx)
* through the forge--object_prep()--apply_magic() sequence and
* get_obj_num() should never be called for that purpose XXX XXX XXX
*/
-bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const &theme)
+bool make_object(object_type *j_ptr, bool good, bool great, obj_theme const &theme)
{
- auto const &k_info = game->edit_data.k_info;
auto &alloc = game->alloc;
int invprob, base;
-
/* Chance of "special object" */
invprob = (good ? 10 - luck( -9, 9) : 1000);
@@ -4661,7 +4508,7 @@ bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const &
if (good)
{
/* Activate restriction */
- get_obj_num_hook = kind_is_good;
+ get_object_hook = kind_is_good;
/* Prepare allocation table */
get_obj_num_prep();
@@ -4671,7 +4518,7 @@ bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const &
else if (!alloc.kind_table_valid)
{
/* Activate normal restriction */
- get_obj_num_hook = kind_is_legal;
+ get_object_hook = kind_is_legal;
/* Prepare allocation table */
get_obj_num_prep();
@@ -4687,7 +4534,7 @@ bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const &
if (good)
{
/* Restore normal restriction */
- get_obj_num_hook = kind_is_legal;
+ get_object_hook = kind_is_legal;
/* Prepare allocation table */
get_obj_num_prep();
@@ -4697,14 +4544,14 @@ bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const &
}
/* Handle failure */
- if (!k_idx) return (FALSE);
+ if (!k_idx) return false;
/* Prepare the object */
object_prep(j_ptr, k_idx);
}
/* Apply magic (allow artifacts) */
- apply_magic(j_ptr, object_level, TRUE, good, great);
+ apply_magic(j_ptr, object_level, true, good, great);
/* Hack -- generate multiple spikes/missiles */
switch (j_ptr->tval)
@@ -4719,14 +4566,17 @@ bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const &
}
/* hack, no multiple artifacts */
- if (artifact_p(j_ptr)) j_ptr->number = 1;
+ if (artifact_p(j_ptr))
+ {
+ j_ptr->number = 1;
+ }
/* Notice "okay" out-of-depth objects */
- if (!cursed_p(j_ptr) &&
- (k_info[j_ptr->k_idx].level > dun_level))
+ auto j_level = j_ptr->k_ptr->level;
+ if (!cursed_p(j_ptr) && (j_level > dun_level))
{
/* Rating increase */
- rating += (k_info[j_ptr->k_idx].level - dun_level);
+ rating += (j_level - dun_level);
/* Cheat -- peek at items */
if (options->cheat_peek || p_ptr->precognition)
@@ -4736,7 +4586,7 @@ bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const &
}
/* Success */
- return (TRUE);
+ return true;
}
@@ -4750,10 +4600,9 @@ bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const &
*
* This routine requires a clean floor grid destination.
*/
-void place_object(int y, int x, bool_ good, bool_ great, int where)
+void place_object(int y, int x, bool good, bool great, int where)
{
auto const &d_info = game->edit_data.d_info;
- auto &k_info = game->edit_data.k_info;
auto &a_info = game->edit_data.a_info;
auto &random_artifacts = game->random_artifacts;
@@ -4839,13 +4688,13 @@ void place_object(int y, int x, bool_ good, bool_ great, int where)
{
a_info[q_ptr->name1].cur_num = 0;
}
- else if (k_info[q_ptr->k_idx].flags & TR_NORM_ART)
+ else if (q_ptr->k_ptr->flags & TR_NORM_ART)
{
- k_info[q_ptr->k_idx].artifact = 0;
+ q_ptr->k_ptr->artifact = false;
}
else if (q_ptr->tval == TV_RANDART)
{
- random_artifacts[q_ptr->sval].generated = FALSE;
+ random_artifacts[q_ptr->sval].generated = false;
}
}
}
@@ -4862,17 +4711,12 @@ void place_object(int y, int x, bool_ good, bool_ great, int where)
*
* The location must be a legal, clean, floor grid.
*/
-bool_ make_gold(object_type *j_ptr)
+bool make_gold(object_type *j_ptr)
{
auto const &k_info = game->edit_data.k_info;
- int i;
-
- s32b base;
-
-
/* Hack -- Pick a Treasure variety */
- i = ((randint(object_level + 2) + 2) / 2) - 1;
+ int i = ((randint(object_level + 2) + 2) / 2) - 1;
/* Apply "extra" magic */
if (rand_int(GREAT_OBJ) == 0)
@@ -4890,7 +4734,7 @@ bool_ make_gold(object_type *j_ptr)
object_prep(j_ptr, OBJ_GOLD_LIST + i);
/* Hack -- Base coin cost */
- base = k_info[OBJ_GOLD_LIST + i].cost;
+ s32b const base = k_info.at(OBJ_GOLD_LIST + i)->cost;
/* Determine how much the treasure is "worth" */
j_ptr->pval = (base + (8L * randint(base)) + randint(8));
@@ -4902,7 +4746,7 @@ bool_ make_gold(object_type *j_ptr)
}
/* Success */
- return (TRUE);
+ return true;
}
@@ -4990,7 +4834,6 @@ void place_gold(int y, int x)
s16b drop_near(object_type *j_ptr, int chance, int y, int x)
{
auto const &f_info = game->edit_data.f_info;
- auto &k_info = game->edit_data.k_info;
auto &a_info = game->edit_data.a_info;
auto &random_artifacts = game->random_artifacts;
@@ -5005,17 +4848,17 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x)
char o_name[80];
- bool_ flag = FALSE;
- bool_ done = FALSE;
+ bool flag = false;
+ bool done = false;
- bool_ plural = FALSE;
+ bool plural = false;
/* Extract plural */
- if (j_ptr->number != 1) plural = TRUE;
+ if (j_ptr->number != 1) plural = true;
/* Describe object */
- object_desc(o_name, j_ptr, FALSE, 0);
+ object_desc(o_name, j_ptr, false, 0);
/* Handle normal "breakage" */
@@ -5049,7 +4892,7 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x)
/* Scan local grids */
for (dx = -3; dx <= 3; dx++)
{
- bool_ comb = FALSE;
+ bool comb = false;
/* Calculate actual distance */
d = (dy * dy) + (dx * dx);
@@ -5083,7 +4926,7 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x)
object_type *o_ptr = &o_list[this_o_idx];
/* Check for possible combination */
- if (object_similar(o_ptr, j_ptr)) comb = TRUE;
+ if (object_similar(o_ptr, j_ptr)) comb = true;
/* Count objects */
k++;
@@ -5115,7 +4958,7 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x)
bx = tx;
/* Okay */
- flag = TRUE;
+ flag = true;
}
}
@@ -5170,7 +5013,7 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x)
if (!cave_clean_bold(by, bx)) continue;
/* Okay */
- flag = TRUE;
+ flag = true;
}
@@ -5190,7 +5033,7 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x)
object_absorb(o_ptr, j_ptr);
/* Success */
- done = TRUE;
+ done = true;
/* Done */
break;
@@ -5216,13 +5059,13 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x)
{
a_info[j_ptr->name1].cur_num = 0;
}
- else if (k_info[j_ptr->k_idx].flags & TR_NORM_ART)
+ else if (j_ptr->k_ptr->flags & TR_NORM_ART)
{
- k_info[j_ptr->k_idx].artifact = 0;
+ j_ptr->k_ptr->artifact = false;
}
else if (j_ptr->tval == TV_RANDART)
{
- random_artifacts[j_ptr->sval].generated = FALSE;
+ random_artifacts[j_ptr->sval].generated = false;
}
/* Failure */
@@ -5249,7 +5092,7 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x)
c_ptr->o_idxs.push_back(o_idx);
/* Success */
- done = TRUE;
+ done = true;
}
/* Note the spot */
@@ -5277,7 +5120,7 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x)
/*
* Scatter some "great" objects near the player
*/
-void acquirement(int y1, int x1, int num, bool_ great, bool_ known)
+void acquirement(int y1, int x1, int num, bool great)
{
auto const &d_info = game->edit_data.d_info;
@@ -5294,13 +5137,7 @@ void acquirement(int y1, int x1, int num, bool_ great, bool_ known)
object_wipe(i_ptr);
/* Make a good (or great) object (if possible) */
- if (!make_object(i_ptr, TRUE, great, d_info[dungeon_type].objs)) continue;
-
- if (known)
- {
- object_aware(i_ptr);
- object_known(i_ptr);
- }
+ if (!make_object(i_ptr, true, great, d_info[dungeon_type].objs)) continue;
/* Drop the object */
drop_near(i_ptr, -1, y1, x1);
@@ -5346,7 +5183,7 @@ void inven_item_describe(int item)
char o_name[80];
/* Get a description */
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Print a message */
msg_format("You have %s.", o_name);
@@ -5394,17 +5231,23 @@ void inven_item_increase(int item, int num)
/*
* Erase an inventory slot if it has no more items
*/
-bool_ inven_item_optimize(int item)
+void inven_item_optimize(int item)
{
auto const &a_info = game->edit_data.a_info;
object_type *o_ptr = &p_ptr->inventory[item];
/* Only optimize real items */
- if (!o_ptr->k_idx) return (FALSE);
+ if (!o_ptr->k_ptr)
+ {
+ return;
+ }
/* Only optimize empty items */
- if (o_ptr->number) return (FALSE);
+ if (o_ptr->number)
+ {
+ return;
+ }
/* The item is in the pack */
if (item < INVEN_WIELD)
@@ -5455,8 +5298,6 @@ bool_ inven_item_optimize(int item)
/* Window stuff */
p_ptr->window |= (PW_EQUIP);
}
-
- return (TRUE);
}
@@ -5499,7 +5340,7 @@ void floor_item_describe(int item)
char o_name[80];
/* Get a description */
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Print a message */
msg_format("You see %s.", o_name);
@@ -5536,7 +5377,7 @@ void floor_item_optimize(int item)
object_type *o_ptr = &o_list[item];
/* Paranoia -- be sure it exists */
- if (!o_ptr->k_idx) return;
+ if (!o_ptr->k_ptr) return;
/* Only optimize empty items */
if (o_ptr->number) return;
@@ -5591,31 +5432,46 @@ void inc_stack_size_ex(int item, int delta, optimize_flag opt, describe_flag des
/*
* Check if we have space for an item in the pack without overflow
*/
-bool_ inven_carry_okay(object_type const *o_ptr)
+bool inven_carry_okay(object_type const *o_ptr)
{
- int j;
-
- if (o_ptr->tval == TV_GOLD) return FALSE;
+ if (o_ptr->tval == TV_GOLD) return false;
/* Empty slot? */
- if (inven_cnt < INVEN_PACK) return (TRUE);
+ if (inven_cnt < INVEN_PACK) return true;
/* Similar slot? */
- for (j = 0; j < INVEN_PACK; j++)
+ for (int j = 0; j < INVEN_PACK; j++)
{
object_type *j_ptr = &p_ptr->inventory[j];
/* Skip non-objects */
- if (!j_ptr->k_idx) continue;
+ if (!j_ptr->k_ptr) continue;
/* Check if the two items can be combined */
- if (object_similar(j_ptr, o_ptr)) return (TRUE);
+ if (object_similar(j_ptr, o_ptr)) return true;
}
/* Nope */
- return (FALSE);
+ return false;
}
+/**
+ * Find an empty slot in the player's inventory.
+ */
+static boost::optional<int> find_empty_slot()
+{
+ for (int i = 0; i < INVEN_PACK; i++)
+ {
+ auto o_ptr = &p_ptr->inventory[i];
+
+ if (!o_ptr->k_ptr)
+ {
+ return i;
+ }
+ }
+
+ return boost::none;
+}
/*
* Add an item to the players inventory, and return the slot used.
@@ -5637,22 +5493,27 @@ bool_ inven_carry_okay(object_type const *o_ptr)
* The "final" flag tells this function to bypass the "combine"
* and "reorder" code until later.
*/
-s16b inven_carry(object_type *o_ptr, bool_ final)
+s16b inven_carry(object_type *o_ptr, bool final)
{
- int i, j, k;
+ // Auto-identify the item before we put it in the pack.
+ object_aware(o_ptr);
+
+ // Index of last item
int n = -1;
- object_type *j_ptr;
/* Not final */
if (!final)
{
/* Check for combining */
- for (j = 0; j < INVEN_PACK; j++)
+ for (int j = 0; j < INVEN_PACK; j++)
{
- j_ptr = &p_ptr->inventory[j];
+ auto j_ptr = &p_ptr->inventory[j];
/* Skip non-objects */
- if (!j_ptr->k_idx) continue;
+ if (!j_ptr->k_ptr)
+ {
+ continue;
+ }
/* Hack -- track last item */
n = j;
@@ -5675,39 +5536,33 @@ s16b inven_carry(object_type *o_ptr, bool_ final)
}
}
-
/* Paranoia */
- if (inven_cnt > INVEN_PACK) return ( -1);
-
-
- /* Find an empty slot */
- for (j = 0; j <= INVEN_PACK; j++)
+ if (inven_cnt > INVEN_PACK)
{
- j_ptr = &p_ptr->inventory[j];
-
- /* Use it if found */
- if (!j_ptr->k_idx) break;
+ return ( -1);
}
- /* Use that slot */
- i = j;
-
+ /* Find an empty slot */
+ auto i = find_empty_slot()
+ .get_value_or(INVEN_PACK);
/* Hack -- pre-reorder the pack */
if (!final && (i < INVEN_PACK))
{
- s32b o_value, j_value;
-
/* Get the "value" of the item */
- o_value = object_value(o_ptr);
+ s32b o_value = object_value(o_ptr);
/* Scan every occupied slot */
+ int j;
for (j = 0; j < INVEN_PACK; j++)
{
- j_ptr = &p_ptr->inventory[j];
+ auto j_ptr = &p_ptr->inventory[j];
/* Use empty slots */
- if (!j_ptr->k_idx) break;
+ if (!j_ptr->k_ptr)
+ {
+ break;
+ }
/* Objects sort by decreasing type */
if (o_ptr->tval > j_ptr->tval) break;
@@ -5734,7 +5589,7 @@ s16b inven_carry(object_type *o_ptr, bool_ final)
}
/* Determine the "value" of the pack item */
- j_value = object_value(j_ptr);
+ s32b j_value = object_value(j_ptr);
/* Objects sort by decreasing value */
if (o_value > j_value) break;
@@ -5745,7 +5600,7 @@ s16b inven_carry(object_type *o_ptr, bool_ final)
i = j;
/* Slide objects */
- for (k = n; k >= i; k--)
+ for (int k = n; k >= i; k--)
{
/* Hack -- Slide the item */
object_copy(&p_ptr->inventory[k + 1], &p_ptr->inventory[k]);
@@ -5794,7 +5649,7 @@ s16b inven_carry(object_type *o_ptr, bool_ final)
*
* Return the inventory slot into which the item is placed.
*/
-s16b inven_takeoff(int item, int amt, bool_ force_drop)
+s16b inven_takeoff(int item, int amt, bool force_drop)
{
int slot;
@@ -5803,7 +5658,7 @@ s16b inven_takeoff(int item, int amt, bool_ force_drop)
object_type *o_ptr;
- cptr act;
+ const char *act;
char o_name[80];
@@ -5827,7 +5682,7 @@ s16b inven_takeoff(int item, int amt, bool_ force_drop)
q_ptr->number = amt;
/* Describe the object */
- object_desc(o_name, q_ptr, TRUE, 3);
+ object_desc(o_name, q_ptr, true, 3);
/* Took off weapon */
if (item == INVEN_WIELD)
@@ -5884,7 +5739,7 @@ s16b inven_takeoff(int item, int amt, bool_ force_drop)
else
{
/* Carry the object */
- slot = inven_carry(q_ptr, FALSE);
+ slot = inven_carry(q_ptr, false);
}
/* Message */
@@ -5902,7 +5757,7 @@ s16b inven_takeoff(int item, int amt, bool_ force_drop)
*
* The object will be dropped "near" the current location
*/
-void inven_drop(int item, int amt, int dy, int dx, bool_ silent)
+void inven_drop(int item, int amt, int dy, int dx, bool silent)
{
object_type forge;
object_type *q_ptr;
@@ -5926,7 +5781,7 @@ void inven_drop(int item, int amt, int dy, int dx, bool_ silent)
if (item >= INVEN_WIELD)
{
/* Take off first */
- item = inven_takeoff(item, amt, FALSE);
+ item = inven_takeoff(item, amt, false);
/* Access original object */
o_ptr = &p_ptr->inventory[item];
@@ -5959,7 +5814,7 @@ void inven_drop(int item, int amt, int dy, int dx, bool_ silent)
q_ptr->number = amt;
/* Describe local object */
- object_desc(o_name, q_ptr, TRUE, 3);
+ object_desc(o_name, q_ptr, true, 3);
/* Message */
if (!silent) msg_format("You drop %s (%c).", o_name, index_to_label(item));
@@ -5981,35 +5836,37 @@ void inven_drop(int item, int amt, int dy, int dx, bool_ silent)
*/
void combine_pack()
{
- int i, j, k;
- object_type *o_ptr;
- object_type *j_ptr;
- bool_ flag = FALSE;
-
+ bool flag = false;
/* Combine the pack (backwards) */
- for (i = INVEN_PACK; i > 0; i--)
+ for (int i = INVEN_PACK; i > 0; i--)
{
/* Get the item */
- o_ptr = &p_ptr->inventory[i];
+ auto o_ptr = &p_ptr->inventory[i];
/* Skip empty items */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Scan the items above that item */
- for (j = 0; j < i; j++)
+ for (int j = 0; j < i; j++)
{
/* Get the item */
- j_ptr = &p_ptr->inventory[j];
+ auto j_ptr = &p_ptr->inventory[j];
/* Skip empty items */
- if (!j_ptr->k_idx) continue;
+ if (!j_ptr->k_ptr)
+ {
+ continue;
+ }
/* Can we drop "o_ptr" onto "j_ptr"? */
if (object_similar(j_ptr, o_ptr))
{
/* Take note */
- flag = TRUE;
+ flag = true;
/* Add together the item counts */
object_absorb(j_ptr, o_ptr);
@@ -6018,6 +5875,7 @@ void combine_pack()
inven_cnt--;
/* Slide everything down */
+ int k;
for (k = i; k < INVEN_PACK; k++)
{
/* Structure copy */
@@ -6037,7 +5895,10 @@ void combine_pack()
}
/* Message */
- if (flag) msg_print("You combine some items in your pack.");
+ if (flag)
+ {
+ msg_print("You combine some items in your pack.");
+ }
}
@@ -6055,7 +5916,7 @@ void reorder_pack()
object_type *q_ptr;
object_type *j_ptr;
object_type *o_ptr;
- bool_ flag = FALSE;
+ bool flag = false;
/* Re-order the pack (forwards) */
@@ -6068,7 +5929,10 @@ void reorder_pack()
o_ptr = &p_ptr->inventory[i];
/* Skip empty slots */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Get the "value" of the item */
o_value = object_value(o_ptr);
@@ -6080,7 +5944,10 @@ void reorder_pack()
j_ptr = &p_ptr->inventory[j];
/* Use empty slots */
- if (!j_ptr->k_idx) break;
+ if (!j_ptr->k_ptr)
+ {
+ break;
+ }
/* Objects sort by decreasing type */
if (o_ptr->tval > j_ptr->tval) break;
@@ -6121,7 +5988,7 @@ void reorder_pack()
if (j >= i) continue;
/* Take note */
- flag = TRUE;
+ flag = true;
/* Get local object */
q_ptr = &forge;
@@ -6235,7 +6102,7 @@ void pack_decay(int item)
char desc[80];
/* Player notices each decaying object */
- object_desc(desc, o_ptr, TRUE, 3);
+ object_desc(desc, o_ptr, true, 3);
msg_format("You feel %s decompose.", desc);
/* Get local object */
@@ -6291,7 +6158,7 @@ void pack_decay(int item)
/* Named skeletons are artifacts */
i_ptr->name1 = 201;
}
- inven_carry(i_ptr, TRUE);
+ inven_carry(i_ptr, true);
}
}
}
@@ -6324,13 +6191,13 @@ void floor_decay(int item)
byte y = o_ptr->iy;
/* Maybe the player sees it */
- bool_ visible = player_can_see_bold(o_ptr->iy, o_ptr->ix);
+ bool visible = player_can_see_bold(o_ptr->iy, o_ptr->ix);
char desc[80];
if (visible)
{
/* Player notices each decaying object */
- object_desc(desc, o_ptr, TRUE, 3);
+ object_desc(desc, o_ptr, true, 3);
msg_format("You see %s decompose.", desc);
}
diff --git a/src/object2.hpp b/src/object2.hpp
index a91631aa..f5d093e3 100644
--- a/src/object2.hpp
+++ b/src/object2.hpp
@@ -1,7 +1,8 @@
#pragma once
#include "ego_flag_set.hpp"
-#include "h-basic.h"
+#include "h-basic.hpp"
+#include "object_kind_fwd.hpp"
#include "object_type_fwd.hpp"
#include "obj_theme_fwd.hpp"
@@ -14,26 +15,27 @@ void inc_stack_size(int item, int delta);
void inc_stack_size_ex(int item, int delta, optimize_flag opt, describe_flag desc);
object_type *get_object(int item);
s32b calc_total_weight();
-void add_random_ego_flag(object_type *o_ptr, ego_flag_set const &fego, bool_ *limit_blows);
+void add_random_ego_flag(object_type *o_ptr, ego_flag_set const &fego, bool *limit_blows);
bool init_match_theme(obj_theme const &theme);
-bool_ kind_is_artifactable(int k_idx);
-bool_ kind_is_legal(int k_idx);
+bool kind_is_artifactable(object_kind const *);
+bool kind_is_legal(object_kind const *);
void inven_item_charges(int item);
void inven_item_describe(int item);
void inven_item_increase(int item, int num);
-bool_ inven_item_optimize(int item);
+void inven_item_optimize(int item);
void floor_item_charges(int item);
void floor_item_describe(int item);
void floor_item_increase(int item, int num);
void floor_item_optimize(int item);
-bool_ inven_carry_okay(object_type const *o_ptr);
-s16b inven_carry(object_type *o_ptr, bool_ final);
-s16b inven_takeoff(int item, int amt, bool_ force_drop);
-void inven_drop(int item, int amt, int dy, int dx, bool_ silent);
+bool inven_carry_okay(object_type const *o_ptr);
+s16b inven_carry(object_type *o_ptr, bool final);
+s16b inven_takeoff(int item, int amt, bool force_drop);
+void inven_drop(int item, int amt, int dy, int dx, bool silent);
void excise_object_idx(int o_idx);
void delete_object_idx(int o_idx);
void delete_object(int y, int x);
void compact_objects(int size);
+void rescue_artifact(object_type *o_ptr);
void wipe_o_list();
s16b o_pop();
errr get_obj_num_prep();
@@ -42,23 +44,21 @@ void object_known(object_type *o_ptr);
bool object_known_p(object_type const *o_ptr);
void object_aware(object_type *o_ptr);
bool object_aware_p(object_type const *o_ptr);
-void object_tried(object_type *o_ptr);
-bool object_tried_p(object_type const *o_ptr);
s32b object_value(object_type const *o_ptr);
s32b object_value_real(object_type const *o_ptr);
-bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr);
+bool object_similar(object_type const *o_ptr, object_type const *j_ptr);
void object_absorb(object_type *o_ptr, object_type *j_ptr);
s16b lookup_kind(int tval, int sval);
void object_wipe(object_type *o_ptr);
void object_prep(object_type *o_ptr, int k_idx);
void object_copy(object_type *o_ptr, object_type *j_ptr);
-void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ great, boost::optional<int> force_power = boost::none);
-bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const &theme);
-void place_object(int y, int x, bool_ good, bool_ great, int where);
-bool_ make_gold(object_type *j_ptr);
+void apply_magic(object_type *o_ptr, int lev, bool okay, bool good, bool great, boost::optional<int> force_power = boost::none);
+bool make_object(object_type *j_ptr, bool good, bool great, obj_theme const &theme);
+void place_object(int y, int x, bool good, bool great, int where);
+bool make_gold(object_type *j_ptr);
void place_gold(int y, int x);
s16b drop_near(object_type *o_ptr, int chance, int y, int x);
-void acquirement(int y1, int x1, int num, bool_ great, bool_ known);
+void acquirement(int y1, int x1, int num, bool great);
void combine_pack();
void reorder_pack();
void random_artifact_resistance(object_type * o_ptr);
diff --git a/src/object_filter.hpp b/src/object_filter.hpp
index d18e13ee..33abed75 100644
--- a/src/object_filter.hpp
+++ b/src/object_filter.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_flag_set.hpp"
#include "object_type_fwd.hpp"
diff --git a/src/object_flag_list.hpp b/src/object_flag_list.hpp
index a7aef7d4..7b2e69db 100644
--- a/src/object_flag_list.hpp
+++ b/src/object_flag_list.hpp
@@ -141,7 +141,6 @@ TR(4, 21, TR_EASY_USE , EASY_USE , nullptr , -1, -1, -1,
TR(4, 22, TR_IM_NETHER , IM_NETHER , "Imm Neth" , 1, 1, 12, TERNARY(2), 1, false, false)
TR(4, 23, TR_RECHARGED , RECHARGED , nullptr , -1, -1, -1, BINARY , 0, false, false)
TR(4, 24, TR_ULTIMATE , ULTIMATE , nullptr , -1, -1, -1, BINARY , 0, false, false)
-TR(4, 25, TR_AUTO_ID , AUTO_ID , nullptr , -1, -1, -1, BINARY , 0, false, false)
TR(4, 26, TR_LITE2 , LITE2 , "Lite" , 2, 0, 13, FIXED(2) , 0, false, false)
TR(4, 27, TR_LITE3 , LITE3 , "Lite" , 2, 0, 13, FIXED(3) , 0, false, false)
TR(4, 28, TR_FUEL_LITE , FUEL_LITE , nullptr , -1, -1, -1, BINARY , 0, false, false)
diff --git a/src/object_kind.hpp b/src/object_kind.hpp
index 2f347f3f..f82d1b86 100644
--- a/src/object_kind.hpp
+++ b/src/object_kind.hpp
@@ -1,8 +1,11 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_flag_set.hpp"
+#include <boost/optional.hpp>
+#include <string>
+
/**
* Size of allocation table for objects
*/
@@ -15,8 +18,10 @@ constexpr int ALLOCATION_MAX = 8;
*/
struct object_kind
{
- const char *name = nullptr; /* Name */
- char *text = nullptr; /* Text */
+ s16b idx; /* Index */
+
+ std::string name; /* Name */
+ std::string text; /* Text */
byte tval = 0; /* Object type */
byte sval = 0; /* Object sub type */
@@ -59,15 +64,22 @@ struct object_kind
byte flavor = 0; /* Special object flavor (or zero) */
- bool_ easy_know = 0; /* This object is always known (if aware) */
+ bool easy_know = 0; /* This object is always known (if aware) */
- bool_ aware = 0; /* The player is "aware" of the item's effects */
+ bool aware = 0; /* The player is "aware" of the item's effects */
- bool_ tried = 0; /* The player has "tried" one of the items */
+ bool allow_special = 0;
byte btval = 0; /* Become Object type */
byte bsval = 0; /* Become Object sub type */
- bool_ artifact = 0; /* Is it a normal artifact(already generated) */
+ bool artifact = 0; /* Is it a normal artifact(already generated) */
+
+ boost::optional<int> power; /* Power granted */
+
+public:
+ explicit object_kind(s16b idx_)
+ : idx(idx_)
+ {
+ }
- s16b power = 0; /* Power granted(if any) */
};
diff --git a/src/object_kind_fwd.hpp b/src/object_kind_fwd.hpp
new file mode 100644
index 00000000..6d26db9f
--- /dev/null
+++ b/src/object_kind_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct object_kind;
diff --git a/src/object_proto.hpp b/src/object_proto.hpp
index faa0b2e8..a652e40f 100644
--- a/src/object_proto.hpp
+++ b/src/object_proto.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct object_proto
{
diff --git a/src/object_type.hpp b/src/object_type.hpp
index 3a34d181..69e8c5df 100644
--- a/src/object_type.hpp
+++ b/src/object_type.hpp
@@ -1,8 +1,10 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_flag_set.hpp"
+#include "object_kind_fwd.hpp"
+#include <memory>
#include <string>
/**
@@ -34,7 +36,7 @@
*/
struct object_type
{
- s16b k_idx = 0; /* Kind index (zero if "dead") */
+ std::shared_ptr<object_kind> k_ptr;
byte iy = 0; /* Y-position on map, or zero */
byte ix = 0; /* X-position on map, or zero */
@@ -73,7 +75,7 @@ struct object_type
s16b timeout = 0; /* Timeout Counter */
- byte ident = 0; /* Special flags */
+ bool identified = false; /* Has the object been identified? */
byte marked = 0; /* Object is marked */
@@ -86,8 +88,6 @@ struct object_type
s16b held_m_idx = 0; /* Monster holding the object; if any */
- byte sense = 0; /* Pseudo-id status */
-
byte found = 0; /* How did we find it */
s16b found_aux1 = 0; /* Stores info for found */
s16b found_aux2 = 0; /* Stores info for found */
diff --git a/src/option_type.hpp b/src/option_type.hpp
index 4d8a7a51..36e50299 100644
--- a/src/option_type.hpp
+++ b/src/option_type.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* Option descriptor.
@@ -10,7 +10,7 @@ struct option_type
/**
* Address of actual option variable.
*/
- bool_ *o_var;
+ bool *o_var;
/**
* Option page number.
@@ -25,10 +25,10 @@ struct option_type
/**
* Textual name.
*/
- cptr o_text;
+ const char *o_text;
/**
* Textual description
*/
- cptr o_desc;
+ const char *o_desc;
};
diff --git a/src/options.cc b/src/options.cc
index ea2f3172..9f5a09f7 100644
--- a/src/options.cc
+++ b/src/options.cc
@@ -2,9 +2,9 @@
void options::reset_cheat_options()
{
- cheat_peek = FALSE;
- cheat_hear = FALSE;
- cheat_room = FALSE;
- cheat_xtra = FALSE;
- cheat_live = FALSE;
+ cheat_peek = false;
+ cheat_hear = false;
+ cheat_room = false;
+ cheat_xtra = false;
+ cheat_live = false;
}
diff --git a/src/options.hpp b/src/options.hpp
index c1ac35a9..b0088fe2 100644
--- a/src/options.hpp
+++ b/src/options.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "option_type.hpp"
#include <vector>
@@ -13,102 +13,102 @@ struct options {
//
// Option Set 1 -- User Interface
//
- bool_ rogue_like_commands = FALSE; /* Rogue-like commands */
- bool_ quick_messages = TRUE; /* Activate quick messages */
- bool_ carry_query_flag = FALSE; /* Prompt before picking things up */
- bool_ use_old_target = FALSE; /* Use old target by default */
- bool_ always_pickup = FALSE; /* Pick things up by default */
- bool_ always_repeat = TRUE; /* Repeat obvious commands */
- bool_ ring_bell = FALSE; /* Ring the bell (on errors, etc) */
+ bool rogue_like_commands = false; /* Rogue-like commands */
+ bool quick_messages = true; /* Activate quick messages */
+ bool carry_query_flag = false; /* Prompt before picking things up */
+ bool use_old_target = false; /* Use old target by default */
+ bool always_pickup = false; /* Pick things up by default */
+ bool always_repeat = true; /* Repeat obvious commands */
+ bool ring_bell = false; /* Ring the bell (on errors, etc) */
//
// Option Set 2 -- Disturbance
//
- bool_ find_ignore_stairs = FALSE; /* Run past stairs */
- bool_ find_ignore_doors = TRUE; /* Run through open doors */
- bool_ find_cut = FALSE; /* Run past known corners */
- bool_ find_examine = TRUE; /* Run into potential corners */
- bool_ disturb_move = FALSE; /* Disturb whenever any monster moves */
- bool_ disturb_near = TRUE; /* Disturb whenever viewable monster moves */
- bool_ disturb_panel = TRUE; /* Disturb whenever map panel changes */
- bool_ disturb_state = TRUE; /* Disturn whenever player state changes */
- bool_ disturb_minor = TRUE; /* Disturb whenever boring things happen */
- bool_ disturb_other = FALSE; /* Disturb whenever various things happen */
- bool_ last_words = TRUE; /* Get last words upon dying */
- bool_ wear_confirm = TRUE; /* Confirm before putting on known cursed items */
- bool_ confirm_stairs = FALSE; /* Prompt before staircases... */
- bool_ disturb_pets = FALSE; /* Pets moving nearby disturb us */
+ bool find_ignore_stairs = false; /* Run past stairs */
+ bool find_ignore_doors = true; /* Run through open doors */
+ bool find_cut = false; /* Run past known corners */
+ bool find_examine = true; /* Run into potential corners */
+ bool disturb_move = false; /* Disturb whenever any monster moves */
+ bool disturb_near = true; /* Disturb whenever viewable monster moves */
+ bool disturb_panel = true; /* Disturb whenever map panel changes */
+ bool disturb_state = true; /* Disturn whenever player state changes */
+ bool disturb_minor = true; /* Disturb whenever boring things happen */
+ bool disturb_other = false; /* Disturb whenever various things happen */
+ bool last_words = true; /* Get last words upon dying */
+ bool wear_confirm = true; /* Confirm before putting on known cursed items */
+ bool confirm_stairs = false; /* Prompt before staircases... */
+ bool disturb_pets = false; /* Pets moving nearby disturb us */
//
// Option Set 3 -- Game-Play
//
- bool_ auto_scum = TRUE; /* Auto-scum for good levels */
- bool_ view_perma_grids = TRUE; /* Map remembers all perma-lit grids */
- bool_ view_torch_grids = FALSE; /* Map remembers all torch-lit grids */
- bool_ dungeon_align = TRUE; /* Generate dungeons with aligned rooms */
- bool_ dungeon_stair = TRUE; /* Generate dungeons with connected stairs */
- bool_ flow_by_sound = FALSE; /* Monsters track new player location */
- bool_ smart_learn = FALSE; /* Monsters learn from their mistakes */
- bool_ small_levels = TRUE; /* Allow unusually small dungeon levels */
- bool_ empty_levels = TRUE; /* Allow empty 'arena' levels */
+ bool auto_scum = true; /* Auto-scum for good levels */
+ bool view_perma_grids = true; /* Map remembers all perma-lit grids */
+ bool view_torch_grids = false; /* Map remembers all torch-lit grids */
+ bool dungeon_align = true; /* Generate dungeons with aligned rooms */
+ bool dungeon_stair = true; /* Generate dungeons with connected stairs */
+ bool flow_by_sound = false; /* Monsters track new player location */
+ bool smart_learn = false; /* Monsters learn from their mistakes */
+ bool small_levels = true; /* Allow unusually small dungeon levels */
+ bool empty_levels = true; /* Allow empty 'arena' levels */
//
// Option Set 4 -- Efficiency
//
- bool_ view_reduce_lite = FALSE; /* Reduce lite-radius when running */
- bool_ avoid_abort = FALSE; /* Avoid checking for user abort */
- bool_ avoid_shimmer = FALSE; /* Avoid processing extra shimmering */
- bool_ avoid_other = FALSE; /* Avoid processing special colors */
- bool_ flush_failure = TRUE; /* Flush input on any failure */
- bool_ flush_disturb = FALSE; /* Flush input on disturbance */
- bool_ flush_command = FALSE; /* Flush input before every command */
- bool_ fresh_before = TRUE; /* Flush output before normal commands */
- bool_ fresh_after = FALSE; /* Flush output after normal commands */
- bool_ fresh_message = FALSE; /* Flush output after all messages */
- bool_ hilite_player = FALSE; /* Hilite the player with the cursor */
- bool_ view_yellow_lite = FALSE; /* Use special colors for torch-lit grids */
- bool_ view_bright_lite = FALSE; /* Use special colors for 'viewable' grids */
- bool_ view_granite_lite = FALSE; /* Use special colors for wall grids (slow) */
- bool_ view_special_lite = FALSE; /* Use special colors for floor grids (slow) */
- bool_ center_player = FALSE; /* Center view on player */
+ bool view_reduce_lite = false; /* Reduce lite-radius when running */
+ bool avoid_abort = false; /* Avoid checking for user abort */
+ bool avoid_shimmer = false; /* Avoid processing extra shimmering */
+ bool avoid_other = false; /* Avoid processing special colors */
+ bool flush_failure = true; /* Flush input on any failure */
+ bool flush_disturb = false; /* Flush input on disturbance */
+ bool flush_command = false; /* Flush input before every command */
+ bool fresh_before = true; /* Flush output before normal commands */
+ bool fresh_after = false; /* Flush output after normal commands */
+ bool fresh_message = false; /* Flush output after all messages */
+ bool hilite_player = false; /* Hilite the player with the cursor */
+ bool view_yellow_lite = false; /* Use special colors for torch-lit grids */
+ bool view_bright_lite = false; /* Use special colors for 'viewable' grids */
+ bool view_granite_lite = false; /* Use special colors for wall grids (slow) */
+ bool view_special_lite = false; /* Use special colors for floor grids (slow) */
+ bool center_player = false; /* Center view on player */
//
// Option Set 5 - ToME options
//
- bool_ ingame_help = TRUE; /* In-game contextual help? */
- bool_ auto_more = FALSE; /* Auto more */
- bool_ player_char_health = TRUE; /* Display the player as a special symbol when in bad health ? */
- bool_ linear_stats = TRUE;
+ bool ingame_help = true; /* In-game contextual help? */
+ bool auto_more = false; /* Auto more */
+ bool player_char_health = true; /* Display the player as a special symbol when in bad health ? */
+ bool linear_stats = true;
//
// Option Set 6 - Birth options
//
- bool_ preserve = TRUE; /* Preserve artifacts */
- bool_ autoroll = TRUE; /* Specify 'minimal' stats to roll */
- bool_ point_based = FALSE; /* Generate character using a point system */
- bool_ ironman_rooms = FALSE; /* Always generate very unusual rooms */
- bool_ joke_monsters = FALSE; /* Allow 'joke' monsters */
- bool_ always_small_level = FALSE; /* Force small levels */
- bool_ fate_option = TRUE; /* Player can receive fates */
- bool_ no_selling = FALSE; /* Player cannot sell items */
+ bool preserve = true; /* Preserve artifacts */
+ bool autoroll = true; /* Specify 'minimal' stats to roll */
+ bool point_based = false; /* Generate character using a point system */
+ bool ironman_rooms = false; /* Always generate very unusual rooms */
+ bool joke_monsters = false; /* Allow 'joke' monsters */
+ bool always_small_level = false; /* Force small levels */
+ bool fate_option = true; /* Player can receive fates */
+ bool no_selling = false; /* Player cannot sell items */
//
// Other options
//
- bool_ cheat_peek = FALSE; /* Peek into object creation */
- bool_ cheat_hear = FALSE; /* Peek into monster creation */
- bool_ cheat_room = FALSE; /* Peek into dungeon creation */
- bool_ cheat_xtra = FALSE; /* Peek into something else */
- bool_ cheat_live = FALSE; /* Allow player to avoid death */
+ bool cheat_peek = false; /* Peek into object creation */
+ bool cheat_hear = false; /* Peek into monster creation */
+ bool cheat_room = false; /* Peek into dungeon creation */
+ bool cheat_xtra = false; /* Peek into something else */
+ bool cheat_live = false; /* Allow player to avoid death */
byte hitpoint_warn = 0; /* Hitpoint warning (0 to 9) */
byte delay_factor = 0; /* Delay factor (0 to 9) */
s16b autosave_freq = 100; /* Autosave frequency */
- bool_ autosave_t = FALSE; /* Timed autosave */
- bool_ autosave_l = FALSE; /* Autosave before entering new levels */
+ bool autosave_t = false; /* Timed autosave */
+ bool autosave_l = false; /* Autosave before entering new levels */
/**
* Option groups
diff --git a/src/owner_type.hpp b/src/owner_type.hpp
index 4c47dc48..a0fa2d1b 100644
--- a/src/owner_type.hpp
+++ b/src/owner_type.hpp
@@ -1,8 +1,9 @@
#pragma once
+#include <array>
#include <string>
-#include "h-basic.h"
+#include "h-basic.hpp"
/*
* Store owner descriptor.
@@ -27,15 +28,15 @@ struct owner_type
/**
* Liked/hated races.
*/
- u32b races[2][2] { };
+ std::array<std::array<u32b, 2>, 2> races { };
/**
* Liked/hated classes
*/
- u32b classes[2][2] { };
+ std::array<std::array<u32b, 2>, 2> classes { };
/**
* Costs for liked people
*/
- s16b costs[3] { };
+ std::array<s16b, 3> costs { };
};
diff --git a/src/player_class.hpp b/src/player_class.hpp
index 02d0fc11..0d9711bf 100644
--- a/src/player_class.hpp
+++ b/src/player_class.hpp
@@ -1,7 +1,7 @@
#pragma once
#include "body.hpp"
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_flag_set.hpp"
#include "object_proto.hpp"
#include "player_defs.hpp"
@@ -11,6 +11,8 @@
#include "player_spec.hpp"
#include "skill_modifiers.hpp"
+#include <array>
+
/**
* Player descriptor and runtime data.
*/
@@ -18,7 +20,7 @@ struct player_class
{
std::string title; /* Type of class */
std::string desc; /* Small desc of the class */
- const char *titles[PY_MAX_LEVEL / 5] { }; /* Titles */
+ std::array<std::string, PY_MAX_LEVEL / 5> titles { };/* Titles */
int display_order_idx; /* Display order index; lowest first */
diff --git a/src/player_level_flag.hpp b/src/player_level_flag.hpp
index fe4c862c..7a6226c0 100644
--- a/src/player_level_flag.hpp
+++ b/src/player_level_flag.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_flag_set.hpp"
#include "player_defs.hpp"
diff --git a/src/player_race.hpp b/src/player_race.hpp
index e0b236db..6ea31dbc 100644
--- a/src/player_race.hpp
+++ b/src/player_race.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "body.hpp"
#include "object_flag_set.hpp"
#include "object_proto.hpp"
@@ -30,7 +30,7 @@ struct player_race
byte infra = 0; /* Infra-vision range */
- u32b choice[2] { }; /* Legal class choices */
+ std::array<u32b, 2> choice { }; /* Legal class choices */
byte body_parts[BODY_MAX] { }; /* To help to decide what to use when body changing */
diff --git a/src/player_race_ability_type.hpp b/src/player_race_ability_type.hpp
index 5f520052..70962bbd 100644
--- a/src/player_race_ability_type.hpp
+++ b/src/player_race_ability_type.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct player_race_ability_type
{
diff --git a/src/player_race_mod.hpp b/src/player_race_mod.hpp
index 8eb984b7..34f5be41 100644
--- a/src/player_race_mod.hpp
+++ b/src/player_race_mod.hpp
@@ -1,7 +1,7 @@
#pragma once
#include "body.hpp"
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_flag_set.hpp"
#include "object_proto.hpp"
#include "player_defs.hpp"
@@ -21,7 +21,7 @@ struct player_race_mod
std::string title;
std::string description;
- bool_ place = FALSE; /* TRUE = race race modifier, FALSE = Race modifier race */
+ bool place = false; /* true = race race modifier, false = Race modifier race */
char luck = '\0'; /* Luck */
s16b mana = 0; /* Mana % */
@@ -30,12 +30,12 @@ struct player_race_mod
char infra = '\0'; /* (+) Infra-vision range */
- u32b choice[2] { }; /* Legal race choices */
+ std::array<u32b, 2> choice { }; /* Legal race choices */
- u32b pclass[2] { }; /* Classes allowed */
- u32b mclass[2] { }; /* Classes restricted */
+ std::array<u32b, 2> pclass { }; /* Classes allowed */
+ std::array<u32b, 2> mclass { }; /* Classes restricted */
- char body_parts[BODY_MAX] { }; /* To help to decide what to use when body changing */
+ std::array<char, BODY_MAX> body_parts { }; /* To help to decide what to use when body changing */
player_race_flag_set flags;
diff --git a/src/player_shared.hpp b/src/player_shared.hpp
index 1ae7b9a7..6b830782 100644
--- a/src/player_shared.hpp
+++ b/src/player_shared.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "skills_defs.hpp"
#include <array>
#include <vector>
diff --git a/src/player_spec.hpp b/src/player_spec.hpp
index 574425f6..3dabbb9a 100644
--- a/src/player_spec.hpp
+++ b/src/player_spec.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_proto.hpp"
#include "player_race_ability_type.hpp"
#include "player_race_flag_set.hpp"
diff --git a/src/player_type.hpp b/src/player_type.hpp
index 9b7ac21d..a5c41618 100644
--- a/src/player_type.hpp
+++ b/src/player_type.hpp
@@ -1,8 +1,8 @@
#pragma once
#include "corrupt.hpp"
-#include "defines.h"
-#include "h-basic.h"
+#include "defines.hpp"
+#include "h-basic.hpp"
#include "help_info.hpp"
#include "inventory.hpp"
#include "object_type.hpp"
@@ -11,6 +11,7 @@
#include "spellbinder.hpp"
#include <array>
+#include <unordered_set>
/*
* Most of the "player" information goes here.
@@ -64,8 +65,8 @@ struct player_type
s32b wilderness_x = 0; /* Coordinates in the wilderness */
s32b wilderness_y = 0;
- bool_ wild_mode = FALSE; /* TRUE = Small map, FLASE = Big map */
- bool_ old_wild_mode = FALSE; /* TRUE = Small map, FLASE = Big map */
+ bool wild_mode = false; /* true = Small map, FLASE = Big map */
+ bool old_wild_mode = false; /* true = Small map, FLASE = Big map */
s16b mhp = 0; /* Max hit pts */
s16b chp = 0; /* Cur hit pts */
@@ -83,13 +84,13 @@ struct player_type
s32b grace = 0; /* Your God's appreciation factor. */
s32b grace_delay = 0; /* Delay factor for granting piety. */
byte pgod = 0; /* Your God. */
- bool_ praying = FALSE; /* Praying to your god. */
+ bool praying = false; /* Praying to your god. */
s16b melkor_sacrifice = 0; /* How much hp has been sacrified for damage */
s16b max_plv = 0; /* Max Player Level */
- s16b stat_max[6] = { 0 }; /* Current "maximal" stat values */
- s16b stat_cur[6] = { 0 }; /* Current "natural" stat values */
+ std::array<s16b, 6> stat_max { }; /* Current "maximal" stat values */
+ std::array<s16b, 6> stat_cur { }; /* Current "natural" stat values */
s16b luck_cur = 0; /* Current "natural" luck value (range -30 <> 30) */
s16b luck_max = 0; /* Current "maximal base" luck value (range -30 <> 30) */
@@ -177,23 +178,24 @@ struct player_type
byte confusing = 0; /* Glowing hands */
- bool_ old_cumber_armor = FALSE;
- bool_ old_cumber_glove = FALSE;
- bool_ old_heavy_wield = FALSE;
- bool_ old_heavy_shoot = FALSE;
- bool_ old_icky_wield = FALSE;
+ bool old_cumber_armor = false;
+ bool old_cumber_glove = false;
+ bool old_heavy_wield = false;
+ bool old_heavy_shoot = false;
+ bool old_icky_wield = false;
s16b old_lite = 0; /* Old radius of lite (if any) */
s16b old_view = 0; /* Old radius of view (if any) */
s16b old_food_aux = 0; /* Old value of food */
- bool_ cumber_armor = FALSE; /* Mana draining armor */
- bool_ cumber_glove = FALSE; /* Mana draining gloves */
- bool_ heavy_wield = FALSE; /* Heavy weapon */
- bool_ heavy_shoot = FALSE; /* Heavy shooter */
- bool_ icky_wield = FALSE; /* Icky weapon */
- bool_ immovable = FALSE; /* Immovable character */
+ bool cumber_armor = false; /* Mana draining armor */
+ bool cumber_glove = false; /* Mana draining gloves */
+ bool heavy_wield = false; /* Heavy weapon */
+ bool heavy_shoot = false; /* Heavy shooter */
+ bool icky_wield = false; /* Icky weapon */
+
+ bool immovable = false; /* Immovable character */
s16b cur_lite = 0; /* Radius of lite (if any) */
@@ -202,79 +204,82 @@ struct player_type
u32b redraw = 0; /* Normal Redraws (bit flags) */
u32b window = 0; /* Window Redraws (bit flags) */
- s16b stat_use[6] = { 0 }; /* Current modified stats */
- s16b stat_top[6] = { 0 }; /* Maximal modified stats */
-
- s16b stat_add[6] = { 0 }; /* Modifiers to stat values */
- s16b stat_ind[6] = { 0 }; /* Indexes into stat tables */
- s16b stat_cnt[6] = { 0 }; /* Counter for temporary drains */
- s16b stat_los[6] = { 0 }; /* Amount of temporary drains */
-
- bool_ immune_acid = FALSE; /* Immunity to acid */
- bool_ immune_elec = FALSE; /* Immunity to lightning */
- bool_ immune_fire = FALSE; /* Immunity to fire */
- bool_ immune_cold = FALSE; /* Immunity to cold */
- bool_ immune_neth = FALSE; /* Immunity to nether */
-
- bool_ resist_acid = FALSE; /* Resist acid */
- bool_ resist_elec = FALSE; /* Resist lightning */
- bool_ resist_fire = FALSE; /* Resist fire */
- bool_ resist_cold = FALSE; /* Resist cold */
- bool_ resist_pois = FALSE; /* Resist poison */
-
- bool_ resist_conf = FALSE; /* Resist confusion */
- bool_ resist_sound = FALSE; /* Resist sound */
- bool_ resist_lite = FALSE; /* Resist light */
- bool_ resist_dark = FALSE; /* Resist darkness */
- bool_ resist_chaos = FALSE; /* Resist chaos */
- bool_ resist_disen = FALSE; /* Resist disenchant */
- bool_ resist_shard = FALSE; /* Resist shards */
- bool_ resist_nexus = FALSE; /* Resist nexus */
- bool_ resist_blind = FALSE; /* Resist blindness */
- bool_ resist_neth = FALSE; /* Resist nether */
- bool_ resist_fear = FALSE; /* Resist fear */
- bool_ resist_continuum = FALSE; /* Resist space-time continuum disruption */
-
- bool_ sensible_fire = FALSE; /* Fire does more damage on the player */
- bool_ sensible_lite = FALSE; /* Lite does more damage on the player and blinds her/him */
-
- bool_ reflect = FALSE; /* Reflect 'bolt' attacks */
- bool_ sh_fire = FALSE; /* Fiery 'immolation' effect */
- bool_ sh_elec = FALSE; /* Electric 'immolation' effect */
- bool_ wraith_form = FALSE; /* wraithform */
-
- bool_ anti_magic = FALSE; /* Anti-magic */
- bool_ anti_tele = FALSE; /* Prevent teleportation */
-
- bool_ sustain_str = FALSE; /* Keep strength */
- bool_ sustain_int = FALSE; /* Keep intelligence */
- bool_ sustain_wis = FALSE; /* Keep wisdom */
- bool_ sustain_dex = FALSE; /* Keep dexterity */
- bool_ sustain_con = FALSE; /* Keep constitution */
- bool_ sustain_chr = FALSE; /* Keep charisma */
-
- bool_ aggravate = FALSE; /* Aggravate monsters */
- bool_ teleport = FALSE; /* Random teleporting */
-
- bool_ exp_drain = FALSE; /* Experience draining */
- byte drain_mana = FALSE; /* mana draining */
- byte drain_life = FALSE; /* hp draining */
-
- bool_ magical_breath = FALSE; /* Magical breathing -- can breath anywhere */
- bool_ water_breath = FALSE; /* Water breathing -- can breath underwater */
- bool_ climb = FALSE; /* Can climb mountains */
- bool_ fly = FALSE; /* Can fly over some features */
- bool_ ffall = FALSE; /* No damage falling */
- bool_ lite = FALSE; /* Permanent light */
- bool_ free_act = FALSE; /* Never paralyzed */
- bool_ see_inv = FALSE; /* Can see invisible */
- bool_ regenerate = FALSE; /* Regenerate hit pts */
- bool_ hold_life = FALSE; /* Resist life draining */
- bool_ slow_digest = FALSE; /* Slower digestion */
- bool_ bless_blade = FALSE; /* Blessed blade */
+ std::array<s16b, 6> stat_use { }; /* Current modified stats */
+ std::array<s16b, 6> stat_top { }; /* Maximal modified stats */
+
+ std::array<s16b, 6> stat_add { }; /* Modifiers to stat values */
+ std::array<s16b, 6> stat_ind { }; /* Indexes into stat tables */
+ std::array<s16b, 6> stat_cnt { }; /* Counter for temporary drains */
+ std::array<s16b, 6> stat_los { }; /* Amount of temporary drains */
+
+ bool immune_acid = false; /* Immunity to acid */
+ bool immune_elec = false; /* Immunity to lightning */
+ bool immune_fire = false; /* Immunity to fire */
+ bool immune_cold = false; /* Immunity to cold */
+ bool immune_neth = false; /* Immunity to nether */
+
+ bool resist_acid = false; /* Resist acid */
+ bool resist_elec = false; /* Resist lightning */
+ bool resist_fire = false; /* Resist fire */
+ bool resist_cold = false; /* Resist cold */
+ bool resist_pois = false; /* Resist poison */
+
+ bool resist_conf = false; /* Resist confusion */
+ bool resist_sound = false; /* Resist sound */
+ bool resist_lite = false; /* Resist light */
+ bool resist_dark = false; /* Resist darkness */
+ bool resist_chaos = false; /* Resist chaos */
+ bool resist_disen = false; /* Resist disenchant */
+ bool resist_shard = false; /* Resist shards */
+ bool resist_nexus = false; /* Resist nexus */
+ bool resist_blind = false; /* Resist blindness */
+ bool resist_neth = false; /* Resist nether */
+ bool resist_fear = false; /* Resist fear */
+ bool resist_continuum = false; /* Resist space-time continuum disruption */
+
+ bool sensible_fire = false; /* Fire does more damage on the player */
+ bool sensible_lite = false; /* Lite does more damage on the player and blinds her/him */
+
+ bool reflect = false; /* Reflect 'bolt' attacks */
+
+ bool sh_fire = false; /* Fiery 'immolation' effect */
+ bool sh_elec = false; /* Electric 'immolation' effect */
+
+ bool wraith_form = false; /* wraithform */
+
+ bool anti_magic = false; /* Anti-magic */
+ bool anti_tele = false; /* Prevent teleportation */
+
+ bool sustain_str = false; /* Keep strength */
+ bool sustain_int = false; /* Keep intelligence */
+ bool sustain_wis = false; /* Keep wisdom */
+ bool sustain_dex = false; /* Keep dexterity */
+ bool sustain_con = false; /* Keep constitution */
+ bool sustain_chr = false; /* Keep charisma */
+
+ bool aggravate = false; /* Aggravate monsters */
+ bool teleport = false; /* Random teleporting */
+
+ bool exp_drain = false; /* Experience draining */
+ byte drain_mana = false; /* mana draining */
+ byte drain_life = false; /* hp draining */
+
+ bool magical_breath = false; /* Magical breathing -- can breath anywhere */
+ bool water_breath = false; /* Water breathing -- can breath underwater */
+
+ bool climb = false; /* Can climb mountains */
+ bool fly = false; /* Can fly over some features */
+ bool ffall = false; /* No damage falling */
+
+ bool lite = false; /* Permanent light */
+ bool free_act = false; /* Never paralyzed */
+ bool see_inv = false; /* Can see invisible */
+ bool regenerate = false; /* Regenerate hit pts */
+ bool hold_life = false; /* Resist life draining */
+ bool slow_digest = false; /* Slower digestion */
+ bool bless_blade = false; /* Blessed blade */
byte xtra_might = 0; /* Extra might bow */
- bool_ impact = FALSE; /* Earthquake blows */
- bool_ auto_id = FALSE; /* Auto id items */
+ bool impact = false; /* Earthquake blows */
s16b invis = 0; /* Invisibility */
@@ -332,18 +337,18 @@ struct player_type
struct spellbinder spellbinder;
- cptr mimic_name = nullptr;
+ const char *mimic_name = nullptr;
char tactic = '\0'; /* from 128-4 "extremely coward" to, 128+4 "berserker" */
char movement = '\0'; /* base movement way */
s16b companion_killed = 0; /* Number of companion death */
- bool_ no_mortal = FALSE; /* Fated to never die by the hand of a mortal being */
+ bool no_mortal = false; /* Fated to never die by the hand of a mortal being */
- bool_ black_breath = FALSE; /* The Tolkien's Black Breath */
+ bool black_breath = false; /* The Tolkien's Black Breath */
- bool_ precognition = FALSE; /* Like the cheat mode */
+ bool precognition = false; /* Like the cheat mode */
/*** Extra flags ***/
object_flag_set xtra_flags;
@@ -352,8 +357,8 @@ struct player_type
object_flag_set computed_flags;
/* Corruptions */
- bool_ corruptions[CORRUPTIONS_MAX] = { FALSE };
- bool_ corrupt_anti_teleport_stopped = FALSE;
+ std::array<bool, CORRUPTIONS_MAX> corruptions { };
+ bool corrupt_anti_teleport_stopped = false;
/*** Pet commands ***/
byte pet_follow_distance = 0; /* Length of the imaginary "leash" for pets */
@@ -365,16 +370,16 @@ struct player_type
/*** Body changing variables ***/
u16b body_monster = 0; /* In which body is the player */
- bool_ disembodied = FALSE; /* Is the player in a body ? */
+ bool disembodied = false; /* Is the player in a body ? */
std::array<byte, INVEN_TOTAL-INVEN_WIELD> body_parts = /* Which body parts does he have ? */
{ };
/* Astral */
- bool_ astral = FALSE; /* We started at the bottom ? */
+ bool astral = false; /* We started at the bottom ? */
- /* Powers */
- bool_ powers[POWER_MAX] = { FALSE }; /* Actual powers */
- bool_ powers_mod[POWER_MAX] = { FALSE }; /* Intrinsinc powers */
+ /* Powers; keys of Game::powers */
+ std::unordered_set<int> powers; /* Actual powers */
+ std::unordered_set<int> powers_mod; /* Intrinsinc powers */
/* Acquired abilities; indexes into ab_info[] */
std::vector<u16b> abilities;
@@ -402,8 +407,8 @@ struct player_type
/*** Temporary fields ***/
- bool_ did_nothing = FALSE; /* True if the last action wasnt a real action */
- bool_ leaving = FALSE; /* True if player is leaving */
+ bool did_nothing = false; /* True if the last action wasnt a real action */
+ bool leaving = false; /* True if player is leaving */
/**
* Random spells.
diff --git a/src/power_activation.hpp b/src/power_activation.hpp
new file mode 100644
index 00000000..d4624632
--- /dev/null
+++ b/src/power_activation.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "h-basic.hpp"
+
+struct power_activation {
+
+ byte level; /* Min level */
+ byte cost; /* Mana/Life cost */
+ byte stat; /* Stat used */
+ byte diff; /* Difficulty */
+
+};
diff --git a/src/power_type.hpp b/src/power_type.hpp
index 6cf8c29b..1f95abb7 100644
--- a/src/power_type.hpp
+++ b/src/power_type.hpp
@@ -1,19 +1,33 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
+#include "power_activation.hpp"
+
+#include <string>
/**
- * Power descriptor. (Racial, class, mutation, artifacts, ...)
+ * Power descriptor.
*/
struct power_type
{
- const char *name; /* Name */
- const char *desc_text; /* Text describing power */
- const char *gain_text; /* Text displayed on gaining the power */
- const char *lose_text; /* Text displayed on losing the power */
+ std::string name; /* Name */
+ std::string desc_text; /* Text describing power */
+ std::string gain_text; /* Text displayed on gaining the power */
+ std::string lose_text; /* Text displayed on losing the power */
+ power_activation activation;
+
+ power_type(
+ const char *name_,
+ const char *desc_text_,
+ const char *gain_text_,
+ const char *lose_text_,
+ power_activation const &activation_)
+ : name(name_)
+ , desc_text(desc_text_)
+ , gain_text(gain_text_)
+ , lose_text(lose_text_)
+ , activation(activation_)
+ {
+ }
- byte level; /* Min level */
- byte cost; /* Mana/Life cost */
- byte stat; /* Stat used */
- byte diff; /* Difficulty */
};
diff --git a/src/powers.cc b/src/powers.cc
index f3ffe668..a340d1c5 100644
--- a/src/powers.cc
+++ b/src/powers.cc
@@ -12,6 +12,7 @@
#include "cave_type.hpp"
#include "cmd1.hpp"
#include "cmd2.hpp"
+#include "cmd5.hpp"
#include "cmd7.hpp"
#include "dungeon_flag.hpp"
#include "feature_flag.hpp"
@@ -35,32 +36,36 @@
#include "stats.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "xtra2.hpp"
#include "z-rand.hpp"
-/*
- * Note: return value indicates the amount of mana to use
- */
-static bool_ power_chance(power_type *x_ptr)
+#include <fmt/format.h>
+
+static bool power_chance(power_activation const &x_ref)
{
- bool_ use_hp = FALSE;
+ auto x_ptr = &x_ref;
+ bool use_hp = false;
int diff = x_ptr->diff;
/* Always true ? */
- if (!x_ptr->cost) return TRUE;
+ if (!x_ptr->cost)
+ {
+ return true;
+ }
/* Not enough mana - use hp */
- if (p_ptr->csp < x_ptr->cost) use_hp = TRUE;
+ if (p_ptr->csp < x_ptr->cost)
+ {
+ use_hp = true;
+ }
/* Power is not available yet */
if (p_ptr->lev < x_ptr->level)
{
msg_format("You need to attain level %d to use this power.", x_ptr->level);
energy_use = 0;
- return (FALSE);
+ return false;
}
/* Too confused */
@@ -68,7 +73,7 @@ static bool_ power_chance(power_type *x_ptr)
{
msg_print("You are too confused to use this power.");
energy_use = 0;
- return (FALSE);
+ return false;
}
/* Risk death? */
@@ -77,7 +82,7 @@ static bool_ power_chance(power_type *x_ptr)
if (!(get_check("Really use the power in your weakened state? ")))
{
energy_use = 0;
- return (FALSE);
+ return false;
}
}
@@ -89,12 +94,13 @@ static bool_ power_chance(power_type *x_ptr)
}
else if (p_ptr->lev > x_ptr->level)
{
- int lev_adj = ((p_ptr->lev - x_ptr->level) / 3);
- if (lev_adj > 10) lev_adj = 10;
+ int const lev_adj =
+ std::min((p_ptr->lev - x_ptr->level) / 3, 10);
+
diff -= lev_adj;
}
- if (diff < 5) diff = 5;
+ diff = std::max(diff, 5);
/* take time and pay the price */
if (use_hp)
@@ -118,19 +124,19 @@ static bool_ power_chance(power_type *x_ptr)
if (randint(p_ptr->stat_cur[x_ptr->stat]) >=
((diff / 2) + randint(diff / 2)))
{
- return (TRUE);
+ return true;
}
flush_on_failure();
msg_print("You've failed to concentrate hard enough.");
- return (FALSE);
+ return false;
}
static void power_activate(int power)
{
auto const &f_info = game->edit_data.f_info;
- auto const &k_info = game->edit_data.k_info;
+ auto const &dungeon_flags = game->dungeon_flags;
s16b plev = p_ptr->lev;
char ch = 0;
@@ -139,10 +145,8 @@ static void power_activate(int power)
object_type *q_ptr;
object_type forge;
int ii = 0, ij = 0;
- /* char out_val[80]; */
- /* cptr p = "Power of the flame: "; */
- cptr q, s;
- power_type *x_ptr = &powers_type[power], x_ptr_foo;
+ const char *q;
+ const char *s;
int x, y;
cave_type *c_ptr;
@@ -156,8 +160,11 @@ static void power_activate(int power)
set_disrupt_shield(0);
}
-
- if (!power_chance(x_ptr)) return;
+ /* Check that we activate successfully */
+ if (!power_chance(game->powers.at(power)->activation))
+ {
+ return;
+ }
switch (power)
{
@@ -211,7 +218,7 @@ static void power_activate(int power)
{
if (!get_aim_dir(&dir))
break;
- if (passwall(dir, TRUE))
+ if (passwall(dir, true))
msg_print("A passage opens, and you step through.");
else
msg_print("There is no wall there!");
@@ -266,7 +273,7 @@ static void power_activate(int power)
case PWR_ROHAN:
/* Select power to use */
- while (TRUE)
+ while (true)
{
if (!get_com("Use [F]lash aura or [L]ight speed jump? ", &ch))
{
@@ -289,11 +296,12 @@ static void power_activate(int power)
if (amber_power == 1)
{
+ power_activation x_ptr_foo;
x_ptr_foo.level = 1;
x_ptr_foo.cost = 9;
x_ptr_foo.stat = A_CHR;
x_ptr_foo.diff = 7;
- if (power_chance(&x_ptr_foo))
+ if (power_chance(x_ptr_foo))
{
if (!(get_aim_dir(&dir))) break;
msg_print("You flash a bright aura.");
@@ -305,11 +313,12 @@ static void power_activate(int power)
}
if (amber_power == 2)
{
+ power_activation x_ptr_foo;
x_ptr_foo.level = 30;
x_ptr_foo.cost = 30;
x_ptr_foo.stat = A_WIS;
x_ptr_foo.diff = 7;
- if (power_chance(&x_ptr_foo))
+ if (power_chance(x_ptr_foo))
{
set_light_speed(p_ptr->lightspeed + 3);
}
@@ -344,7 +353,7 @@ static void power_activate(int power)
case PWR_THUNDER:
/* Select power to use */
- while (TRUE)
+ while (true)
{
if (!get_com("Use [T]hunder strike, [R]ide the straight road, go [B]ack in town? ", &ch))
{
@@ -374,11 +383,12 @@ static void power_activate(int power)
if (amber_power == 1)
{
+ power_activation x_ptr_foo;
x_ptr_foo.level = 1;
x_ptr_foo.cost = p_ptr->lev;
x_ptr_foo.stat = A_CON;
x_ptr_foo.diff = 6;
- if (power_chance(&x_ptr_foo))
+ if (power_chance(x_ptr_foo))
{
if (!get_aim_dir(&dir)) break;
msg_format("You conjure up thunder!");
@@ -394,11 +404,13 @@ static void power_activate(int power)
msg_print("No teleport on special levels ...");
break;
}
+
+ power_activation x_ptr_foo;
x_ptr_foo.level = 3;
x_ptr_foo.cost = 15;
x_ptr_foo.stat = A_CON;
x_ptr_foo.diff = 6;
- if (power_chance(&x_ptr_foo))
+ if (power_chance(x_ptr_foo))
{
msg_print("You enter the straight road and fly beside the world. Where to exit?");
if (!tgt_pt(&ii, &ij)) return;
@@ -421,11 +433,13 @@ static void power_activate(int power)
msg_print("No recall on special levels..");
break;
}
+
+ power_activation x_ptr_foo;
x_ptr_foo.level = 7;
x_ptr_foo.cost = 30;
x_ptr_foo.stat = A_CON;
x_ptr_foo.diff = 6;
- if (power_chance(&x_ptr_foo))
+ if (power_chance(x_ptr_foo))
{
if (dun_level == 0)
msg_print("You are already in town!");
@@ -487,7 +501,7 @@ static void power_activate(int power)
autosave_checkpoint();
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
break;
case PWR_VAMPIRISM:
@@ -505,7 +519,7 @@ static void power_activate(int power)
}
msg_print("You grin and bare your fangs...");
- dummy = plev + randint(plev) * MAX(1, plev / 10); /* Dmg */
+ dummy = plev + randint(plev) * std::max(1, plev / 10); /* Dmg */
if (drain_life(dir, dummy))
{
if (p_ptr->food < PY_FOOD_FULL)
@@ -517,7 +531,7 @@ static void power_activate(int power)
/* A Food ration gives 5000 food points (by contrast) */
/* Don't ever get more than "Full" this way */
/* But if we ARE Gorged, it won't cure us */
- dummy = p_ptr->food + MIN(5000, 100 * dummy);
+ dummy = p_ptr->food + std::min(5000, 100 * dummy);
if (p_ptr->food < PY_FOOD_MAX) /* Not gorged already */
set_food(dummy >= PY_FOOD_MAX ? PY_FOOD_MAX - 1 : dummy);
}
@@ -569,8 +583,6 @@ static void power_activate(int power)
object_aware(q_ptr);
object_known(q_ptr);
- q_ptr->ident |= IDENT_STOREB;
-
drop_near(q_ptr, 0, y, x);
delete_monster(y, x);
@@ -590,7 +602,8 @@ static void power_activate(int power)
int item, x, y, d;
object_type *o_ptr;
- cptr q, s;
+ const char *q;
+ const char *s;
/* Get an item */
q = "Awaken which monster? ";
@@ -611,7 +624,7 @@ static void power_activate(int power)
if (d >= 100) return;
- if ((m_idx = place_monster_one(y, x, o_ptr->pval, 0, FALSE, MSTATUS_PET)) == 0) return;
+ if ((m_idx = place_monster_one(y, x, o_ptr->pval, 0, false, MSTATUS_PET)) == 0) return;
m_ptr = &m_list[m_idx];
m_ptr->hp = o_ptr->pval2;
@@ -661,7 +674,7 @@ static void power_activate(int power)
{
msg_print("You concentrate...");
if (get_aim_dir(&dir))
- fetch(dir, p_ptr->lev * 10, TRUE);
+ fetch(dir, p_ptr->lev * 10, true);
}
break;
@@ -796,22 +809,6 @@ static void power_activate(int power)
}
break;
- case PWR_DET_CURSE:
- {
- int i;
-
- for (i = 0; i < INVEN_TOTAL; i++)
- {
- object_type *o_ptr = &p_ptr->inventory[i];
-
- if (!o_ptr->k_idx) continue;
- if (!cursed_p(o_ptr)) continue;
-
- if (!o_ptr->sense) o_ptr->sense = SENSE_CURSED;
- }
- }
- break;
-
case PWR_POLYMORPH:
{
do_poly_self();
@@ -829,7 +826,7 @@ static void power_activate(int power)
int i;
for (i = 0; i < 8; i++)
{
- summon_specific_friendly(p_ptr->py, p_ptr->px, p_ptr->lev, SUMMON_BIZARRE1, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, p_ptr->lev, SUMMON_BIZARRE1, false);
}
}
break;
@@ -887,7 +884,7 @@ static void power_activate(int power)
o_ptr = get_object(item);
- lev = k_info[o_ptr->k_idx].level;
+ lev = o_ptr->k_ptr->level;
if (o_ptr->tval == TV_ROD_MAIN)
{
@@ -912,7 +909,6 @@ static void power_activate(int power)
{
msg_print("There's no energy there to absorb!");
}
- o_ptr->ident |= IDENT_EMPTY;
}
if (p_ptr->csp > p_ptr->msp)
@@ -1055,13 +1051,13 @@ static void power_activate(int power)
case POWER_COR_SPACE_TIME:
if (p_ptr->corrupt_anti_teleport_stopped)
{
- p_ptr->corrupt_anti_teleport_stopped = FALSE;
+ p_ptr->corrupt_anti_teleport_stopped = false;
msg_print("You stop controlling your corruption.");
p_ptr->update |= PU_BONUS;
}
else
{
- p_ptr->corrupt_anti_teleport_stopped = TRUE;
+ p_ptr->corrupt_anti_teleport_stopped = true;
msg_print("You start controlling your corruption, teleportation works once more.");
p_ptr->update |= PU_BONUS;
}
@@ -1079,28 +1075,38 @@ static void power_activate(int power)
/*
* Print a batch of power.
*/
-static void print_power_batch(int *p, int start, int max)
+static void print_power_batch(std::vector<int> const &power_idxs, int start, int max)
{
- char buff[80];
- power_type* spell;
- int i = start, j = 0;
+ int j = 0;
- prt(format(" %-31s Level Mana Fail", "Name"), 1, 20);
+ prt(fmt::format("{:<10}{:<31} Level Mana Fail", "", "Name"), 1, 19);
- for (i = start; i < (start + 20); i++)
+ for (int i = start; i < (start + 20); i++)
{
- if (i >= max) break;
+ if (i >= max)
+ {
+ break;
+ }
- spell = &powers_type[p[i]];
+ auto spell = game->powers.at(power_idxs.at(i));
- sprintf(buff, " %c-%3d) %-30s %5d %4d %s@%d", I2A(j), p[i] + 1, spell->name,
- spell->level, spell->cost, stat_names[spell->stat], spell->diff);
+ auto buff = fmt::format(
+ " {} -{:>3}) {:<30} {:>5} {:>4} {}@{}",
+ I2C(j),
+ power_idxs.at(i) + 1,
+ spell->name,
+ spell->activation.level,
+ spell->activation.cost,
+ stat_names[spell->activation.stat],
+ spell->activation.diff
+ );
- prt(buff, 2 + j, 20);
+ prt(buff, 2 + j, 19);
j++;
}
- prt("", 2 + j, 20);
- prt(format("Select a power (a-%c), +/- to scroll:", I2A(j - 1)), 0, 0);
+
+ prt("", 2 + j, 19);
+ prt(fmt::format("Select a power (a-{}), +/- to scroll:", I2C(j - 1)), 0, 0);
}
@@ -1108,58 +1114,52 @@ static void print_power_batch(int *p, int start, int max)
* List powers and ask to pick one.
*/
-static power_type* select_power(int *x_idx)
+static boost::optional<int> select_power()
{
- char which;
- int max = 0, i, start = 0;
- power_type* ret;
- int p[POWER_MAX];
-
- /* Count the max */
- for (i = 0; i < POWER_MAX; i++)
- {
- if (p_ptr->powers[i])
- {
- p[max++] = i;
- }
- }
+ // Find selectable power indexes
+ std::vector<int> power_idxs;
+ std::copy(
+ std::begin(p_ptr->powers),
+ std::end(p_ptr->powers),
+ std::back_inserter(power_idxs));
+ std::sort(
+ std::begin(power_idxs),
+ std::end(power_idxs));
/* Exit if there aren't powers */
- if (max == 0)
+ if (power_idxs.empty())
{
- *x_idx = -1;
- ret = NULL;
msg_print("You don't have any special powers.");
+ return boost::none;
}
else
{
- character_icky = TRUE;
- Term_save();
-
- while (1)
+ int start = 0;
+ int const max = power_idxs.size();
+ // Save
+ screen_save_no_flush();
+ // Loop until we get a result.
+ boost::optional<int> result;
+ while (true)
{
- print_power_batch(p, start, max);
- which = inkey();
+ print_power_batch(power_idxs, start, max);
+ char which = inkey();
if (which == ESCAPE)
{
- *x_idx = -1;
- ret = NULL;
break;
}
else if (which == '+')
{
start += 20;
if (start >= max) start -= 20;
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
}
else if (which == '-')
{
start -= 20;
if (start < 0) start += 20;
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
}
else
{
@@ -1175,46 +1175,65 @@ static power_type* select_power(int *x_idx)
continue;
}
- *x_idx = p[start + A2I(which)];
- ret = &powers_type[p[start + A2I(which)]];
+ result = power_idxs[start + A2I(which)];
break;
}
}
- Term_load();
- character_icky = FALSE;
- }
- return ret;
+ screen_load_no_flush();
+
+ return result;
+ }
}
/* Ask & execute a power */
void do_cmd_power()
{
int x_idx;
- power_type *x_ptr;
- bool_ push = TRUE;
+ bool push = true;
/* Get the skill, if available */
if (repeat_pull(&x_idx))
{
- if ((x_idx < 0) || (x_idx >= POWER_MAX)) return;
- x_ptr = &powers_type[x_idx];
- push = FALSE;
+ if (!game->powers.count(x_idx))
+ {
+ return;
+ }
+
+ push = false;
+ }
+ else if (!command_arg)
+ {
+ if (auto i = select_power())
+ {
+ x_idx = *i;
+ }
+ else
+ {
+ return;
+ }
}
- else if (!command_arg) x_ptr = select_power(&x_idx);
else
{
x_idx = command_arg - 1;
- if ((x_idx < 0) || (x_idx >= POWER_MAX)) return;
- x_ptr = &powers_type[x_idx];
- }
- if (x_ptr == NULL) return;
+ if (!game->powers.count(x_idx))
+ {
+ return;
+ }
+ }
- if (push) repeat_push(x_idx);
+ if (push)
+ {
+ repeat_push(x_idx);
+ }
- if (p_ptr->powers[x_idx])
+ if (p_ptr->powers.count(x_idx))
+ {
power_activate(x_idx);
+ }
else
+ {
msg_print("You do not have access to this power.");
+ }
}
diff --git a/src/powers.hpp b/src/powers.hpp
index aa24e7d0..2fb4d134 100644
--- a/src/powers.hpp
+++ b/src/powers.hpp
@@ -22,7 +22,6 @@ void do_cmd_power();
#define PWR_SWAP_POS 12
#define PWR_SHRIEK 13
#define PWR_ILLUMINE 14
-#define PWR_DET_CURSE 15
#define PWR_BERSERK 16
#define PWR_POLYMORPH 17
#define PWR_MIDAS_TCH 18
diff --git a/src/program_args.cc b/src/program_args.cc
new file mode 100644
index 00000000..b4522d9d
--- /dev/null
+++ b/src/program_args.cc
@@ -0,0 +1 @@
+#include "program_args.hpp"
diff --git a/src/program_args.hpp b/src/program_args.hpp
new file mode 100644
index 00000000..00dbc793
--- /dev/null
+++ b/src/program_args.hpp
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <optional>
+#include <string>
+
+/**
+ * Program command line arguments.
+ */
+struct program_args {
+
+ /**
+ * Wizard mode?
+ */
+ bool wizard = false;
+
+ /**
+ * Force key set?
+ */
+ std::optional<char> force_key_set;
+
+ /**
+ * Character name.
+ */
+ std::string player_name;
+
+ /**
+ * Select the given module instead of prompting
+ * the user.
+ */
+ const char *module = nullptr;
+
+};
diff --git a/src/q_betwen.cc b/src/q_betwen.cc
index ca8243b4..d14c32d8 100644
--- a/src/q_betwen.cc
+++ b/src/q_betwen.cc
@@ -3,10 +3,12 @@
#include "cave.hpp"
#include "dungeon_flag.hpp"
#include "cave_type.hpp"
+#include "game.hpp"
#include "hook_chardump_in.hpp"
#include "hook_init_quest_in.hpp"
#include "hook_move_in.hpp"
#include "hook_quest_finish_in.hpp"
+#include "hook_quest_gen_in.hpp"
#include "hooks.hpp"
#include "init1.hpp"
#include "monster2.hpp"
@@ -16,9 +18,18 @@
#include "tables.hpp"
#include "util.hpp"
#include "variable.hpp"
+#include "z-term.hpp"
#define cquest (quest[QUEST_BETWEEN])
+static std::shared_ptr<object_kind> get_golden_horn()
+{
+ static auto &k_info = game->edit_data.k_info;
+ static auto &k_golden_horn = k_info[test_item_name("& Golden Horn~ of the Thunderlords")];
+
+ return k_golden_horn;
+}
+
static bool quest_between_move_hook(void *, void *in_, void *)
{
struct hook_move_in *in = static_cast<struct hook_move_in *>(in_);
@@ -66,11 +77,11 @@ static bool quest_between_move_hook(void *, void *in_, void *)
}
/* Mark as entered */
- cquest.data[0] = TRUE;
+ cquest.data[0] = true;
- p_ptr->wild_mode = FALSE;
+ p_ptr->wild_mode = false;
p_ptr->inside_quest = QUEST_BETWEEN;
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
cmsg_print(TERM_YELLOW, "Looks like a full wing of thunderlords ambushes you!");
cmsg_print(TERM_YELLOW, "Trone steps forth and speaks: 'The secret of the Void Jumpgates");
@@ -79,8 +90,10 @@ static bool quest_between_move_hook(void *, void *in_, void *)
return false;
}
-static bool quest_between_gen_hook(void *, void *, void *)
+static bool quest_between_gen_hook(void *, void *in_, void *)
{
+ auto in = static_cast<hook_quest_gen_in *>(in_);
+
int x, y;
int xstart = 2;
int ystart = 2;
@@ -101,18 +114,18 @@ static bool quest_between_gen_hook(void *, void *, void *)
dun_level = quest[p_ptr->inside_quest].level;
/* Set the correct monster hook */
- set_mon_num_hook();
+ reset_get_monster_hook();
/* Prepare allocation table */
get_mon_num_prep();
init_flags = INIT_CREATE_DUNGEON;
- process_dungeon_file("between.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, TRUE);
+ process_dungeon_file("between.map", &ystart, &xstart, cur_hgt, cur_wid, true, true);
/* Otherwise instadeath */
energy_use = 0;
- dungeon_flags |= DF_NO_GENO;
+ in->dungeon_flags_ref |= DF_NO_GENO;
return true;
}
@@ -137,20 +150,18 @@ static bool quest_between_finish_hook(void *, void *in_, void *)
/* Mega-Hack -- Actually create the Golden Horn of the Thunderlords */
- k_allow_special[test_item_name("& Golden Horn~ of the Thunderlords")] = TRUE;
- apply_magic(q_ptr, -1, TRUE, TRUE, TRUE);
- k_allow_special[test_item_name("& Golden Horn~ of the Thunderlords")] = FALSE;
- object_aware(q_ptr);
- object_known(q_ptr);
+ get_golden_horn()->allow_special = true;
+ apply_magic(q_ptr, -1, true, true, true);
+ get_golden_horn()->allow_special = false;
+
q_ptr->discount = 100;
- q_ptr->ident |= IDENT_STOREB;
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
/* Continue the plot */
*(quest[q_idx].plot) = QUEST_NULL;
del_hook_new(HOOK_QUEST_FINISH, quest_between_finish_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return true;
}
@@ -206,7 +217,7 @@ static bool quest_between_forbid_hook(void *, void *in_, void *)
hook_init_quest_in *in = static_cast<struct hook_init_quest_in *>(in_);
s32b q_idx = in->q_idx;
- if (q_idx != QUEST_BETWEEN) return (FALSE);
+ if (q_idx != QUEST_BETWEEN) return false;
if (p_ptr->lev < 45)
{
diff --git a/src/q_betwen.hpp b/src/q_betwen.hpp
index 54042a24..41949e95 100644
--- a/src/q_betwen.hpp
+++ b/src/q_betwen.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_between_init_hook();
diff --git a/src/q_bounty.cc b/src/q_bounty.cc
index f0a431de..4d1c64e8 100644
--- a/src/q_bounty.cc
+++ b/src/q_bounty.cc
@@ -20,39 +20,35 @@
#define bounty_quest_monster (cquest.data[0])
-static bool_ lua_mon_hook_bounty(int r_idx)
+static bool lua_mon_hook_bounty(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
-
/* Reject uniques */
- if (r_ptr->flags & RF_UNIQUE) return (FALSE);
+ if (r_ptr->flags & RF_UNIQUE) return false;
/* Reject those who cannot leave anything */
- if (!(r_ptr->flags & RF_DROP_CORPSE)) return (FALSE);
+ if (!(r_ptr->flags & RF_DROP_CORPSE)) return false;
/* Accept only monsters that can be generated */
- if (r_ptr->flags & RF_SPECIAL_GENE) return (FALSE);
- if (r_ptr->flags & RF_NEVER_GENE) return (FALSE);
+ if (r_ptr->flags & RF_SPECIAL_GENE) return false;
+ if (r_ptr->flags & RF_NEVER_GENE) return false;
/* Reject pets */
- if (r_ptr->flags & RF_PET) return (FALSE);
+ if (r_ptr->flags & RF_PET) return false;
/* Reject friendly creatures */
- if (r_ptr->flags & RF_FRIENDLY) return (FALSE);
+ if (r_ptr->flags & RF_FRIENDLY) return false;
/* Accept only monsters that are not breeders */
- if (r_ptr->spells & SF_MULTIPLY) return (FALSE);
+ if (r_ptr->spells & SF_MULTIPLY) return false;
/* Forbid joke monsters */
- if (r_ptr->flags & RF_JOKEANGBAND) return (FALSE);
+ if (r_ptr->flags & RF_JOKEANGBAND) return false;
/* Accept only monsters that are not good */
- if (r_ptr->flags & RF_GOOD) return (FALSE);
+ if (r_ptr->flags & RF_GOOD) return false;
/* The rest are acceptable */
- return (TRUE);
+ return true;
}
static int get_new_bounty_monster(int lev)
@@ -63,14 +59,14 @@ static int get_new_bounty_monster(int lev)
* Set up the hooks -- no bounties on uniques or monsters
* with no corpses
*/
- get_mon_num_hook = lua_mon_hook_bounty;
+ get_monster_hook = lua_mon_hook_bounty;
get_mon_num_prep();
/* Set up the quest monster. */
r_idx = get_mon_num(lev);
/* Undo the filters */
- get_mon_num_hook = NULL;
+ get_monster_hook = NULL;
get_mon_num_prep();
return r_idx;
@@ -86,7 +82,7 @@ void quest_bounty_init_hook()
// Initialized by building action
}
-bool_ quest_bounty_drop_item()
+void quest_bounty_drop_item()
{
char mdesc[512];
char msg[512];
@@ -106,29 +102,27 @@ bool_ quest_bounty_drop_item()
snprintf(msg, sizeof(msg), "You still must bring me back %s corpse.", mdesc);
msg_print(msg);
}
- return FALSE;
}
-bool_ quest_bounty_get_item()
+void quest_bounty_get_item()
{
auto &s_info = game->s_info;
if (cquest.status != QUEST_STATUS_TAKEN)
{
msg_print("You do not have any bounty quest yet.");
- return FALSE;
+ return;
}
// Get the corpse.
int item = -1;
- bool_ ret =
- get_item(&item,
- "What corpse to return?",
- "You have no corpse to return.",
- USE_INVEN,
- bounty_item_tester_hook);
- if (!ret) {
- return FALSE;
+ if (!get_item(&item,
+ "What corpse to return?",
+ "You have no corpse to return.",
+ USE_INVEN,
+ bounty_item_tester_hook))
+ {
+ return;
}
// Take the corpse from the inventory
@@ -160,7 +154,6 @@ bool_ quest_bounty_get_item()
// Need to ask for new quest.
cquest.status = QUEST_STATUS_UNTAKEN;
bounty_quest_monster = 0;
- return FALSE;
}
std::string quest_bounty_describe()
diff --git a/src/q_bounty.hpp b/src/q_bounty.hpp
index fe9742ef..9c959df7 100644
--- a/src/q_bounty.hpp
+++ b/src/q_bounty.hpp
@@ -1,10 +1,10 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include <string>
void quest_bounty_init_hook();
-bool_ quest_bounty_drop_item();
-bool_ quest_bounty_get_item();
+void quest_bounty_drop_item();
+void quest_bounty_get_item();
std::string quest_bounty_describe();
diff --git a/src/q_dragons.cc b/src/q_dragons.cc
index 9f89089c..6a4a19dd 100644
--- a/src/q_dragons.cc
+++ b/src/q_dragons.cc
@@ -7,6 +7,7 @@
#include "feature_type.hpp"
#include "game.hpp"
#include "hook_quest_finish_in.hpp"
+#include "hook_quest_gen_in.hpp"
#include "hooks.hpp"
#include "init1.hpp"
#include "monster2.hpp"
@@ -16,18 +17,20 @@
#include "util.hpp"
#include "variable.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#define cquest (quest[QUEST_DRAGONS])
-static bool quest_dragons_gen_hook(void *, void *, void *)
+static bool quest_dragons_gen_hook(void *, void *in_, void *)
{
+ auto in = static_cast<hook_quest_gen_in *>(in_);
auto const &f_info = game->edit_data.f_info;
int x, y, i;
int xstart = 2;
int ystart = 2;
- if (p_ptr->inside_quest != QUEST_DRAGONS) return FALSE;
+ if (p_ptr->inside_quest != QUEST_DRAGONS) return false;
/* Just in case we didnt talk the the mayor */
if (cquest.status == QUEST_STATUS_UNTAKEN)
@@ -45,14 +48,14 @@ static bool quest_dragons_gen_hook(void *, void *, void *)
dun_level = quest[p_ptr->inside_quest].level;
/* Set the correct monster hook */
- set_mon_num_hook();
+ reset_get_monster_hook();
/* Prepare allocation table */
get_mon_num_prep();
init_flags = INIT_CREATE_DUNGEON;
- process_dungeon_file("dragons.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, FALSE);
- dungeon_flags |= DF_NO_GENO;
+ process_dungeon_file("dragons.map", &ystart, &xstart, cur_hgt, cur_wid, true, false);
+ in->dungeon_flags_ref |= DF_NO_GENO;
/* Place some columns */
for (i = 35; i > 0; )
@@ -102,16 +105,16 @@ static bool quest_dragons_gen_hook(void *, void *, void *)
}
}
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
- return TRUE;
+ return true;
}
static bool quest_dragons_death_hook(void *, void *, void *)
{
int i, mcnt = 0;
- if (p_ptr->inside_quest != QUEST_DRAGONS) return FALSE;
+ if (p_ptr->inside_quest != QUEST_DRAGONS) return false;
/* Process the monsters (backwards) */
for (i = m_max - 1; i >= 1; i--)
@@ -137,7 +140,7 @@ static bool quest_dragons_death_hook(void *, void *, void *)
quest[p_ptr->inside_quest].status = QUEST_STATUS_COMPLETED;
del_hook_new(HOOK_MONSTER_DEATH, quest_dragons_death_hook);
del_hook_new(HOOK_GEN_QUEST, quest_dragons_gen_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
cmsg_print(TERM_YELLOW, "Gondolin is safer now.");
return false;
diff --git a/src/q_dragons.hpp b/src/q_dragons.hpp
index cda41321..f290b6ac 100644
--- a/src/q_dragons.hpp
+++ b/src/q_dragons.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_dragons_init_hook();
diff --git a/src/q_eol.cc b/src/q_eol.cc
index 815b3107..fd60ff37 100644
--- a/src/q_eol.cc
+++ b/src/q_eol.cc
@@ -18,6 +18,7 @@
#include "util.hpp"
#include "variable.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#include <cassert>
@@ -28,7 +29,6 @@ GENERATE_MONSTER_LOOKUP_FN(get_eol, "Eol, the Dark Elf")
static bool quest_eol_gen_hook(void *, void *, void *)
{
int x, y;
- bool_ done = FALSE;
int xsize = 50, ysize = 30, y0, x0;
int m_idx = 0;
@@ -59,6 +59,7 @@ static bool quest_eol_gen_hook(void *, void *, void *)
}
dun_level = quest[p_ptr->inside_quest].level;
+ bool done = false;
while (!done)
{
int grd, roug, cutoff;
@@ -76,7 +77,7 @@ static bool quest_eol_gen_hook(void *, void *, void *)
generate_hmap(y0, x0, xsize, ysize, grd, roug, cutoff);
/* Convert to normal format+ clean up*/
- done = generate_fracave(y0, x0, xsize, ysize, cutoff, FALSE, TRUE);
+ done = generate_fracave(y0, x0, xsize, ysize, cutoff, false, true);
}
/* Place a few traps */
@@ -91,9 +92,9 @@ static bool quest_eol_gen_hook(void *, void *, void *)
// Find Eol's r_info entry
int r_idx = get_eol();
// "Summon" Eol
- m_allow_special[r_idx] = TRUE;
- m_idx = place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_ENEMY);
- m_allow_special[r_idx] = FALSE;
+ m_allow_special[r_idx] = true;
+ m_idx = place_monster_one(y, x, r_idx, 0, false, MSTATUS_ENEMY);
+ m_allow_special[r_idx] = false;
// Mark with the QUEST flag
if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST;
}
@@ -126,19 +127,16 @@ static bool quest_eol_finish_hook(void *, void *in_, void *)
object_prep(q_ptr, lookup_kind(TV_LITE, SV_LITE_DWARVEN));
q_ptr->found = OBJ_FOUND_REWARD;
q_ptr->name2 = EGO_LITE_MAGI;
- apply_magic(q_ptr, 1, FALSE, FALSE, FALSE);
+ apply_magic(q_ptr, 1, false, false, false);
q_ptr->number = 1;
- object_aware(q_ptr);
- object_known(q_ptr);
- q_ptr->ident |= IDENT_STOREB;
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
/* Continue the plot */
*(quest[q_idx].plot) = QUEST_NIRNAETH;
quest[*(quest[q_idx].plot)].init();
del_hook_new(HOOK_QUEST_FINISH, quest_eol_finish_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return true;
}
@@ -159,7 +157,7 @@ static bool quest_eol_fail_hook(void *, void *in_, void *)
*(quest[q_idx].plot) = QUEST_NULL;
del_hook_new(HOOK_QUEST_FAIL, quest_eol_fail_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return true;
}
@@ -181,7 +179,7 @@ static bool quest_eol_death_hook(void *, void *in_, void *)
cquest.status = QUEST_STATUS_COMPLETED;
del_hook_new(HOOK_MONSTER_DEATH, quest_eol_death_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return false;
}
@@ -222,7 +220,7 @@ static bool quest_eol_stair_hook(void *, void *in_, void *)
cquest.status = QUEST_STATUS_FAILED;
del_hook_new(HOOK_STAIR, quest_eol_stair_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return false;
}
}
diff --git a/src/q_eol.hpp b/src/q_eol.hpp
index 19af3583..3f92b80f 100644
--- a/src/q_eol.hpp
+++ b/src/q_eol.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_eol_init_hook();
diff --git a/src/q_evil.cc b/src/q_evil.cc
index 4636356a..55f2dcfd 100644
--- a/src/q_evil.cc
+++ b/src/q_evil.cc
@@ -7,6 +7,7 @@
#include "feature_type.hpp"
#include "game.hpp"
#include "hook_quest_finish_in.hpp"
+#include "hook_quest_gen_in.hpp"
#include "hooks.hpp"
#include "init1.hpp"
#include "monster2.hpp"
@@ -16,11 +17,13 @@
#include "util.hpp"
#include "variable.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#define cquest (quest[QUEST_EVIL])
-static bool quest_evil_gen_hook(void *, void *, void *)
+static bool quest_evil_gen_hook(void *, void *in_, void *)
{
+ auto in = static_cast<hook_quest_gen_in *>(in_);
auto const &f_info = game->edit_data.f_info;
int x, y, i;
@@ -50,14 +53,14 @@ static bool quest_evil_gen_hook(void *, void *, void *)
dun_level = quest[p_ptr->inside_quest].level;
/* Set the correct monster hook */
- set_mon_num_hook();
+ reset_get_monster_hook();
/* Prepare allocation table */
get_mon_num_prep();
init_flags = INIT_CREATE_DUNGEON;
- process_dungeon_file("evil.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, FALSE);
- dungeon_flags |= DF_NO_GENO;
+ process_dungeon_file("evil.map", &ystart, &xstart, cur_hgt, cur_wid, true, false);
+ in->dungeon_flags_ref |= DF_NO_GENO;
/* Place some random balrogs */
for (i = 6; i > 0; )
@@ -67,13 +70,13 @@ static bool quest_evil_gen_hook(void *, void *, void *)
auto const flags = f_info[cave[y][x].feat].flags;
if (!(flags & FF_PERMANENT) && (flags & FF_FLOOR))
{
- int m_idx = place_monster_one(y, x, 996, 0, FALSE, MSTATUS_ENEMY);
+ int m_idx = place_monster_one(y, x, 996, 0, false, MSTATUS_ENEMY);
if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST;
--i;
}
}
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return true;
}
@@ -108,7 +111,7 @@ static bool quest_evil_death_hook(void *, void *, void *)
del_hook_new(HOOK_MONSTER_DEATH, quest_evil_death_hook);
del_hook_new(HOOK_GEN_QUEST, quest_evil_gen_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
cmsg_print(TERM_YELLOW, "Khazad-Dum is safer now.");
return false;
diff --git a/src/q_evil.hpp b/src/q_evil.hpp
index 0079e56c..010aec3d 100644
--- a/src/q_evil.hpp
+++ b/src/q_evil.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_evil_init_hook();
diff --git a/src/q_fireprof.cc b/src/q_fireprof.cc
index 26bf75af..430e172e 100644
--- a/src/q_fireprof.cc
+++ b/src/q_fireprof.cc
@@ -5,6 +5,7 @@
#include "feature_flag.hpp"
#include "feature_type.hpp"
#include "hook_get_in.hpp"
+#include "hook_quest_gen_in.hpp"
#include "hooks.hpp"
#include "lua_bind.hpp"
#include "object1.hpp"
@@ -16,6 +17,7 @@
#include "util.hpp"
#include "variable.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#include <cassert>
#include <fmt/format.h>
@@ -30,8 +32,8 @@ struct fireproof_settings
{
byte tval; /* tval of object to use. */
byte sval; /* sval of object to use. */
- cptr tval_name; /* descriptive name of tval */
- cptr tval_name_plural; /* descriptive name of tval (plural) */
+ const char *tval_name; /* descriptive name of tval */
+ const char *tval_name_plural; /* descriptive name of tval (plural) */
s32b total_points; /* total number of points awarded */
};
@@ -88,7 +90,7 @@ static object_filter_t const &item_tester_hook_proofable()
/*
* This function makes sure the player has enough 'points' left to fireproof stuff.
*/
-static bool_ fireproof_enough_points(object_type *o_ptr, int *stack)
+static bool fireproof_enough_points(object_type *o_ptr, int *stack)
{
int item_value;
@@ -117,14 +119,14 @@ static bool_ fireproof_enough_points(object_type *o_ptr, int *stack)
item_value = FIREPROOF_SCROLL_POINTS * (*stack);
break;
default:
- assert(FALSE);
+ assert(false);
}
/* do we have enough points? */
if (item_value > get_item_points_remaining())
{
msg_print("I do not have enough fireproofing material for that.");
- return FALSE;
+ return false;
}
else
{
@@ -138,10 +140,10 @@ static bool_ fireproof_enough_points(object_type *o_ptr, int *stack)
cquest.status = QUEST_STATUS_REWARDED;
}
- return TRUE;
+ return true;
}
-static bool_ fireproof()
+static bool fireproof()
{
int item;
if (!get_item(&item,
@@ -150,7 +152,7 @@ static bool_ fireproof()
USE_INVEN,
item_tester_hook_proofable()))
{
- return FALSE;
+ return false;
}
/* get the object type from the number */
@@ -160,12 +162,12 @@ static bool_ fireproof()
int stack = 0;
if (!fireproof_enough_points(obj2, &stack))
{
- return FALSE;
+ return false;
}
/* Do the actual fireproofing */
{
- bool_ carry_it;
+ bool carry_it;
object_type *obj3;
object_type obj_forge;
s32b oldpval, oldpval2, oldpval3;
@@ -184,7 +186,7 @@ static bool_ fireproof()
obj3 = &obj_forge;
/* we'll need to add this to the inventory after fireproofing */
- carry_it = TRUE;
+ carry_it = true;
}
else
{
@@ -192,7 +194,7 @@ static bool_ fireproof()
obj3 = obj2;
/* we'll be dealing this while it's still in the inventory */
- carry_it = FALSE;
+ carry_it = false;
}
/* make it fireproof */
@@ -203,27 +205,27 @@ static bool_ fireproof()
oldpval = obj3->pval;
oldpval2 = obj3->pval2;
oldpval3 = obj3->pval3;
- apply_magic(obj3, -1, FALSE, FALSE, FALSE);
+ apply_magic(obj3, -1, false, false, false);
obj3->pval = oldpval;
obj3->pval2 = oldpval2;
obj3->pval3 = oldpval3;
/* put it in the inventory if it's only part of a stack */
- if (carry_it == TRUE)
+ if (carry_it == true)
{
- inven_carry(obj3, TRUE);
+ inven_carry(obj3, true);
}
/* id and notice it */
- object_known(obj3);
object_aware(obj3);
+ object_known(obj3);
- return TRUE;
+ return true;
}
}
-void quest_fireproof_building(bool_ *paid, bool_ *recreate)
+void quest_fireproof_building(bool *paid, bool *recreate)
{
fireproof_settings const *settings = fireproof_get_settings();
int num_books, num_staff, num_scroll;
@@ -244,8 +246,8 @@ void quest_fireproof_building(bool_ *paid, bool_ *recreate)
msg_print("fetch it myself. Please bring it back to me. You can find it north of here.");
msg_print("Be careful with it, it's fragile and might be destroyed easily.");
- *paid = FALSE;
- *recreate = TRUE;
+ *paid = false;
+ *recreate = true;
}
/* if quest completed (item was retrieved) */
@@ -277,8 +279,8 @@ void quest_fireproof_building(bool_ *paid, bool_ *recreate)
/* take item */
inc_stack_size_ex(item_idx, -1, OPTIMIZE, NO_DESCRIBE);
- msg_print(format("Great! Let me fireproof some of your items in thanks. I can do %d books, ", num_books));
- msg_print(format("%d staves, or %d scrolls.", num_staff, num_scroll));
+ msg_print(fmt::format("Great! Let me fireproof some of your items in thanks. I can do {} books, ", num_books));
+ msg_print(fmt::format("{} staves, or {} scrolls.", num_staff, num_scroll));
/* how many items to proof? */
items = get_item_points_remaining();
@@ -289,7 +291,7 @@ void quest_fireproof_building(bool_ *paid, bool_ *recreate)
ret = fireproof();
/* don't loop the fireproof if there's nothing to fireproof */
- if (ret == FALSE)
+ if (ret == false)
{
break;
}
@@ -332,7 +334,7 @@ void quest_fireproof_building(bool_ *paid, bool_ *recreate)
int ret = fireproof();
/* don't loop the fireproof if there's nothing to fireproof */
- if (ret == FALSE)
+ if (ret == false)
{
break;
}
@@ -390,7 +392,7 @@ static bool fireproof_stair_hook(void *, void *, void *)
}
else
{
- bool_ ret;
+ bool ret;
if (cave[p_ptr->py][p_ptr->px].feat != FEAT_LESS)
{
@@ -404,7 +406,7 @@ static bool fireproof_stair_hook(void *, void *, void *)
ret = get_check("Really abandon the quest?");
/* if yes, then */
- if (ret == TRUE)
+ if (ret == true)
{
/* fail the quest */
cquest.status = QUEST_STATUS_FAILED;
@@ -458,9 +460,10 @@ std::string quest_fireproof_describe()
return w.str();
}
-static bool fireproof_gen_hook(void *, void *, void *)
+static bool fireproof_gen_hook(void *, void *in_, void *)
{
fireproof_settings const *settings = fireproof_get_settings();
+ auto in = static_cast<hook_quest_gen_in *>(in_);
/* Only if player doing this quest */
if (p_ptr->inside_quest != QUEST_FIREPROOF)
@@ -478,7 +481,7 @@ static bool fireproof_gen_hook(void *, void *, void *)
}
/* no teleport */
- dungeon_flags = DF_NO_TELEPORT;
+ in->dungeon_flags_ref |= DF_NO_TELEPORT;
/* create quest item */
{
diff --git a/src/q_fireprof.hpp b/src/q_fireprof.hpp
index 361d45ad..98e4851e 100644
--- a/src/q_fireprof.hpp
+++ b/src/q_fireprof.hpp
@@ -1,9 +1,9 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include <string>
-void quest_fireproof_building(bool_ *paid, bool_ *recreate);
+void quest_fireproof_building(bool *paid, bool *recreate);
void quest_fireproof_init_hook();
std::string quest_fireproof_describe();
diff --git a/src/q_god.cc b/src/q_god.cc
index 68296f36..8c6b4cc0 100644
--- a/src/q_god.cc
+++ b/src/q_god.cc
@@ -22,8 +22,9 @@
#include "wilderness_map.hpp"
#include "wilderness_type_info.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
-#include <assert.h>
+#include <cassert>
#include <fmt/format.h>
#define cquest (quest[QUEST_GOD])
@@ -139,7 +140,7 @@ static int MAX_NUM_GOD_QUESTS()
return 7;
}
/* Uh, oh. */
- assert(FALSE);
+ assert(false);
return 0;
}
@@ -169,7 +170,7 @@ static byte get_relic_num()
}
/* Uh, oh. */
- assert(FALSE);
+ assert(false);
}
static void get_home_coordinates(int *home1_y, int *home1_x, const char **home1,
@@ -224,7 +225,7 @@ static void get_home_coordinates(int *home1_y, int *home1_x, const char **home1,
}
else
{
- assert(FALSE); /* Uh, oh */
+ assert(false); /* Uh, oh */
}
}
@@ -234,7 +235,8 @@ static std::string make_directions(bool feel_it)
int home2_y, home2_x;
const char *home1 = NULL;
const char *home2 = NULL;
- cptr feel_it_str = feel_it ? ", I can feel it.'" : ".";
+ const char *feel_it_str = feel_it ? ", I can feel it.'" : ".";
+ std::string dir_string;
get_home_coordinates(
&home1_y, &home1_x, &home1,
@@ -246,33 +248,36 @@ static std::string make_directions(bool feel_it)
/* Build the message */
if (home1_axis.empty())
{
- return fmt::format("The temple lies very close to {}, ",
+ dir_string = fmt::format("The temple lies very close to {},",
home1);
}
else
{
auto home1_distance = approximate_distance(home1_y, home1_x, cquest_dung_y, cquest_dung_x);
- return fmt::format("The temple lies {} to the {} of {}, ",
+ dir_string = fmt::format("The temple lies {} to the {} of {},",
home1_distance,
home1_axis,
home1);
}
+ dir_string += feel_it ? " " : "\n";
+
if (home2_axis.empty())
{
- return fmt::format("and very close to {}{}",
+ dir_string += fmt::format("and very close to {}{}",
home2,
feel_it_str);
}
else
{
auto home2_distance = approximate_distance(home2_y, home2_x, cquest_dung_y, cquest_dung_x);
- return fmt::format("and {} to the {} of {}{}",
+ dir_string += fmt::format("and {} to the {} of {}{}",
home2_distance,
home2_axis,
home2,
feel_it_str);
}
+ return dir_string;
}
std::string quest_god_describe()
@@ -401,7 +406,7 @@ static void quest_god_generate_relic()
if (inven_carry_okay(&relic))
{
- inven_carry(&relic, FALSE);
+ inven_carry(&relic, false);
}
else
{
@@ -416,7 +421,7 @@ static void quest_god_generate_relic()
}
/* Only generate once! */
- cquest_relic_generated = TRUE;
+ cquest_relic_generated = true;
/* Reset some variables */
cquest_relic_gen_tries = 0;
@@ -915,7 +920,7 @@ static bool quest_god_level_end_gen_hook(void *, void *, void *)
therefore the player has caused another level generation in
the temple and hence failed the quest.*/
- else if ((cquest_relic_generated == TRUE) &&
+ else if ((cquest_relic_generated == true) &&
(cquest.status != QUEST_STATUS_FAILED))
{
/* fail the quest, don't give another one, don't give
@@ -937,7 +942,7 @@ static bool quest_god_level_end_gen_hook(void *, void *, void *)
* unsuccessful. */
else if ((cquest_relic_gen_tries == 4) &&
- (cquest_relic_generated == FALSE))
+ (cquest_relic_generated == false))
{
quest_god_generate_relic();
}
@@ -974,7 +979,7 @@ static bool quest_god_player_level_hook(void *, void *in_, void *)
(cquest.status == QUEST_STATUS_TAKEN) ||
(cquest.status == QUEST_STATUS_FAILED) ||
(cquest_quests_given >= MAX_NUM_GOD_QUESTS()) ||
- (magik(CHANCE_OF_GOD_QUEST) == FALSE) ||
+ (magik(CHANCE_OF_GOD_QUEST) == false) ||
((dungeon_type == DUNGEON_GOD) &&
(dun_level > 0)) ||
(p_ptr->lev <= cquest_dun_minplev))
@@ -990,7 +995,7 @@ static bool quest_god_player_level_hook(void *, void *in_, void *)
{
/* This var will need resetting */
cquest.status = QUEST_STATUS_TAKEN;
- cquest_relic_generated = FALSE;
+ cquest_relic_generated = false;
cquest_quests_given = cquest_quests_given + 1;
/* actually place the dungeon in a random place */
@@ -1034,7 +1039,7 @@ static bool quest_god_get_hook(void *, void *in_, void *)
if ((cquest.status == QUEST_STATUS_TAKEN) &&
(o_ptr->tval == TV_JUNK) &&
(o_ptr->sval == get_relic_num()) &&
- (o_ptr->pval != TRUE) &&
+ (o_ptr->pval != true) &&
(cquest_relics_found < cquest_quests_given))
{
cmsg_format(TERM_L_BLUE, "%s speaks to you:", deity_info[p_ptr->pgod].name);
@@ -1063,7 +1068,7 @@ static bool quest_god_get_hook(void *, void *in_, void *)
inc_stack_size_ex(item, -1, OPTIMIZE, NO_DESCRIBE);
/* relic piece has been identified */
- o_ptr->pval = TRUE;
+ o_ptr->pval = true;
cquest_relics_found = cquest_relics_found + 1;
/* Make sure quests can be given again if neccesary */
@@ -1086,7 +1091,7 @@ static bool quest_god_char_dump_hook(void *, void *in_, void *)
{
int relics = cquest_relics_found;
char relics_text[128];
- cptr append_text = "";
+ const char *append_text = "";
snprintf(relics_text, sizeof(relics_text), "%d", relics);
@@ -1156,7 +1161,7 @@ static void set_god_dungeon_attributes()
}
else
{
- assert(FALSE); /* Uh, oh! */
+ assert(false); /* Uh, oh! */
}
/* W: All dungeons are 5 levels deep, and created at 2/3 of
@@ -1208,7 +1213,7 @@ static bool quest_god_birth_objects_hook(void *, void *, void *)
cquest_dun_maxdepth = 4;
cquest_dun_minplev = 0;
cquest_relic_gen_tries = 0;
- cquest_relic_generated = FALSE;
+ cquest_relic_generated = false;
return false;
}
diff --git a/src/q_god.hpp b/src/q_god.hpp
index 839d4eaa..b44b41a2 100644
--- a/src/q_god.hpp
+++ b/src/q_god.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include <string>
diff --git a/src/q_haunted.cc b/src/q_haunted.cc
index f460ee80..6dc54457 100644
--- a/src/q_haunted.cc
+++ b/src/q_haunted.cc
@@ -7,6 +7,7 @@
#include "feature_type.hpp"
#include "game.hpp"
#include "hook_quest_finish_in.hpp"
+#include "hook_quest_gen_in.hpp"
#include "hooks.hpp"
#include "init1.hpp"
#include "monster2.hpp"
@@ -16,11 +17,13 @@
#include "util.hpp"
#include "variable.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#define cquest (quest[QUEST_HAUNTED])
-static bool quest_haunted_gen_hook(void *, void *, void *)
+static bool quest_haunted_gen_hook(void *, void *in_, void *)
{
+ auto in = static_cast<hook_quest_gen_in *>(in_);
auto const &f_info = game->edit_data.f_info;
int x, y, i, m_idx;
@@ -48,14 +51,14 @@ static bool quest_haunted_gen_hook(void *, void *, void *)
dun_level = quest[p_ptr->inside_quest].level;
/* Set the correct monster hook */
- set_mon_num_hook();
+ reset_get_monster_hook();
/* Prepare allocation table */
get_mon_num_prep();
init_flags = INIT_CREATE_DUNGEON;
- process_dungeon_file("haunted.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, FALSE);
- dungeon_flags |= DF_NO_GENO;
+ process_dungeon_file("haunted.map", &ystart, &xstart, cur_hgt, cur_wid, true, false);
+ in->dungeon_flags_ref |= DF_NO_GENO;
/* Place some ghosts */
for (i = 12; i > 0; )
@@ -65,7 +68,7 @@ static bool quest_haunted_gen_hook(void *, void *, void *)
auto const flags = f_info[cave[y][x].feat].flags;
if (!(flags & FF_PERMANENT) && (flags & FF_FLOOR))
{
- m_idx = place_monster_one(y, x, 477, 0, FALSE, MSTATUS_ENEMY);
+ m_idx = place_monster_one(y, x, 477, 0, false, MSTATUS_ENEMY);
if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST;
--i;
}
@@ -82,13 +85,13 @@ static bool quest_haunted_gen_hook(void *, void *, void *)
int monsters[22] = { 65, 100, 124, 125, 133, 231, 273, 327, 365, 416, 418,
507, 508, 533, 534, 553, 554, 555, 577, 607, 622, 665};
int monster = monsters[rand_int(22)];
- m_idx = place_monster_one(y, x, monster, 0, FALSE, MSTATUS_ENEMY);
+ m_idx = place_monster_one(y, x, monster, 0, false, MSTATUS_ENEMY);
m_list[m_idx].mflag |= MFLAG_QUEST;
--i;
}
}
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return true;
}
@@ -127,7 +130,7 @@ static bool quest_haunted_death_hook(void *, void *, void *)
del_hook_new(HOOK_MONSTER_DEATH, quest_haunted_death_hook);
del_hook_new(HOOK_GEN_QUEST, quest_haunted_gen_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
cmsg_print(TERM_YELLOW, "Minas Anor is safer now.");
return false;
diff --git a/src/q_haunted.hpp b/src/q_haunted.hpp
index 3965f0c3..11783642 100644
--- a/src/q_haunted.hpp
+++ b/src/q_haunted.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_haunted_init_hook();
diff --git a/src/q_hobbit.cc b/src/q_hobbit.cc
index 655755a3..39d76594 100644
--- a/src/q_hobbit.cc
+++ b/src/q_hobbit.cc
@@ -18,8 +18,10 @@
#include "util.hpp"
#include "variable.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#include <cassert>
+#include <fmt/format.h>
#define cquest (quest[QUEST_HOBBIT])
@@ -28,11 +30,10 @@ GENERATE_MONSTER_LOOKUP_FN(get_merton_proudfoot, "Merton Proudfoot, the lost hob
static bool quest_hobbit_town_gen_hook(void *, void *in_, void *)
{
- struct hook_wild_gen_in *in = static_cast<struct hook_wild_gen_in *>(in_);
+ auto in = static_cast<struct hook_wild_gen_in const *>(in_);
int x = 1, y = 1, tries = 10000;
- bool_ small = in->small;
- if ((turn < (cquest.data[1] + (DAY * 10L))) || (cquest.status > QUEST_STATUS_COMPLETED) || (small) || (p_ptr->town_num != 1))
+ if ((turn < (cquest.data[1] + (DAY * 10L))) || (cquest.status > QUEST_STATUS_COMPLETED) || in->small || (p_ptr->town_num != 1))
{
return false;
}
@@ -55,9 +56,9 @@ static bool quest_hobbit_town_gen_hook(void *, void *in_, void *)
/* Place Melinda */
int r_idx = get_melinda_proudfoot();
- m_allow_special[r_idx] = TRUE;
- place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_ENEMY);
- m_allow_special[r_idx] = FALSE;
+ m_allow_special[r_idx] = true;
+ place_monster_one(y, x, r_idx, 0, false, MSTATUS_ENEMY);
+ m_allow_special[r_idx] = false;
return false;
}
@@ -87,9 +88,9 @@ static bool quest_hobbit_gen_hook(void *, void *, void *)
/* Place the hobbit */
int r_idx = get_merton_proudfoot();
- m_allow_special[r_idx] = TRUE;
- place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_FRIEND);
- m_allow_special[r_idx] = FALSE;
+ m_allow_special[r_idx] = true;
+ place_monster_one(y, x, r_idx, 0, false, MSTATUS_FRIEND);
+ m_allow_special[r_idx] = false;
return false;
}
@@ -119,7 +120,7 @@ static bool quest_hobbit_give_hook(void *, void *in_, void *)
cquest.status = QUEST_STATUS_COMPLETED;
del_hook_new(HOOK_GIVE, quest_hobbit_give_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return true;
}
@@ -175,15 +176,12 @@ static bool quest_hobbit_chat_hook(void *, void *in_, void *)
object_prep(q_ptr, lookup_kind(TV_ROD, SV_ROD_RECALL));
q_ptr->number = 1;
q_ptr->found = OBJ_FOUND_REWARD;
- object_aware(q_ptr);
- object_known(q_ptr);
- q_ptr->ident |= IDENT_STOREB;
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
cquest.status = QUEST_STATUS_FINISHED;
del_hook_new(HOOK_MON_SPEAK, quest_hobbit_speak_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
delete_monster_idx(m_idx);
return true;
@@ -219,7 +217,7 @@ void quest_hobbit_init_hook()
cquest.data[1] = turn;
if (wizard)
{
- messages.add(format("Hobbit level %d", cquest.data[0]), TERM_BLUE);
+ messages.add(fmt::format("Hobbit level {}", cquest.data[0]), TERM_BLUE);
}
}
diff --git a/src/q_hobbit.hpp b/src/q_hobbit.hpp
index c3482fd9..f8e297a5 100644
--- a/src/q_hobbit.hpp
+++ b/src/q_hobbit.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_hobbit_init_hook();
diff --git a/src/q_invas.cc b/src/q_invas.cc
index 60ca0b65..e561e657 100644
--- a/src/q_invas.cc
+++ b/src/q_invas.cc
@@ -16,6 +16,7 @@
#include "town_type.hpp"
#include "util.hpp"
#include "variable.hpp"
+#include "z-term.hpp"
#define cquest (quest[QUEST_INVASION])
@@ -41,13 +42,13 @@ static bool quest_invasion_gen_hook(void *, void *, void *)
dun_level = quest[p_ptr->inside_quest].level;
/* Set the correct monster hook */
- set_mon_num_hook();
+ reset_get_monster_hook();
/* Prepare allocation table */
get_mon_num_prep();
init_flags = INIT_CREATE_DUNGEON;
- process_dungeon_file("maeglin.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, TRUE);
+ process_dungeon_file("maeglin.map", &ystart, &xstart, cur_hgt, cur_wid, true, true);
for (x = 3; x < xstart; x++)
{
@@ -89,7 +90,7 @@ static bool quest_invasion_ai_hook(void *, void *in_, void *out_)
cmsg_print(TERM_YELLOW, "Maeglin found the way to Gondolin! All hope is lost now!");
cquest.status = QUEST_STATUS_FAILED;
- town_info[2].destroyed = TRUE;
+ town_info[2].destroyed = true;
return false;
}
@@ -111,14 +112,14 @@ static bool quest_invasion_ai_hook(void *, void *in_, void *out_)
static bool quest_invasion_turn_hook(void *, void *, void *)
{
- if (cquest.status != QUEST_STATUS_UNTAKEN) return (FALSE);
- if (p_ptr->lev < 45) return (FALSE);
+ if (cquest.status != QUEST_STATUS_UNTAKEN) return false;
+ if (p_ptr->lev < 45) return false;
/* Wait until the end of the current quest */
- if (p_ptr->inside_quest) return ( FALSE);
+ if (p_ptr->inside_quest) return ( false);
/* Wait until the end of the astral mode */
- if (p_ptr->astral) return ( FALSE);
+ if (p_ptr->astral) return ( false);
/* Ok give the quest */
cmsg_print(TERM_YELLOW, "A Thunderlord appears in front of you and says:");
@@ -130,7 +131,7 @@ static bool quest_invasion_turn_hook(void *, void *, void *)
quest_invasion_init_hook();
del_hook_new(HOOK_END_TURN, quest_invasion_turn_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return false;
}
@@ -168,7 +169,7 @@ static bool quest_invasion_death_hook(void *, void *in_, void *)
cquest.status = QUEST_STATUS_COMPLETED;
del_hook_new(HOOK_MONSTER_DEATH, quest_invasion_death_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return false;
}
@@ -180,9 +181,9 @@ static bool quest_invasion_stair_hook(void *, void *in_, void *)
{
struct hook_stair_in *in = static_cast<struct hook_stair_in *>(in_);
- if (p_ptr->inside_quest != QUEST_INVASION) return FALSE;
+ if (p_ptr->inside_quest != QUEST_INVASION) return false;
- if (cave[p_ptr->py][p_ptr->px].feat != FEAT_LESS) return TRUE;
+ if (cave[p_ptr->py][p_ptr->px].feat != FEAT_LESS) return true;
if (in->direction == STAIRS_UP)
{
@@ -205,13 +206,13 @@ static bool quest_invasion_stair_hook(void *, void *in_, void *)
/* Flush input */
flush();
- if (!get_check("Really abandon the quest?")) return TRUE;
+ if (!get_check("Really abandon the quest?")) return true;
cmsg_print(TERM_YELLOW, "You flee away from Maeglin and his army...");
cquest.status = QUEST_STATUS_FAILED;
- town_info[2].destroyed = TRUE;
+ town_info[2].destroyed = true;
}
del_hook_new(HOOK_STAIR, quest_invasion_stair_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return false;
}
diff --git a/src/q_invas.hpp b/src/q_invas.hpp
index dc2d8780..8a062a75 100644
--- a/src/q_invas.hpp
+++ b/src/q_invas.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_invasion_init_hook();
diff --git a/src/q_library.cc b/src/q_library.cc
index e267e2b7..e72aa024 100644
--- a/src/q_library.cc
+++ b/src/q_library.cc
@@ -4,6 +4,7 @@
#include "dungeon_flag.hpp"
#include "game.hpp"
#include "hooks.hpp"
+#include "hook_quest_gen_in.hpp"
#include "lua_bind.hpp"
#include "monster2.hpp"
#include "monster_type.hpp"
@@ -13,8 +14,6 @@
#include "spells4.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "z-rand.hpp"
@@ -63,7 +62,6 @@ void initialize_bookable_spells()
push_spell(SENSEMONSTERS);
push_spell(SENSEHIDDEN);
push_spell(REVEALWAYS);
- push_spell(IDENTIFY);
push_spell(VISION);
push_spell(MAGELOCK);
push_spell(SLOWMONSTER);
@@ -105,7 +103,7 @@ static s16b library_quest_place_random(int minY, int minX, int maxY, int maxX, i
{
int y = randint(maxY - minY + 1) + minY;
int x = randint(maxX - minX + 1) + minX;
- return place_monster_one(y, x, r_idx, 0, TRUE, MSTATUS_ENEMY);
+ return place_monster_one(y, x, r_idx, 0, true, MSTATUS_ENEMY);
}
static void library_quest_place_nrandom(int minY, int minX, int maxY, int maxX, int r_idx, int n)
@@ -142,17 +140,17 @@ static int library_quest_book_slots_left()
}
}
-static bool_ library_quest_book_contains_spell(int spell)
+static bool library_quest_book_contains_spell(int spell)
{
int i;
for (i = 1; i <= 3; i++)
{
if (library_quest_book_get_slot(i) == spell)
{
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
static void quest_library_finalize_book()
@@ -208,7 +206,7 @@ static void library_quest_print_spells(int first, int current)
} else if (slots == 1) {
c_prt(TERM_L_BLUE, "The book can hold 1 more spell.", 2, 0);
} else {
- c_prt(TERM_L_BLUE, format("The book can hold %d more spells.", slots), 2, 0);
+ c_prt(TERM_L_BLUE, fmt::format("The book can hold {} more spells.", slots), 2, 0);
}
row = 3;
@@ -238,7 +236,7 @@ static void library_quest_print_spells(int first, int current)
static void library_quest_fill_book()
{
int width, height, margin, first, current;
- bool_ done;
+ bool done;
/* Always start with a cleared book */
library_quest_book_set_slot(1, -1);
@@ -253,9 +251,9 @@ static void library_quest_fill_book()
first = 0;
current = 0;
- done = FALSE;
+ done = false;
- while (done == FALSE)
+ while (done == false)
{
char ch;
int dir, spell_idx;
@@ -272,7 +270,7 @@ static void library_quest_fill_book()
flush();
done = get_check("Really create the book?");
} else {
- done = TRUE;
+ done = true;
}
} else if (ch == '\r') {
/* TODO: make tree of schools */
@@ -288,7 +286,7 @@ static void library_quest_fill_book()
} else if (dir == 8) {
current = current - 1;
} else if (dir == 6) {
- if (library_quest_book_contains_spell(spell_idx) == FALSE)
+ if (library_quest_book_contains_spell(spell_idx) == false)
{
library_quest_add_spell(spell_idx);
}
@@ -312,8 +310,10 @@ static void library_quest_fill_book()
screen_load();
}
-static bool quest_library_gen_hook(void *, void *, void *)
+static bool quest_library_gen_hook(void *, void *in_, void *)
{
+ auto in = static_cast<hook_quest_gen_in *>(in_);
+
/* Only if player doing this quest */
if (p_ptr->inside_quest != QUEST_LIBRARY)
{
@@ -324,7 +324,7 @@ static bool quest_library_gen_hook(void *, void *, void *)
int y = 2;
int x = 2;
load_map("library.map", &y, &x);
- dungeon_flags = DF_NO_GENO;
+ in->dungeon_flags_ref |= DF_NO_GENO;
}
/* Generate monsters */
@@ -419,7 +419,7 @@ static bool quest_library_monster_death_hook(void *, void *, void *)
return false;
}
-void quest_library_building(bool_ *paid, bool_ *recreate)
+void quest_library_building(bool *paid, bool *recreate)
{
int status = cquest.status;
@@ -433,8 +433,8 @@ void quest_library_building(bool_ *paid, bool_ *recreate)
msg_print("I need get some stock from my main library, but it is infested with monsters!");
msg_print("Please use the side entrance and vanquish the intruders for me.");
- *paid = FALSE;
- *recreate = TRUE;
+ *paid = false;
+ *recreate = true;
}
/* if quest completed */
@@ -453,9 +453,7 @@ void quest_library_building(bool_ *paid, bool_ *recreate)
object_prep(q_ptr, lookup_kind(TV_BOOK, 61));
q_ptr->artifact_name = game->player_name;
q_ptr->found = OBJ_FOUND_REWARD;
- object_aware(q_ptr);
- object_known(q_ptr);
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
}
quest_library_finalize_book();
diff --git a/src/q_library.hpp b/src/q_library.hpp
index 266accc3..3555c580 100644
--- a/src/q_library.hpp
+++ b/src/q_library.hpp
@@ -1,10 +1,10 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include <string>
void quest_library_init_hook();
std::string quest_library_describe();
-void quest_library_building(bool_ *paid, bool_ *recreate);
+void quest_library_building(bool *paid, bool *recreate);
void initialize_bookable_spells();
diff --git a/src/q_main.cc b/src/q_main.cc
index 2d3473f1..b40f5471 100644
--- a/src/q_main.cc
+++ b/src/q_main.cc
@@ -12,6 +12,7 @@
#include "tables.hpp"
#include "util.hpp"
#include "variable.hpp"
+#include "z-term.hpp"
#include <cassert>
@@ -97,7 +98,7 @@ static bool quest_morgoth_hook(void *, void *, void *)
/* Continue the plot(maybe) */
del_hook_new(HOOK_MONSTER_DEATH, quest_morgoth_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
/* Either ultra good if the one Ring is destroyed, or ultra evil if used */
if (quest[QUEST_ONE].status == QUEST_STATUS_FINISHED)
@@ -158,7 +159,7 @@ static bool quest_sauron_hook(void *, void *, void *)
*(quest[QUEST_SAURON].plot) = QUEST_MORGOTH;
quest_morgoth_init_hook();
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
}
return false;
@@ -215,7 +216,7 @@ static bool quest_necro_hook(void *, void *, void *)
quest[*(quest[QUEST_NECRO].plot)].init();
del_hook_new(HOOK_MONSTER_DEATH, quest_necro_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
}
return false;
diff --git a/src/q_main.hpp b/src/q_main.hpp
index be33897b..8d2b1540 100644
--- a/src/q_main.hpp
+++ b/src/q_main.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_necro_init_hook();
void quest_sauron_init_hook();
diff --git a/src/q_narsil.cc b/src/q_narsil.cc
index 8d3c2775..298b4580 100644
--- a/src/q_narsil.cc
+++ b/src/q_narsil.cc
@@ -11,6 +11,7 @@
#include "tables.hpp"
#include "util.hpp"
#include "variable.hpp"
+#include "z-term.hpp"
#define cquest (quest[QUEST_NARSIL])
@@ -37,11 +38,17 @@ static bool quest_narsil_move_hook(void *, void *in_, void *)
/* Look out for Narsil */
for (i = 0; i < INVEN_TOTAL; i++)
{
- o_ptr = get_object(i);
+ o_ptr = &p_ptr->inventory[i];
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
- if (o_ptr->name1 == ART_NARSIL) break;
+ if (o_ptr->name1 == ART_NARSIL)
+ {
+ break;
+ }
}
if (i == INVEN_TOTAL)
@@ -59,7 +66,7 @@ static bool quest_narsil_move_hook(void *, void *in_, void *)
object_prep(o_ptr, lookup_kind(TV_SWORD, SV_LONG_SWORD));
o_ptr->name1 = ART_ANDURIL;
- apply_magic(o_ptr, -1, TRUE, TRUE, TRUE);
+ apply_magic(o_ptr, -1, true, true, true);
object_aware(o_ptr);
object_known(o_ptr);
inven_item_describe(i);
@@ -72,7 +79,7 @@ static bool quest_narsil_move_hook(void *, void *in_, void *)
cquest.status = QUEST_STATUS_FINISHED;
del_hook_new(HOOK_MOVE, quest_narsil_move_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return true;
}
@@ -109,7 +116,7 @@ static bool quest_narsil_identify_hook(void *, void *in_, void *)
add_hook_new(HOOK_MOVE, quest_narsil_move_hook, "narsil_move", NULL);
del_hook_new(HOOK_IDENTIFY, quest_narsil_identify_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
}
}
diff --git a/src/q_narsil.hpp b/src/q_narsil.hpp
index da0fa85d..3964b2e2 100644
--- a/src/q_narsil.hpp
+++ b/src/q_narsil.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_narsil_init_hook();
diff --git a/src/q_nazgul.cc b/src/q_nazgul.cc
index 99735eed..6eda1db1 100644
--- a/src/q_nazgul.cc
+++ b/src/q_nazgul.cc
@@ -15,6 +15,7 @@
#include "util.hpp"
#include "variable.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#include <cassert>
@@ -24,11 +25,10 @@ GENERATE_MONSTER_LOOKUP_FN(get_uvatha, "Uvatha the Horseman")
static bool quest_nazgul_gen_hook(void *, void *in_, void *)
{
- struct hook_wild_gen_in *in = static_cast<struct hook_wild_gen_in *>(in_);
+ auto in = static_cast<struct hook_wild_gen_in const *>(in_);
int m_idx, x = 1, y = 1, tries = 10000;
- bool_ small = in->small;
- if ((cquest.status != QUEST_STATUS_TAKEN) || (small) || (p_ptr->town_num != 1))
+ if ((cquest.status != QUEST_STATUS_TAKEN) || in->small || (p_ptr->town_num != 1))
{
return false;
}
@@ -51,9 +51,9 @@ static bool quest_nazgul_gen_hook(void *, void *in_, void *)
/* Place the nazgul */
int r_idx = get_uvatha();
- m_allow_special[r_idx] = TRUE;
- m_idx = place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_ENEMY);
- m_allow_special[r_idx] = FALSE;
+ m_allow_special[r_idx] = true;
+ m_idx = place_monster_one(y, x, r_idx, 0, false, MSTATUS_ENEMY);
+ m_allow_special[r_idx] = false;
if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST;
@@ -79,16 +79,13 @@ static bool quest_nazgul_finish_hook(void *, void *in_, void *)
object_prep(q_ptr, lookup_kind(TV_FOOD, SV_FOOD_ATHELAS));
q_ptr->found = OBJ_FOUND_REWARD;
q_ptr->number = 6;
- object_aware(q_ptr);
- object_known(q_ptr);
- q_ptr->ident |= IDENT_STOREB;
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
/* End the plot */
*(quest[q_idx].plot) = QUEST_NULL;
del_hook_new(HOOK_QUEST_FINISH, quest_nazgul_finish_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return true;
}
@@ -143,7 +140,7 @@ static bool quest_nazgul_death_hook(void *, void *in_, void *)
cquest.status = QUEST_STATUS_COMPLETED;
del_hook_new(HOOK_MONSTER_DEATH, quest_nazgul_death_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return false;
}
diff --git a/src/q_nazgul.hpp b/src/q_nazgul.hpp
index ad35e5b3..d4c6b703 100644
--- a/src/q_nazgul.hpp
+++ b/src/q_nazgul.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_nazgul_init_hook();
diff --git a/src/q_nirna.cc b/src/q_nirna.cc
index 822d8b6c..a036bfa3 100644
--- a/src/q_nirna.cc
+++ b/src/q_nirna.cc
@@ -10,6 +10,7 @@
#include "tables.hpp"
#include "util.hpp"
#include "variable.hpp"
+#include "z-term.hpp"
#define cquest (quest[QUEST_NIRNAETH])
@@ -35,13 +36,13 @@ static bool quest_nirnaeth_gen_hook(void *, void *, void *)
dun_level = quest[p_ptr->inside_quest].level;
/* Set the correct monster hook */
- set_mon_num_hook();
+ reset_get_monster_hook();
/* Prepare allocation table */
get_mon_num_prep();
init_flags = INIT_CREATE_DUNGEON;
- process_dungeon_file("nirnaeth.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, TRUE);
+ process_dungeon_file("nirnaeth.map", &ystart, &xstart, cur_hgt, cur_wid, true, true);
/* Count the number of monsters */
cquest.data[0] = 0;
@@ -92,14 +93,14 @@ static bool quest_nirnaeth_finish_hook(void *, void *in_, void *)
*(quest[q_idx].plot) = QUEST_NULL;
del_hook_new(HOOK_QUEST_FINISH, quest_nirnaeth_finish_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return true;
}
static bool quest_nirnaeth_death_hook(void *, void *, void *)
{
- if (p_ptr->inside_quest != QUEST_NIRNAETH) return FALSE;
+ if (p_ptr->inside_quest != QUEST_NIRNAETH) return false;
cquest.data[1]++;
@@ -122,7 +123,7 @@ static bool quest_nirnaeth_stair_hook(void *, void *, void *)
cquest.status = QUEST_STATUS_COMPLETED;
del_hook_new(HOOK_STAIR, quest_nirnaeth_stair_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return false;
}
diff --git a/src/q_nirna.hpp b/src/q_nirna.hpp
index 1aaeae54..9045d00b 100644
--- a/src/q_nirna.hpp
+++ b/src/q_nirna.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_nirnaeth_init_hook();
diff --git a/src/q_one.cc b/src/q_one.cc
index 8985b695..6c48c442 100644
--- a/src/q_one.cc
+++ b/src/q_one.cc
@@ -24,6 +24,7 @@
#include "util.hpp"
#include "variable.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#define cquest (quest[QUEST_ONE])
@@ -185,11 +186,11 @@ static bool quest_one_wield_hook(void *, void *in_, void *)
* Towns aren't, right ?
* So let's destroy them !
*/
- town_info[1].destroyed = TRUE;
- town_info[2].destroyed = TRUE;
- town_info[3].destroyed = TRUE;
- town_info[4].destroyed = TRUE;
- town_info[5].destroyed = TRUE;
+ town_info[1].destroyed = true;
+ town_info[2].destroyed = true;
+ town_info[3].destroyed = true;
+ town_info[4].destroyed = true;
+ town_info[5].destroyed = true;
/* Continue the plot */
cquest.status = QUEST_STATUS_FAILED_DONE;
@@ -321,13 +322,13 @@ static bool quest_one_death_hook(void *, void *in_, void *)
q_ptr->name1 = ART_POWER;
/* Mega-Hack -- Actually create "the one ring" */
- apply_magic(q_ptr, -1, TRUE, TRUE, TRUE);
+ apply_magic(q_ptr, -1, true, true, true);
/* Find a space */
for (i = 0; i < INVEN_PACK; i++)
{
/* Skip non-objects */
- if (!p_ptr->inventory[i].k_idx)
+ if (!p_ptr->inventory[i].k_ptr)
{
break;
}
@@ -337,17 +338,17 @@ static bool quest_one_death_hook(void *, void *in_, void *)
{
char o_name[200];
- object_desc(o_name, &p_ptr->inventory[INVEN_PACK - 1], FALSE, 0);
+ object_desc(o_name, &p_ptr->inventory[INVEN_PACK - 1], false, 0);
/* Drop the item */
- inven_drop(INVEN_PACK - 1, 99, p_ptr->py, p_ptr->px, FALSE);
+ inven_drop(INVEN_PACK - 1, 99, p_ptr->py, p_ptr->px, false);
cmsg_format(TERM_VIOLET, "You feel the urge to drop your %s to make room in your inventory.", o_name);
}
/* Carry it */
cmsg_format(TERM_VIOLET, "You feel the urge to pick up that plain gold ring you see.");
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
}
return false;
@@ -399,7 +400,7 @@ static bool quest_one_gen_hook(void *, void *, void *)
if (tries)
{
- int m_idx = place_monster_one(y, x, test_monster_name("Sauron, the Sorcerer"), 0, FALSE, MSTATUS_ENEMY);
+ int m_idx = place_monster_one(y, x, test_monster_name("Sauron, the Sorcerer"), 0, false, MSTATUS_ENEMY);
if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST;
}
diff --git a/src/q_one.hpp b/src/q_one.hpp
index 13389968..ce6478e2 100644
--- a/src/q_one.hpp
+++ b/src/q_one.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_one_init_hook();
diff --git a/src/q_poison.cc b/src/q_poison.cc
index e7f1c71b..b190ccaa 100644
--- a/src/q_poison.cc
+++ b/src/q_poison.cc
@@ -20,6 +20,9 @@
#include "util.hpp"
#include "variable.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
+
+#include <fmt/format.h>
#define cquest (quest[QUEST_POISON])
@@ -31,24 +34,21 @@ static int wild_locs[4][2] =
{ 34, 48, },
};
-static bool_ create_molds_hook(int r_idx)
+static bool create_molds_hook(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
-
- auto r_ptr = &r_info[r_idx];
+ if (r_ptr->spells & SF_MULTIPLY) return false;
- if (r_ptr->spells & SF_MULTIPLY) return FALSE;
+ if (r_ptr->d_char == 'm') return true;
+ if (r_ptr->d_char == ',') return true;
+ if (r_ptr->d_char == 'e') return true;
- if (r_ptr->d_char == 'm') return TRUE;
- else if (r_ptr->d_char == ',') return TRUE;
- else if (r_ptr->d_char == 'e') return TRUE;
- else return FALSE;
+ return false;
}
static bool quest_poison_gen_hook(void *, void *, void *)
{
int cy = 1, cx = 1, x, y, tries = 10000, r_idx;
- bool_ (*old_get_mon_num_hook)(int r_idx);
+ bool (*old_get_monster_hook)(monster_race const *);
if (cquest.status != QUEST_STATUS_TAKEN)
{
@@ -87,10 +87,10 @@ static bool quest_poison_gen_hook(void *, void *, void *)
/* Place the baddies */
/* Backup the old hook */
- old_get_mon_num_hook = get_mon_num_hook;
+ old_get_monster_hook = get_monster_hook;
/* Require "okay" monsters */
- get_mon_num_hook = create_molds_hook;
+ get_monster_hook = create_molds_hook;
/* Prepare allocation table */
get_mon_num_prep();
@@ -125,7 +125,7 @@ static bool quest_poison_gen_hook(void *, void *, void *)
int m_idx;
r_idx = get_mon_num(30);
- m_idx = place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_ENEMY);
+ m_idx = place_monster_one(y, x, r_idx, 0, false, MSTATUS_ENEMY);
if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST;
/* Sometimes make it up some levels */
@@ -136,7 +136,7 @@ static bool quest_poison_gen_hook(void *, void *, void *)
if (m_ptr->level < p_ptr->lev)
{
m_ptr->exp = monster_exp(m_ptr->level + randint(p_ptr->lev - m_ptr->level));
- monster_check_experience(m_idx, TRUE);
+ monster_check_experience(m_idx, true);
}
}
}
@@ -144,7 +144,7 @@ static bool quest_poison_gen_hook(void *, void *, void *)
}
/* Reset restriction */
- get_mon_num_hook = old_get_mon_num_hook;
+ get_monster_hook = old_get_monster_hook;
/* Prepare allocation table */
get_mon_num_prep();
@@ -171,17 +171,15 @@ static bool quest_poison_finish_hook(void *, void *in_, void *)
q_ptr->found = OBJ_FOUND_REWARD;
q_ptr->number = 1;
q_ptr->name2 = EGO_ELVENKIND;
- apply_magic(q_ptr, 1, FALSE, FALSE, FALSE);
- object_aware(q_ptr);
- object_known(q_ptr);
- q_ptr->ident |= IDENT_STOREB;
- inven_carry(q_ptr, FALSE);
+ apply_magic(q_ptr, 1, false, false, false);
+
+ inven_carry(q_ptr, false);
/* Continue the plot */
*(quest[q_idx].plot) = QUEST_NULL;
del_hook_new(HOOK_QUEST_FINISH, quest_poison_finish_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return true;
}
@@ -212,15 +210,12 @@ static bool quest_poison_quest_hook(void *, void *in_, void *)
q_ptr = &forge;
object_prep(q_ptr, lookup_kind(TV_POTION2, SV_POTION2_CURE_WATER));
q_ptr->number = 99;
- object_aware(q_ptr);
- object_known(q_ptr);
- q_ptr->ident |= IDENT_STOREB;
q_ptr->inscription = "quest";
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
del_hook_new(HOOK_INIT_QUEST, quest_poison_quest_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return false;
}
@@ -298,7 +293,7 @@ static bool quest_poison_drop_hook(void *, void *in_, void *)
cquest.status = QUEST_STATUS_COMPLETED;
del_hook_new(HOOK_DROP, quest_poison_drop_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return false;
}
@@ -317,11 +312,11 @@ void quest_poison_init_hook()
/* Get a place to place the poison */
if (!cquest.data[1])
{
- cquest.data[1] = TRUE;
+ cquest.data[1] = true;
cquest.data[0] = rand_int(4);
if (wizard)
{
- messages.add(format("Wilderness poison %d, %d", wild_locs[cquest.data[0]][0], wild_locs[cquest.data[0]][1]), TERM_BLUE);
+ messages.add(fmt::format("Wilderness poison {}, {}", wild_locs[cquest.data[0]][0], wild_locs[cquest.data[0]][1]), TERM_BLUE);
}
}
diff --git a/src/q_poison.hpp b/src/q_poison.hpp
index 6c4e771b..02d0fe00 100644
--- a/src/q_poison.hpp
+++ b/src/q_poison.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_poison_init_hook();
diff --git a/src/q_rand.cc b/src/q_rand.cc
index b643ca39..8c244d0b 100644
--- a/src/q_rand.cc
+++ b/src/q_rand.cc
@@ -31,6 +31,7 @@
#include "util.hpp"
#include "variable.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#include <cassert>
#include <fmt/format.h>
@@ -105,7 +106,7 @@ void initialize_random_quests(int n)
/* XXX XXX XXX Try until valid choice is found */
while (tries)
{
- bool_ ok;
+ bool ok;
tries--;
@@ -146,12 +147,12 @@ void initialize_random_quests(int n)
}
/* Assume no explosion attacks */
- ok = TRUE;
+ ok = true;
/* Reject monsters with exploding attacks */
for (k = 0; k < 4; k++)
{
- if (r_ptr->blow[k].method == RBM_EXPLODE) ok = FALSE;
+ if (r_ptr->blow[k].method == RBM_EXPLODE) ok = false;
}
if (!ok) continue;
@@ -174,7 +175,7 @@ void initialize_random_quests(int n)
{
if (wizard)
{
- messages.add(format("Could not find quest monster on lvl %d", rl), TERM_RED);
+ messages.add(fmt::format("Could not find quest monster on lvl {}", rl), TERM_RED);
}
q_ptr->type = 0;
}
@@ -189,7 +190,7 @@ void initialize_random_quests(int n)
if (wizard)
{
- messages.add(format("Quest for %d on lvl %d", q_ptr->r_idx, rl), TERM_RED);
+ messages.add(fmt::format("Quest for {} on lvl {}", q_ptr->r_idx, rl), TERM_RED);
}
}
@@ -199,16 +200,16 @@ void initialize_random_quests(int n)
dungeon_type = old_type;
}
-bool_ is_randhero(int level)
+bool is_randhero(int level)
{
int i;
- bool_ result = FALSE;
+ bool result = false;
for (i = 0; randquest_hero[i] != -1; i++)
{
if (random_quests[level].type == randquest_hero[i])
{
- result = TRUE;
+ result = true;
break;
}
}
@@ -218,7 +219,6 @@ bool_ is_randhero(int level)
static void do_get_new_obj(int y, int x)
{
- auto &k_info = game->edit_data.k_info;
auto &a_info = game->edit_data.a_info;
object_type *q_ptr[3], forge[3];
@@ -235,7 +235,7 @@ static void do_get_new_obj(int y, int x)
object_wipe(q_ptr[i]);
/* Make a great object */
- make_object(q_ptr[i], TRUE, TRUE, obj_theme::no_theme());
+ make_object(q_ptr[i], true, true, obj_theme::no_theme());
q_ptr[i]->found = OBJ_FOUND_REWARD;
char buf[100];
@@ -244,7 +244,7 @@ static void do_get_new_obj(int y, int x)
}
- while (TRUE)
+ while (true)
{
res = ask_menu("Choose a reward to get(a-c to choose, ESC to cancel)?", items);
@@ -270,11 +270,11 @@ static void do_get_new_obj(int y, int x)
/* Mega-Hack -- Preserve the artifact */
if (o_ptr->tval == TV_RANDART)
{
- game->random_artifacts[o_ptr->sval].generated = FALSE;
+ game->random_artifacts[o_ptr->sval].generated = false;
}
- else if (k_info[o_ptr->k_idx].flags & TR_NORM_ART)
+ else if (o_ptr->k_ptr->flags & TR_NORM_ART)
{
- k_info[o_ptr->k_idx].artifact = FALSE;
+ o_ptr->k_ptr->artifact = false;
}
else if (o_ptr->name1)
{
@@ -369,11 +369,6 @@ static void hero_death(s32b m_idx, s32b r_idx)
/* Nor on the between */
if (cave[y][x].feat == FEAT_BETWEEN) continue;
- /* ... nor on the Pattern */
- if ((cave[y][x].feat >= FEAT_PATTERN_START) &&
- (cave[y][x].feat <= FEAT_PATTERN_XTRA2))
- continue;
-
/* Okay */
break;
}
@@ -382,15 +377,15 @@ static void hero_death(s32b m_idx, s32b r_idx)
{
int r_idx = get_adventurer();
- m_allow_special[r_idx] = TRUE;
- int m_idx = place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_COMPANION);
- m_allow_special[r_idx] = FALSE;
+ m_allow_special[r_idx] = true;
+ int m_idx = place_monster_one(y, x, r_idx, 0, false, MSTATUS_COMPANION);
+ m_allow_special[r_idx] = false;
if (m_idx)
{
m_list[m_idx].exp = monster_exp(1 + (dun_level * 3 / 2));
m_list[m_idx].status = MSTATUS_COMPANION;
- monster_check_experience(m_idx, TRUE);
+ monster_check_experience(m_idx, true);
}
}
else
@@ -409,6 +404,7 @@ static bool quest_random_death_hook(void *, void *in_, void *)
struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_);
s32b m_idx = in->m_idx;
int r_idx = m_list[m_idx].r_idx;
+ auto const &dungeon_flags = game->dungeon_flags;
if ((!(dungeon_flags & DF_PRINCIPAL)) ||
((dun_level < 1) || (dun_level >= MAX_RANDOM_QUEST)) ||
@@ -447,6 +443,7 @@ static bool quest_random_turn_hook(void *, void *, void *)
static bool quest_random_feeling_hook(void *, void *, void *)
{
+ auto const &dungeon_flags = game->dungeon_flags;
auto const &r_info = game->edit_data.r_info;
if ((!(dungeon_flags & DF_PRINCIPAL)) ||
@@ -473,6 +470,8 @@ static bool quest_random_feeling_hook(void *, void *, void *)
static bool quest_random_gen_hero_hook(void *, void *, void *)
{
+ auto const &dungeon_flags = game->dungeon_flags;
+
if ((!(dungeon_flags & DF_PRINCIPAL)) ||
((dun_level < 1) || (dun_level >= MAX_RANDOM_QUEST)) ||
(!random_quests[dun_level].type) ||
@@ -485,12 +484,12 @@ static bool quest_random_gen_hero_hook(void *, void *, void *)
int i = random_quests[dun_level].type;
- m_allow_special[random_quests[dun_level].r_idx] = TRUE;
+ m_allow_special[random_quests[dun_level].r_idx] = true;
while (i)
{
int m_idx, y = rand_range(1, cur_hgt - 2), x = rand_range(1, cur_wid - 2);
- m_idx = place_monster_one(y, x, random_quests[dun_level].r_idx, 0, FALSE, MSTATUS_ENEMY);
+ m_idx = place_monster_one(y, x, random_quests[dun_level].r_idx, 0, false, MSTATUS_ENEMY);
if (m_idx)
{
monster_type *m_ptr = &m_list[m_idx];
@@ -498,7 +497,7 @@ static bool quest_random_gen_hero_hook(void *, void *, void *)
i--;
}
}
- m_allow_special[random_quests[dun_level].r_idx] = FALSE;
+ m_allow_special[random_quests[dun_level].r_idx] = false;
return false;
}
@@ -506,6 +505,8 @@ static bool quest_random_gen_hero_hook(void *, void *, void *)
static bool quest_random_gen_hook(void *, void *in_, void *)
{
struct hook_build_room1_in *in = static_cast<struct hook_build_room1_in *>(in_);
+ auto const &dungeon_flags = game->dungeon_flags;
+
s32b bx0 = in->x;
s32b by0 = in->y;
s32b x, y;
@@ -526,10 +527,10 @@ static bool quest_random_gen_hook(void *, void *in_, void *)
}
/* Pick a room size */
- get_map_size(format("qrand%d.map", random_quests[dun_level].type), &ysize, &xsize);
+ get_map_size(fmt::format("qrand{}.map", random_quests[dun_level].type).c_str(), &ysize, &xsize);
/* Try to allocate space for room. If fails, exit */
- if (!room_alloc(xsize + 2, ysize + 2, FALSE, by0, bx0, &xval, &yval))
+ if (!room_alloc(xsize + 2, ysize + 2, false, by0, bx0, &xval, &yval))
{
return false;
}
@@ -553,7 +554,7 @@ static bool quest_random_gen_hook(void *, void *in_, void *)
build_rectangle(y1 - 1, x1 - 1, y2 + 1, x2 + 1, feat_wall_outer, CAVE_ROOM | CAVE_GLOW);
/* Set the correct monster hook */
- set_mon_num_hook();
+ reset_get_monster_hook();
/* Prepare allocation table */
get_mon_num_prep();
@@ -561,7 +562,7 @@ static bool quest_random_gen_hook(void *, void *in_, void *)
xstart = x1;
ystart = y1;
init_flags = INIT_CREATE_DUNGEON;
- process_dungeon_file(format("qrand%d.map", random_quests[dun_level].type), &ystart, &xstart, cur_hgt, cur_wid, TRUE, TRUE);
+ process_dungeon_file(fmt::format("qrand{}.map", random_quests[dun_level].type).c_str(), &ystart, &xstart, cur_hgt, cur_wid, true, true);
for (x = x1; x < xstart; x++)
{
@@ -570,9 +571,9 @@ static bool quest_random_gen_hook(void *, void *in_, void *)
cave[y][x].info |= CAVE_ICKY | CAVE_ROOM;
if (cave[y][x].feat == FEAT_MARKER)
{
- m_allow_special[random_quests[dun_level].r_idx] = TRUE;
- int i = place_monster_one(y, x, random_quests[dun_level].r_idx, 0, FALSE, MSTATUS_ENEMY);
- m_allow_special[random_quests[dun_level].r_idx] = FALSE;
+ m_allow_special[random_quests[dun_level].r_idx] = true;
+ int i = place_monster_one(y, x, random_quests[dun_level].r_idx, 0, false, MSTATUS_ENEMY);
+ m_allow_special[random_quests[dun_level].r_idx] = false;
if (i)
{
auto m_ptr = &m_list[i];
@@ -640,6 +641,7 @@ static bool quest_random_dump_hook(void *, void *in_, void *)
std::string quest_random_describe()
{
auto const &r_info = game->edit_data.r_info;
+ auto const &dungeon_flags = game->dungeon_flags;
// Only emit description if we're actually on a
// random quest level.
diff --git a/src/q_rand.hpp b/src/q_rand.hpp
index a992aa98..0ca7b035 100644
--- a/src/q_rand.hpp
+++ b/src/q_rand.hpp
@@ -1,10 +1,10 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include <string>
void initialize_random_quests(int n);
-bool_ is_randhero(int level);
+bool is_randhero(int level);
void quest_random_init_hook();
std::string quest_random_describe();
diff --git a/src/q_shroom.cc b/src/q_shroom.cc
index 627f2b39..10347512 100644
--- a/src/q_shroom.cc
+++ b/src/q_shroom.cc
@@ -18,8 +18,10 @@
#include "util.hpp"
#include "variable.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#include <cassert>
+#include <fmt/format.h>
#define cquest (quest[QUEST_SHROOM])
@@ -33,12 +35,11 @@ GENERATE_MONSTER_LOOKUP_FN(get_farmer_maggot, "Farmer Maggot")
static bool quest_shroom_town_gen_hook(void *, void *in_, void *)
{
- struct hook_wild_gen_in *in = static_cast<struct hook_wild_gen_in *>(in_);
+ auto in = static_cast<struct hook_wild_gen_in const *>(in_);
int m_idx, x = 1, y = 1, tries = 10000;
- bool_ small = in->small;
/* Generate the shrooms field */
- if ((!small) && (p_ptr->wilderness_y == 21) && (p_ptr->wilderness_x == 33))
+ if ((!in->small) && (p_ptr->wilderness_y == 21) && (p_ptr->wilderness_x == 33))
{
/* Create the field */
for (x = (cur_wid / 2) - 7; x <= (cur_wid / 2) + 7; x++)
@@ -64,30 +65,30 @@ static bool quest_shroom_town_gen_hook(void *, void *in_, void *)
/* Throw in some dogs ;) */
y = rand_range((cur_hgt / 2) - 5, (cur_hgt / 2) + 5);
x = rand_range((cur_wid / 2) - 7, (cur_wid / 2) + 7);
- m_allow_special[get_grip()] = TRUE;
- m_idx = place_monster_one(y, x, get_grip(), 0, FALSE, MSTATUS_ENEMY);
+ m_allow_special[get_grip()] = true;
+ m_idx = place_monster_one(y, x, get_grip(), 0, false, MSTATUS_ENEMY);
if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST;
- m_allow_special[get_grip()] = FALSE;
+ m_allow_special[get_grip()] = false;
y = rand_range((cur_hgt / 2) - 5, (cur_hgt / 2) + 5);
x = rand_range((cur_wid / 2) - 7, (cur_wid / 2) + 7);
- m_allow_special[get_wolf()] = TRUE;
- m_idx = place_monster_one(y, x, get_wolf(), 0, FALSE, MSTATUS_ENEMY);
+ m_allow_special[get_wolf()] = true;
+ m_idx = place_monster_one(y, x, get_wolf(), 0, false, MSTATUS_ENEMY);
if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST;
- m_allow_special[get_wolf()] = FALSE;
+ m_allow_special[get_wolf()] = false;
y = rand_range((cur_hgt / 2) - 5, (cur_hgt / 2) + 5);
x = rand_range((cur_wid / 2) - 7, (cur_wid / 2) + 7);
- m_allow_special[get_fang()] = TRUE;
- m_idx = place_monster_one(y, x, get_fang(), 0, FALSE, MSTATUS_ENEMY);
+ m_allow_special[get_fang()] = true;
+ m_idx = place_monster_one(y, x, get_fang(), 0, false, MSTATUS_ENEMY);
if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST;
- m_allow_special[get_fang()] = FALSE;
+ m_allow_special[get_fang()] = false;
msg_print("You hear frenzied barking.");
}
/* Generate maggot in town, in daylight */
- if ((bst(HOUR, turn) < 6) || (bst(HOUR, turn) >= 18) || (cquest.status > QUEST_STATUS_COMPLETED) || (small) || (p_ptr->town_num != 1))
+ if ((bst(HOUR, turn) < 6) || (bst(HOUR, turn) >= 18) || (cquest.status > QUEST_STATUS_COMPLETED) || in->small || (p_ptr->town_num != 1))
{
return false;
}
@@ -112,9 +113,9 @@ static bool quest_shroom_town_gen_hook(void *, void *in_, void *)
}
/* Place Farmer Maggot */
- m_allow_special[get_farmer_maggot()] = TRUE;
- place_monster_one(y, x, get_farmer_maggot(), 0, FALSE, MSTATUS_ENEMY);
- m_allow_special[get_farmer_maggot()] = FALSE;
+ m_allow_special[get_farmer_maggot()] = true;
+ place_monster_one(y, x, get_farmer_maggot(), 0, false, MSTATUS_ENEMY);
+ m_allow_special[get_farmer_maggot()] = false;
return false;
}
@@ -172,7 +173,7 @@ static bool quest_shroom_give_hook(void *, void *in_, void *)
del_hook_new(HOOK_GIVE, quest_shroom_give_hook);
del_hook_new(HOOK_CHAT, quest_shroom_speak_hook);
del_hook_new(HOOK_WILD_GEN, quest_shroom_town_gen_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return true;
}
@@ -201,10 +202,10 @@ static bool quest_shroom_give_hook(void *, void *in_, void *)
object_aware(q_ptr);
object_known(q_ptr);
q_ptr->discount = 100;
- q_ptr->ident |= IDENT_STOREB;
+
if (inven_carry_okay(q_ptr))
{
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
}
else
{
@@ -217,19 +218,16 @@ static bool quest_shroom_give_hook(void *, void *in_, void *)
q_ptr->found = OBJ_FOUND_REWARD;
q_ptr->number = 1;
q_ptr->name1 = 149;
- apply_magic(q_ptr, -1, TRUE, TRUE, TRUE);
- object_aware(q_ptr);
- object_known(q_ptr);
+ apply_magic(q_ptr, -1, true, true, true);
q_ptr->discount = 100;
- q_ptr->ident |= IDENT_STOREB;
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
delete_monster_idx(m_idx);
cquest.status = QUEST_STATUS_FINISHED;
del_hook_new(HOOK_GIVE, quest_shroom_give_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
}
else
{
@@ -256,7 +254,7 @@ static void check_dogs_alive(s32b m_idx)
del_hook_new(HOOK_MON_SPEAK, quest_shroom_speak_hook);
del_hook_new(HOOK_CHAT, quest_shroom_chat_hook);
del_hook_new(HOOK_WILD_GEN, quest_shroom_town_gen_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
}
else
{
@@ -328,7 +326,7 @@ void quest_shroom_init_hook()
cquest.data[1] = rand_range(7, 14);
if (wizard)
{
- messages.add(format("Shrooms number %d", cquest.data[1]), TERM_BLUE);
+ messages.add(fmt::format("Shrooms number {}", cquest.data[1]), TERM_BLUE);
}
}
diff --git a/src/q_shroom.hpp b/src/q_shroom.hpp
index 4478aee2..53fe7b4f 100644
--- a/src/q_shroom.hpp
+++ b/src/q_shroom.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_shroom_init_hook();
diff --git a/src/q_spider.cc b/src/q_spider.cc
index a5fa3486..8fc6e874 100644
--- a/src/q_spider.cc
+++ b/src/q_spider.cc
@@ -13,6 +13,7 @@
#include "tables.hpp"
#include "util.hpp"
#include "variable.hpp"
+#include "z-term.hpp"
#define cquest (quest[QUEST_SPIDER])
@@ -38,13 +39,13 @@ static bool quest_spider_gen_hook(void *, void *, void *)
dun_level = quest[p_ptr->inside_quest].level;
/* Set the correct monster hook */
- set_mon_num_hook();
+ reset_get_monster_hook();
/* Prepare allocation table */
get_mon_num_prep();
init_flags = INIT_CREATE_DUNGEON;
- process_dungeon_file("spiders.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, TRUE);
+ process_dungeon_file("spiders.map", &ystart, &xstart, cur_hgt, cur_wid, true, true);
return true;
}
@@ -89,7 +90,7 @@ static bool quest_spider_death_hook(void *, void *, void *)
cquest.status = QUEST_STATUS_COMPLETED;
del_hook_new(HOOK_MONSTER_DEATH, quest_spider_death_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return false;
}
@@ -115,17 +116,14 @@ static bool quest_spider_finish_hook(void *, void *in_, void *)
object_prep(q_ptr, lookup_kind(TV_POTION, SV_POTION_AUGMENTATION));
q_ptr->number = 1;
q_ptr->found = OBJ_FOUND_REWARD;
- object_aware(q_ptr);
- object_known(q_ptr);
- q_ptr->ident |= IDENT_STOREB;
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
/* Continue the plot */
*(quest[q_idx].plot) = QUEST_POISON;
quest[*(quest[q_idx].plot)].init();
del_hook_new(HOOK_QUEST_FINISH, quest_spider_finish_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return true;
}
diff --git a/src/q_spider.hpp b/src/q_spider.hpp
index bd16c06a..fde50d6b 100644
--- a/src/q_spider.hpp
+++ b/src/q_spider.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_spider_init_hook();
diff --git a/src/q_thief.cc b/src/q_thief.cc
index a4505d2a..cf32098e 100644
--- a/src/q_thief.cc
+++ b/src/q_thief.cc
@@ -5,6 +5,7 @@
#include "dungeon_flag.hpp"
#include "game.hpp"
#include "hook_quest_finish_in.hpp"
+#include "hook_quest_gen_in.hpp"
#include "hooks.hpp"
#include "init1.hpp"
#include "monster2.hpp"
@@ -19,15 +20,18 @@
#include "util.hpp"
#include "variable.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#define cquest (quest[QUEST_THIEVES])
-static bool quest_thieves_gen_hook(void *, void *, void *)
+static bool quest_thieves_gen_hook(void *, void *in_, void *)
{
+ auto in = static_cast<hook_quest_gen_in *>(in_);
+
int x, y;
int xstart = 2;
int ystart = 2;
- bool_ again = TRUE;
+ bool again = true;
if (p_ptr->inside_quest != QUEST_THIEVES)
{
@@ -52,25 +56,25 @@ static bool quest_thieves_gen_hook(void *, void *, void *)
dun_level = quest[p_ptr->inside_quest].level;
/* Set the correct monster hook */
- set_mon_num_hook();
+ reset_get_monster_hook();
/* Prepare allocation table */
get_mon_num_prep();
init_flags = INIT_CREATE_DUNGEON;
- process_dungeon_file("thieves.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, FALSE);
- dungeon_flags |= DF_NO_GENO;
+ process_dungeon_file("thieves.map", &ystart, &xstart, cur_hgt, cur_wid, true, false);
+ in->dungeon_flags_ref |= DF_NO_GENO;
/* Rip the inventory from the player */
cmsg_print(TERM_YELLOW, "You feel a vicious blow on your head.");
while (again)
{
- again = FALSE;
+ again = false;
for (x = 0; x < INVEN_TOTAL; x++)
{
object_type *o_ptr = &p_ptr->inventory[x];
- if (!o_ptr->k_idx)
+ if (!o_ptr->k_ptr)
{
continue;
}
@@ -80,18 +84,18 @@ static bool quest_thieves_gen_hook(void *, void *, void *)
continue;
}
- inven_drop(x, 99, 4, 24, TRUE);
+ inven_drop(x, 99, 4, 24, true);
/* Thats ugly .. but it works */
- again = TRUE;
+ again = true;
break;
}
}
del_hook_new(HOOK_GEN_QUEST, quest_thieves_gen_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
- return TRUE;
+ return true;
}
static bool quest_thieves_hook(void *, void *, void *)
@@ -143,7 +147,7 @@ static bool quest_thieves_hook(void *, void *, void *)
quest[p_ptr->inside_quest].status = QUEST_STATUS_COMPLETED;
del_hook_new(HOOK_END_TURN, quest_thieves_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
cmsg_print(TERM_YELLOW, "You stopped the thieves and saved Bree!");
return false;
@@ -187,7 +191,7 @@ static bool quest_thieves_finish_hook(void *, void *in_, void *)
quest[*(quest[q_idx].plot)].init();
del_hook_new(HOOK_QUEST_FINISH, quest_thieves_finish_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return true;
}
@@ -203,7 +207,7 @@ static bool quest_thieves_feeling_hook(void *, void *, void *)
msg_print("All your possessions have been stolen!");
del_hook_new(HOOK_FEELING, quest_thieves_feeling_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return true;
}
diff --git a/src/q_thief.hpp b/src/q_thief.hpp
index 0e191db7..2aac49b8 100644
--- a/src/q_thief.hpp
+++ b/src/q_thief.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_thieves_init_hook();
diff --git a/src/q_thrain.cc b/src/q_thrain.cc
index 7b895695..344d9ffd 100644
--- a/src/q_thrain.cc
+++ b/src/q_thrain.cc
@@ -21,8 +21,10 @@
#include "util.hpp"
#include "variable.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#include <cassert>
+#include <fmt/format.h>
#define cquest (quest[QUEST_THRAIN])
@@ -123,7 +125,7 @@ static bool quest_thrain_death_hook(void *, void *in_, void *)
object_prep(q_ptr, lookup_kind(TV_HELM, SV_DRAGON_HELM));
q_ptr->number = 1;
q_ptr->found = OBJ_FOUND_REWARD;
- create_artifact(q_ptr, FALSE, TRUE);
+ create_artifact(q_ptr, false, true);
q_ptr->artifact_name = "of Thrain";
/* Drop it in the dungeon */
@@ -134,7 +136,7 @@ static bool quest_thrain_death_hook(void *, void *in_, void *)
del_hook_new(HOOK_MONSTER_DEATH, quest_thrain_death_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return false;
}
@@ -159,7 +161,7 @@ static bool quest_thrain_gen_hook(void *, void *in_, void *)
get_map_size("thrain.map", &ysize, &xsize);
/* Try to allocate space for room. If fails, exit */
- if (!room_alloc(xsize + 2, ysize + 2, FALSE, by0, bx0, &xval, &yval)) return false;
+ if (!room_alloc(xsize + 2, ysize + 2, false, by0, bx0, &xval, &yval)) return false;
/* Get corner values */
y1 = yval - ysize / 2;
@@ -180,7 +182,7 @@ static bool quest_thrain_gen_hook(void *, void *in_, void *)
build_rectangle(y1 - 1, x1 - 1, y2 + 1, x2 + 1, feat_wall_outer, CAVE_ROOM | CAVE_GLOW);
/* Set the correct monster hook */
- set_mon_num_hook();
+ reset_get_monster_hook();
/* Prepare allocation table */
get_mon_num_prep();
@@ -188,7 +190,7 @@ static bool quest_thrain_gen_hook(void *, void *in_, void *)
xstart = x1;
ystart = y1;
init_flags = INIT_CREATE_DUNGEON;
- process_dungeon_file("thrain.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, TRUE);
+ process_dungeon_file("thrain.map", &ystart, &xstart, cur_hgt, cur_wid, true, true);
for (x = x1; x < xstart; x++)
for (y = y1; y < ystart; y++)
@@ -196,9 +198,9 @@ static bool quest_thrain_gen_hook(void *, void *in_, void *)
cave[y][x].info |= CAVE_ICKY | CAVE_ROOM | CAVE_FREE;
if (cave[y][x].feat == FEAT_MARKER)
{
- m_allow_special[get_thrain()] = TRUE;
- int i = place_monster_one(y, x, get_thrain(), 0, FALSE, MSTATUS_NEUTRAL);
- m_allow_special[get_thrain()] = FALSE;
+ m_allow_special[get_thrain()] = true;
+ int i = place_monster_one(y, x, get_thrain(), 0, false, MSTATUS_NEUTRAL);
+ m_allow_special[get_thrain()] = false;
if (i) m_list[i].mflag |= MFLAG_QUEST;
}
@@ -271,7 +273,7 @@ void quest_thrain_init_hook()
cquest.data[0] = rand_range(d_info[DUNGEON_DOL_GULDUR].mindepth + 1, d_info[DUNGEON_DOL_GULDUR].maxdepth - 1);
if (wizard)
{
- messages.add(format("Thrain lvl %d", cquest.data[0]), TERM_BLUE);
+ messages.add(fmt::format("Thrain lvl {}", cquest.data[0]), TERM_BLUE);
}
}
if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
diff --git a/src/q_thrain.hpp b/src/q_thrain.hpp
index aa42385d..6bf0c6ac 100644
--- a/src/q_thrain.hpp
+++ b/src/q_thrain.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_thrain_init_hook();
diff --git a/src/q_troll.cc b/src/q_troll.cc
index 54eb3406..88e4b0ed 100644
--- a/src/q_troll.cc
+++ b/src/q_troll.cc
@@ -17,6 +17,7 @@
#include "util.hpp"
#include "variable.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#include <cassert>
@@ -50,22 +51,22 @@ static bool quest_troll_gen_hook(void *, void *, void *)
dun_level = quest[p_ptr->inside_quest].level;
/* Set the correct monster hook */
- set_mon_num_hook();
+ reset_get_monster_hook();
/* Prepare allocation table */
get_mon_num_prep();
init_flags = INIT_CREATE_DUNGEON;
- process_dungeon_file("trolls.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, TRUE);
+ process_dungeon_file("trolls.map", &ystart, &xstart, cur_hgt, cur_wid, true, true);
for (x = 3; x < xstart; x++)
for (y = 3; y < ystart; y++)
{
if (cave[y][x].feat == FEAT_MARKER)
{
- m_allow_special[get_tom()] = TRUE;
- int m_idx = place_monster_one(y, x, get_tom(), 0, FALSE, MSTATUS_ENEMY);
- m_allow_special[get_tom()] = FALSE;
+ m_allow_special[get_tom()] = true;
+ int m_idx = place_monster_one(y, x, get_tom(), 0, false, MSTATUS_ENEMY);
+ m_allow_special[get_tom()] = false;
if (m_idx)
{
@@ -76,7 +77,7 @@ static bool quest_troll_gen_hook(void *, void *, void *)
m_list[m_idx].mflag |= MFLAG_QUEST;
- a_allow_special[ART_GLAMDRING] = TRUE;
+ a_allow_special[ART_GLAMDRING] = true;
/* Mega-Hack -- Prepare to make "Glamdring" */
object_prep(q_ptr, lookup_kind(TV_SWORD, SV_BROAD_SWORD));
@@ -85,9 +86,9 @@ static bool quest_troll_gen_hook(void *, void *, void *)
q_ptr->name1 = ART_GLAMDRING;
/* Mega-Hack -- Actually create "Glamdring" */
- apply_magic(q_ptr, -1, TRUE, TRUE, TRUE);
+ apply_magic(q_ptr, -1, true, true, true);
- a_allow_special[ART_GLAMDRING] = FALSE;
+ a_allow_special[ART_GLAMDRING] = false;
/* Get new object */
o_idx = o_pop();
@@ -115,7 +116,7 @@ static bool quest_troll_gen_hook(void *, void *, void *)
}
/* Reinitialize the ambush ... hehehe */
- cquest.data[0] = FALSE;
+ cquest.data[0] = false;
return true;
}
@@ -137,7 +138,7 @@ static bool quest_troll_finish_hook(void *, void *in_, void *)
quest[*(quest[q_idx].plot)].init();
del_hook_new(HOOK_QUEST_FINISH, quest_troll_finish_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return true;
}
@@ -162,19 +163,19 @@ static bool quest_troll_death_hook(void *, void *in_, void *)
cmsg_print(TERM_YELLOW, "Without Tom, the trolls won't be able to do much.");
cquest.status = QUEST_STATUS_COMPLETED;
del_hook_new(HOOK_MONSTER_DEATH, quest_troll_death_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return false;
}
init_flags = INIT_GET_SIZE;
- process_dungeon_file("trolls.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, TRUE);
+ process_dungeon_file("trolls.map", &ystart, &xstart, cur_hgt, cur_wid, true, true);
if (cquest.data[0])
{
return false;
}
- cquest.data[0] = TRUE;
+ cquest.data[0] = true;
msg_print("Oops, seems like an ambush...");
@@ -191,7 +192,7 @@ static bool quest_troll_death_hook(void *, void *in_, void *)
c_ptr->info &= ~CAVE_SPEC;
int r_idx = (rand_int(2) == 0) ? get_forest_troll() : get_stone_troll();
- place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_ENEMY);
+ place_monster_one(y, x, r_idx, 0, false, MSTATUS_ENEMY);
}
}
}
diff --git a/src/q_troll.hpp b/src/q_troll.hpp
index 08bba3dd..3d426777 100644
--- a/src/q_troll.hpp
+++ b/src/q_troll.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_troll_init_hook();
diff --git a/src/q_ultrae.hpp b/src/q_ultrae.hpp
index 77ec2e38..45716b4b 100644
--- a/src/q_ultrae.hpp
+++ b/src/q_ultrae.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_ultra_evil_init_hook();
diff --git a/src/q_ultrag.cc b/src/q_ultrag.cc
index e3da974f..c4752f89 100644
--- a/src/q_ultrag.cc
+++ b/src/q_ultrag.cc
@@ -2,6 +2,7 @@
#include "cave.hpp"
#include "cave_type.hpp"
+#include "game.hpp"
#include "hook_chardump_in.hpp"
#include "hook_move_in.hpp"
#include "hook_stair_in.hpp"
@@ -11,15 +12,25 @@
#include "object1.hpp"
#include "object2.hpp"
#include "object_flag.hpp"
+#include "object_kind.hpp"
#include "object_type.hpp"
#include "options.hpp"
#include "player_type.hpp"
#include "tables.hpp"
#include "util.hpp"
#include "variable.hpp"
+#include "z-term.hpp"
#define cquest (quest[QUEST_ULTRA_GOOD])
+static std::shared_ptr<object_kind> get_flame_imperishable()
+{
+ static auto &k_info = game->edit_data.k_info;
+ static auto &k_flame_imperishable = k_info[test_item_name("& Flame~ Imperishable")];
+
+ return k_flame_imperishable;
+}
+
static bool quest_ultra_good_move_hook(void *, void *in_, void *)
{
struct hook_move_in *in = static_cast<struct hook_move_in *>(in_);
@@ -41,7 +52,7 @@ static bool quest_ultra_good_move_hook(void *, void *in_, void *)
}
auto old_quick_messages = options->quick_messages;
- options->quick_messages = FALSE;
+ options->quick_messages = false;
cmsg_print(TERM_L_BLUE, "You meet Galadriel.");
cmsg_print(TERM_YELLOW, "'I still cannot believe this is all over.'");
@@ -126,14 +137,14 @@ static bool quest_ultra_good_stair_hook(void *, void *in_, void *)
if ((dir == STAIRS_DOWN) && (dun_level == 149))
{
int i;
- bool_ ultimate = FALSE;
+ bool ultimate = false;
/* Now look for an ULTIMATE artifact, that is, one imbued with the flame */
for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
{
- object_type *o_ptr = get_object(i);
+ auto o_ptr = &p_ptr->inventory[i];
- if (!o_ptr->k_idx)
+ if (!o_ptr->k_ptr)
{
continue;
}
@@ -142,7 +153,7 @@ static bool quest_ultra_good_stair_hook(void *, void *in_, void *)
if (flags & TR_ULTIMATE)
{
- ultimate = TRUE;
+ ultimate = true;
break;
}
}
@@ -152,7 +163,7 @@ static bool quest_ultra_good_stair_hook(void *, void *in_, void *)
cmsg_print(TERM_YELLOW, "It seems the level is protected by an impassable barrier of pure magic.");
cmsg_print(TERM_YELLOW, "Only the most powerful magic could remove it. You will need to use");
cmsg_print(TERM_YELLOW, "the Flame Imperishable to pass. The source of Eru Iluvatar's own power.");
- return TRUE;
+ return true;
}
else
{
@@ -208,7 +219,7 @@ static bool quest_ultra_good_death_hook(void *, void *in_, void *)
/* Remove now used hook */
del_hook_new(HOOK_MONSTER_DEATH, quest_ultra_good_death_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
/* End plot */
*(quest[QUEST_ULTRA_GOOD].plot) = QUEST_NULL;
@@ -226,22 +237,19 @@ static bool quest_ultra_good_death_hook(void *, void *in_, void *)
object_prep(q_ptr, lookup_kind(TV_JUNK, 255));
/* Mega-Hack -- Actually create the Flame Imperishable */
- k_allow_special[296] = TRUE;
- apply_magic(q_ptr, -1, TRUE, TRUE, TRUE);
- k_allow_special[296] = FALSE;
+ get_flame_imperishable()->allow_special = true;
+ apply_magic(q_ptr, -1, true, true, true);
+ get_flame_imperishable()->allow_special = false;
/* Identify it fully */
object_aware(q_ptr);
object_known(q_ptr);
- /* Mark the item as fully known */
- q_ptr->ident |= (IDENT_MENTAL);
-
/* Find a space */
for (i = 0; i < INVEN_PACK; i++)
{
/* Skip non-objects */
- if (!p_ptr->inventory[i].k_idx)
+ if (!p_ptr->inventory[i].k_ptr)
{
break;
}
@@ -251,17 +259,17 @@ static bool quest_ultra_good_death_hook(void *, void *in_, void *)
{
char o_name[200];
- object_desc(o_name, &p_ptr->inventory[INVEN_PACK - 1], FALSE, 0);
+ object_desc(o_name, &p_ptr->inventory[INVEN_PACK - 1], false, 0);
/* Drop the item */
- inven_drop(INVEN_PACK - 1, 99, p_ptr->py, p_ptr->px, FALSE);
+ inven_drop(INVEN_PACK - 1, 99, p_ptr->py, p_ptr->px, false);
cmsg_format(TERM_VIOLET, "You feel the urge to drop your %s to make room in your inventory.", o_name);
}
/* Carry it */
cmsg_format(TERM_VIOLET, "You feel the urge to pick up the Flame Imperishable.");
- inven_carry(q_ptr, FALSE);
+ inven_carry(q_ptr, false);
}
return false;
diff --git a/src/q_ultrag.hpp b/src/q_ultrag.hpp
index cef81fa5..0677111e 100644
--- a/src/q_ultrag.hpp
+++ b/src/q_ultrag.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_ultra_good_init_hook();
diff --git a/src/q_wight.cc b/src/q_wight.cc
index ced87277..4c4c549e 100644
--- a/src/q_wight.cc
+++ b/src/q_wight.cc
@@ -15,6 +15,7 @@
#include "util.hpp"
#include "variable.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#include <cassert>
@@ -44,13 +45,13 @@ static bool quest_wight_gen_hook(void *, void *, void *)
dun_level = quest[p_ptr->inside_quest].level;
/* Set the correct monster hook */
- set_mon_num_hook();
+ reset_get_monster_hook();
/* Prepare allocation table */
get_mon_num_prep();
init_flags = INIT_CREATE_DUNGEON;
- process_dungeon_file("wights.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, TRUE);
+ process_dungeon_file("wights.map", &ystart, &xstart, cur_hgt, cur_wid, true, true);
for (x = 3; x < xstart; x++)
{
@@ -60,9 +61,9 @@ static bool quest_wight_gen_hook(void *, void *, void *)
{
int m_idx = 0;
- m_allow_special[get_wight_king()] = TRUE;
- m_idx = place_monster_one(y, x, get_wight_king(), 0, FALSE, MSTATUS_ENEMY);
- m_allow_special[get_wight_king()] = FALSE;
+ m_allow_special[get_wight_king()] = true;
+ m_idx = place_monster_one(y, x, get_wight_king(), 0, false, MSTATUS_ENEMY);
+ m_allow_special[get_wight_king()] = false;
if (m_idx)
{
@@ -93,8 +94,6 @@ static bool quest_wight_gen_hook(void *, void *, void *)
TR_CURSED |
TR_HEAVY_CURSE;
- q_ptr->ident |= IDENT_CURSED;
-
if (randint(2) == 1)
{
q_ptr->art_flags |= TR_SPELL;
@@ -153,7 +152,7 @@ static bool quest_wight_death_hook(void *, void *in_, void *)
cquest.status = QUEST_STATUS_COMPLETED;
del_hook_new(HOOK_MONSTER_DEATH, quest_wight_death_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return false;
}
@@ -179,7 +178,7 @@ static bool quest_wight_finish_hook(void *, void *in_, void *)
quest[*(quest[q_idx].plot)].init();
del_hook_new(HOOK_QUEST_FINISH, quest_wight_finish_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return true;
}
diff --git a/src/q_wight.hpp b/src/q_wight.hpp
index 16713332..9474f8cd 100644
--- a/src/q_wight.hpp
+++ b/src/q_wight.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_wight_init_hook();
diff --git a/src/q_wolves.cc b/src/q_wolves.cc
index 0e811ce6..9ab7aa7a 100644
--- a/src/q_wolves.cc
+++ b/src/q_wolves.cc
@@ -7,6 +7,7 @@
#include "feature_type.hpp"
#include "game.hpp"
#include "hook_quest_finish_in.hpp"
+#include "hook_quest_gen_in.hpp"
#include "hooks.hpp"
#include "init1.hpp"
#include "monster2.hpp"
@@ -17,11 +18,13 @@
#include "util.hpp"
#include "variable.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#define cquest (quest[QUEST_WOLVES])
-static bool quest_wolves_gen_hook(void *, void *, void *)
+static bool quest_wolves_gen_hook(void *, void *in_, void *)
{
+ auto in = static_cast<hook_quest_gen_in *>(in_);
auto const &f_info = game->edit_data.f_info;
int x, y, i;
@@ -51,14 +54,14 @@ static bool quest_wolves_gen_hook(void *, void *, void *)
dun_level = quest[p_ptr->inside_quest].level;
/* Set the correct monster hook */
- set_mon_num_hook();
+ reset_get_monster_hook();
/* Prepare allocation table */
get_mon_num_prep();
init_flags = INIT_CREATE_DUNGEON;
- process_dungeon_file("wolves.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, FALSE);
- dungeon_flags |= DF_NO_GENO;
+ process_dungeon_file("wolves.map", &ystart, &xstart, cur_hgt, cur_wid, true, false);
+ in->dungeon_flags_ref |= DF_NO_GENO;
/* Place some random wolves */
for (i = damroll(4, 4); i > 0; )
@@ -88,7 +91,7 @@ static bool quest_wolves_gen_hook(void *, void *, void *)
}
}
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
return true;
}
@@ -121,7 +124,7 @@ static bool quest_wolves_death_hook(void *, void *, void *)
del_hook_new(HOOK_MONSTER_DEATH, quest_wolves_death_hook);
del_hook_new(HOOK_GEN_QUEST, quest_wolves_gen_hook);
- process_hooks_restart = TRUE;
+ process_hooks_restart = true;
cmsg_print(TERM_YELLOW, "Lothlorien is safer now.");
return false;
diff --git a/src/q_wolves.hpp b/src/q_wolves.hpp
index c5596fc6..923bdef5 100644
--- a/src/q_wolves.hpp
+++ b/src/q_wolves.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
void quest_wolves_init_hook();
diff --git a/src/quest_type.hpp b/src/quest_type.hpp
index ae97af35..b480cef7 100644
--- a/src/quest_type.hpp
+++ b/src/quest_type.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include <string>
@@ -9,7 +9,7 @@
*/
struct quest_type
{
- bool_ silent;
+ bool silent;
char name[40]; /* Quest name */
diff --git a/src/randart.cc b/src/randart.cc
index a902d734..94d644f6 100644
--- a/src/randart.cc
+++ b/src/randart.cc
@@ -18,7 +18,6 @@
#include "player_type.hpp"
#include "spells2.hpp"
#include "util.hpp"
-#include "variable.h"
#include "variable.hpp"
#include "z-rand.hpp"
@@ -29,13 +28,13 @@
/*
* Attempt to add a power to a randart
*/
-static bool_ grab_one_power(int *ra_idx, object_type const *o_ptr, std::vector<s16b> &max_times)
+static bool grab_one_power(int *ra_idx, object_type const *o_ptr, std::vector<s16b> &max_times)
{
auto const &ra_info = game->edit_data.ra_info;
assert(max_times.size() >= ra_info.size());
- bool_ ret = FALSE;
+ bool ret = false;
std::vector<size_t> ok_ra;
@@ -43,7 +42,7 @@ static bool_ grab_one_power(int *ra_idx, object_type const *o_ptr, std::vector<s
for (size_t i = 0; i < ra_info.size(); i++)
{
auto ra_ptr = &ra_info[i];
- bool_ ok = FALSE;
+ bool ok = false;
/* Must have the correct fields */
for (auto const &filter: ra_ptr->kind_filter)
@@ -52,14 +51,14 @@ static bool_ grab_one_power(int *ra_idx, object_type const *o_ptr, std::vector<s
(filter.min_sval <= o_ptr->sval) &&
(o_ptr->sval <= filter.max_sval))
{
- ok = TRUE;
+ ok = true;
break;
}
}
if ((0 < ra_ptr->max_pval) && (ra_ptr->max_pval < o_ptr->pval))
{
- ok = FALSE;
+ ok = false;
}
if (!ok)
@@ -112,7 +111,7 @@ static bool_ grab_one_power(int *ra_idx, object_type const *o_ptr, std::vector<s
max_times[i]++;
/* Success */
- ret = TRUE;
+ ret = true;
break;
}
@@ -134,12 +133,12 @@ static long ltotal[S_WORD + 1][S_WORD + 1];
* probability tables which are used later on for letter selection. It
* relies on the ASCII character set.
*/
-void build_prob(cptr learn)
+void build_prob(const char *learn)
{
int c_prev, c_cur, c_next;
/* Build raw frequencies */
- while (1)
+ while (true)
{
c_prev = c_cur = S_WORD;
@@ -189,7 +188,7 @@ startover:
cp = word_buf;
c_prev = c_cur = S_WORD;
- while (1)
+ while (true)
{
getletter:
c_next = 0;
@@ -243,7 +242,7 @@ void get_random_name(char * return_name)
}
-bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name)
+bool create_artifact(object_type *o_ptr, bool a_scroll, bool get_name)
{
auto const &ra_gen = game->edit_data.ra_gen;
auto const &ra_info = game->edit_data.ra_info;
@@ -251,13 +250,16 @@ bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name)
char new_name[80];
int powers = 0;
s32b total_flags, total_power = 0;
- bool_ a_cursed = FALSE;
+ bool a_cursed = false;
s16b pval = 0;
- bool_ limit_blows = FALSE;
+ bool limit_blows = false;
strcpy(new_name, "");
- if ((!a_scroll) && (randint(A_CURSED) == 1)) a_cursed = TRUE;
+ if ((!a_scroll) && (randint(A_CURSED) == 1))
+ {
+ a_cursed = true;
+ }
for (auto const &g: ra_gen)
{
@@ -294,12 +296,6 @@ bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name)
add_random_ego_flag(o_ptr, ra_ptr->fego, &limit_blows);
- /* get flags */
- auto const flags = object_flags(o_ptr);
-
- /* Hack -- acquire "cursed" flag */
- if (flags & TR_CURSED) o_ptr->ident |= (IDENT_CURSED);
-
/* Hack -- obtain bonuses */
if (ra_ptr->max_to_h > 0) o_ptr->to_h += randint(ra_ptr->max_to_h);
if (ra_ptr->max_to_h < 0) o_ptr->to_h -= randint( -ra_ptr->max_to_h);
@@ -345,10 +341,9 @@ bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name)
/* Identify it fully */
object_aware(o_ptr);
object_known(o_ptr);
- o_ptr->ident |= (IDENT_STOREB | IDENT_MENTAL);
strcpy(dummy_name, "");
- object_out_desc(o_ptr, NULL, FALSE, TRUE);
+ object_out_desc(o_ptr, NULL, false, true);
if (get_string("What do you want to call the artifact? ", dummy_name, 80))
{
@@ -379,7 +374,7 @@ bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name)
/* HACKS for ToME */
if (o_ptr->tval == TV_CLOAK && o_ptr->sval == SV_MIMIC_CLOAK)
{
- s32b mimic = find_random_mimic_shape(127, TRUE);
+ s32b mimic = find_random_mimic_shape(127, true);
o_ptr->pval2 = mimic;
}
else if (flags & TR_SPELL_CONTAIN)
@@ -387,14 +382,12 @@ bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name)
o_ptr->pval2 = -1;
}
- return TRUE;
+ return true;
}
-bool_ artifact_scroll()
+bool artifact_scroll()
{
- bool_ okay = FALSE;
-
/* Get an item */
int item;
if (!get_item(&item,
@@ -403,7 +396,7 @@ bool_ artifact_scroll()
(USE_EQUIP | USE_INVEN | USE_FLOOR),
item_tester_hook_artifactable()))
{
- return (FALSE);
+ return false;
}
/* Get the item */
@@ -411,29 +404,27 @@ bool_ artifact_scroll()
/* Description */
char o_name[80];
- object_desc(o_name, o_ptr, FALSE, 0);
+ object_desc(o_name, o_ptr, false, 0);
/* Describe */
msg_format("%s %s radiate%s a blinding light!",
((item >= 0) ? "Your" : "The"), o_name,
((o_ptr->number > 1) ? "" : "s"));
+ bool okay = false;
+
if (artifact_p(o_ptr))
{
msg_format("The %s %s already %s!",
o_name, ((o_ptr->number > 1) ? "are" : "is"),
((o_ptr->number > 1) ? "artifacts" : "an artifact"));
- okay = FALSE;
}
-
else if (o_ptr->name2)
{
msg_format("The %s %s already %s!",
o_name, ((o_ptr->number > 1) ? "are" : "is"),
((o_ptr->number > 1) ? "ego items" : "an ego item"));
- okay = FALSE;
}
-
else
{
if (o_ptr->number > 1)
@@ -442,7 +433,8 @@ bool_ artifact_scroll()
msg_format("%d of your %s %s destroyed!", (o_ptr->number) - 1, o_name, (o_ptr->number > 2 ? "were" : "was"));
o_ptr->number = 1;
}
- okay = create_artifact(o_ptr, TRUE, TRUE);
+
+ okay = create_artifact(o_ptr, true, true);
}
/* Failure */
@@ -455,10 +447,12 @@ bool_ artifact_scroll()
msg_print("The enchantment failed.");
}
else
+ {
o_ptr->found = OBJ_FOUND_SELFMADE;
+ }
/* Something happened */
- return (TRUE);
+ return true;
}
diff --git a/src/randart.hpp b/src/randart.hpp
index 6f91f36d..676c89e4 100644
--- a/src/randart.hpp
+++ b/src/randart.hpp
@@ -1,8 +1,8 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_type_fwd.hpp"
-void build_prob(cptr learn);
-bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name);
-bool_ artifact_scroll();
+void build_prob(const char *learn);
+bool create_artifact(object_type *o_ptr, bool a_scroll, bool get_name);
+bool artifact_scroll();
diff --git a/src/randart_part_type.hpp b/src/randart_part_type.hpp
index 5a4ca329..2b45deae 100644
--- a/src/randart_part_type.hpp
+++ b/src/randart_part_type.hpp
@@ -1,7 +1,7 @@
#pragma once
#include "ego_flag_set.hpp"
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_flag_set.hpp"
#include <vector>
diff --git a/src/random_artifact.hpp b/src/random_artifact.hpp
index 618f1102..cc9ec280 100644
--- a/src/random_artifact.hpp
+++ b/src/random_artifact.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include <string>
diff --git a/src/random_quest.hpp b/src/random_quest.hpp
index 9e3c6e10..0e9040be 100644
--- a/src/random_quest.hpp
+++ b/src/random_quest.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct random_quest
{
diff --git a/src/random_spell.hpp b/src/random_spell.hpp
index f02b9848..9a881bc5 100644
--- a/src/random_spell.hpp
+++ b/src/random_spell.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include <string>
/**
diff --git a/src/range.hpp b/src/range.hpp
index 3c185ba6..b0324d59 100644
--- a/src/range.hpp
+++ b/src/range.hpp
@@ -1,7 +1,7 @@
#pragma once
#include "range_fwd.hpp"
-#include "h-basic.h"
+#include "h-basic.hpp"
/*
* Range
diff --git a/src/rule_type.hpp b/src/rule_type.hpp
index b88ce7bf..99ac4dbf 100644
--- a/src/rule_type.hpp
+++ b/src/rule_type.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "monster_race_flag_set.hpp"
#include "monster_spell_flag_set.hpp"
diff --git a/src/school_book.hpp b/src/school_book.hpp
index 51d3e6a7..51aa57cc 100644
--- a/src/school_book.hpp
+++ b/src/school_book.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include <vector>
diff --git a/src/school_type.hpp b/src/school_type.hpp
index 7a5702b4..5386969d 100644
--- a/src/school_type.hpp
+++ b/src/school_type.hpp
@@ -1,21 +1,21 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "deity_type_fwd.hpp"
struct school_type
{
- cptr name; /* Name */
+ const char *name; /* Name */
s16b skill; /* Skill used for that school */
- bool_ spell_power; /* Does spell power affect spells in this school? */
- bool_ sorcery; /* Does Sorcery affect this school? */
+ bool spell_power; /* Does spell power affect spells in this school? */
+ bool sorcery; /* Does Sorcery affect this school? */
int deity_idx; /* Deity; if <=0, no deity required */
deity_type *deity; /* Direct pointer to deity */
int (*bonus_levels)(); /* Calculate number of bonus levels */
- bool_ (*depends_satisfied)(); /* Are dependendies satisfied? */
+ bool (*depends_satisfied)(); /* Are dependendies satisfied? */
struct school_provider_list *providers; /* List of secondary providers of this school */
};
diff --git a/src/set_component.hpp b/src/set_component.hpp
index 18dc4d57..fed44451 100644
--- a/src/set_component.hpp
+++ b/src/set_component.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_flag_set.hpp"
#include <array>
@@ -9,7 +9,7 @@
constexpr std::size_t SET_MAX_SIZE = 6;
struct set_component {
- bool_ present = FALSE; /* Is it being worn? */
+ bool present = false; /* Is it being worn? */
s16b a_idx = 0; /* What artifact? */
std::array<s16b , SET_MAX_SIZE> pval; /* Pval for each combination */
std::array<object_flag_set, SET_MAX_SIZE> flags; /* Flags */
diff --git a/src/skill_descriptor.hpp b/src/skill_descriptor.hpp
index 8d9de004..7c811148 100644
--- a/src/skill_descriptor.hpp
+++ b/src/skill_descriptor.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "skill_flag_set.hpp"
#include "skills_defs.hpp"
diff --git a/src/skill_modifier.hpp b/src/skill_modifier.hpp
index e4bf4ce9..05e4d5d7 100644
--- a/src/skill_modifier.hpp
+++ b/src/skill_modifier.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
struct skill_modifier {
diff --git a/src/skill_modifiers.hpp b/src/skill_modifiers.hpp
index 5e90b000..203242b5 100644
--- a/src/skill_modifiers.hpp
+++ b/src/skill_modifiers.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "skills_defs.hpp"
#include "skill_modifier.hpp"
diff --git a/src/skill_type.hpp b/src/skill_type.hpp
index c26d8649..fdbd427e 100644
--- a/src/skill_type.hpp
+++ b/src/skill_type.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "skill_flag_set.hpp"
#include "skills_defs.hpp"
#include "skill_descriptor.hpp"
diff --git a/src/skills.cc b/src/skills.cc
index af5e46c7..ae53d6e6 100644
--- a/src/skills.cc
+++ b/src/skills.cc
@@ -34,10 +34,9 @@
#include "spells4.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "xtra2.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
#include <algorithm>
@@ -121,7 +120,7 @@ static void decrease_skill(int i, s16b *invest)
* Given the name of a skill, returns skill index or -1 if no
* such skill is found
*/
-s16b find_skill(cptr needle)
+s16b find_skill(const char *needle)
{
auto const &s_descriptors = game->edit_data.s_descriptors;
@@ -139,7 +138,12 @@ s16b find_skill(cptr needle)
return -1;
}
-s16b find_skill_i(cptr needle)
+s16b find_skill_i(std::string const &needle)
+{
+ return find_skill_i(needle.c_str());
+}
+
+s16b find_skill_i(const char *needle)
{
auto const &s_descriptors = game->edit_data.s_descriptors;
@@ -207,13 +211,13 @@ static std::size_t get_idx(int i)
return 0;
}
-static bool_ is_known(int s_idx)
+static bool is_known(int s_idx)
{
auto const &s_descriptors = game->edit_data.s_descriptors;
auto const &s_info = game->s_info;
- if (wizard) return TRUE;
- if (s_info[s_idx].value || s_info[s_idx].mod) return TRUE;
+ if (wizard) return true;
+ if (s_info[s_idx].value || s_info[s_idx].mod) return true;
for (std::size_t i = 0; i < s_descriptors.size(); i++)
{
@@ -221,12 +225,12 @@ static bool_ is_known(int s_idx)
if (s_descriptors[i].father == s_idx)
{
if (is_known(i))
- return TRUE;
+ return true;
}
}
/* Ok know none */
- return FALSE;
+ return false;
}
namespace { // anonymous
@@ -238,7 +242,7 @@ struct skill_entry {
}
-static void init_table_aux(std::vector<skill_entry> *table, int father, int lev, bool_ full)
+static void init_table_aux(std::vector<skill_entry> *table, int father, int lev, bool full)
{
auto const &s_descriptors = game->edit_data.s_descriptors;
auto const &s_info = game->s_info;
@@ -263,7 +267,7 @@ static void init_table_aux(std::vector<skill_entry> *table, int father, int lev,
}
}
-static void init_table(std::vector<skill_entry> *table, bool_ full)
+static void init_table(std::vector<skill_entry> *table, bool full)
{
table->clear();
init_table_aux(table, -1, 0, full);
@@ -297,7 +301,7 @@ void dump_skills(FILE *fff)
std::vector<skill_entry> table;
table.reserve(s_descriptors.size());
- init_table(&table, TRUE);
+ init_table(&table, true);
fprintf(fff, "\nSkills (points left: %d)", p_ptr->skill_points);
@@ -324,11 +328,11 @@ void dump_skills(FILE *fff)
if (!has_child(i))
{
- strcat(buf, format(" . %s", skill_name.c_str()));
+ strcat(buf, fmt::format(" . {}", skill_name).c_str());
}
else
{
- strcat(buf, format(" - %s", skill_name.c_str()));
+ strcat(buf, fmt::format(" - %s", skill_name).c_str());
}
fprintf(fff, "%-49s%s%06.3f [%05.3f]",
@@ -351,16 +355,16 @@ static void print_skills(std::vector<skill_entry> const &table, int sel, int sta
int j;
int wid, hgt;
- cptr keys;
+ const char *keys;
Term_clear();
Term_get_size(&wid, &hgt);
- c_prt(TERM_WHITE, format("%s Skills Screen", game_module), 0, 28);
+ c_prt(TERM_WHITE, fmt::format("{} Skills Screen", game_module), 0, 28);
keys = format("#BEnter#W to develop a branch, #Bup#W/#Bdown#W to move, #Bright#W/#Bleft#W to modify, #B?#W for help");
display_message(0, 1, strlen(keys), TERM_WHITE, keys);
c_prt((p_ptr->skill_points) ? TERM_L_BLUE : TERM_L_RED,
- format("Skill points left: %d", p_ptr->skill_points), 2, 0);
+ fmt::format("Skill points left: {}", p_ptr->skill_points), 2, 0);
print_desc_aux(s_descriptors[table[sel].skill_idx].desc.c_str(), 3, 0);
for (j = start; j < start + (hgt - 7); j++)
@@ -407,17 +411,17 @@ static void print_skills(std::vector<skill_entry> const &table, int sel, int sta
if (!has_child(i))
{
- c_prt(color, format("%c.%c%s", deb, end, name.c_str()),
+ c_prt(color, fmt::format("{}.{}{}", deb, end, name),
j + 7 - start, table[j].indent_level * 4);
}
else if (skill.dev)
{
- c_prt(color, format("%c-%c%s", deb, end, name.c_str()),
+ c_prt(color, fmt::format("{}-{}{}", deb, end, name),
j + 7 - start, table[j].indent_level * 4);
}
else
{
- c_prt(color, format("%c+%c%s", deb, end, name.c_str()),
+ c_prt(color, fmt::format("{}+{}{}", deb, end, name),
j + 7 - start, table[j].indent_level * 4);
}
@@ -435,7 +439,7 @@ static void print_skills(std::vector<skill_entry> const &table, int sel, int sta
/*
* Checks various stuff to do when skills change, like new spells, ...
*/
-void recalc_skills(bool_ init)
+void recalc_skills(bool init)
{
auto const &s_info = game->s_info;
@@ -566,7 +570,7 @@ void do_cmd_skill()
int wid, hgt;
s16b skill_points_save;
- recalc_skills(TRUE);
+ recalc_skills(true);
/* Save the screen */
screen_save();
@@ -594,9 +598,9 @@ void do_cmd_skill()
/* Initialise the skill list */
std::vector<skill_entry> table;
table.reserve(s_descriptors.size());
- init_table(&table, FALSE);
+ init_table(&table, false);
- while (TRUE)
+ while (true)
{
Term_get_size(&wid, &hgt);
@@ -616,7 +620,7 @@ void do_cmd_skill()
// Toggle the selected skill
s_info[table[sel].skill_idx].dev = !s_info[table[sel].skill_idx].dev;
// Re-populate table
- init_table(&table, FALSE);
+ init_table(&table, false);
}
/* Next page */
@@ -710,7 +714,7 @@ void do_cmd_skill()
/* Load the screen */
screen_load();
- recalc_skills(FALSE);
+ recalc_skills(false);
}
@@ -730,7 +734,7 @@ static const char *melee_names[MAX_MELEE] =
"Barehanded combat",
"Bearform combat",
};
-static bool_ melee_bool[MAX_MELEE];
+static bool melee_bool[MAX_MELEE];
static int melee_num[MAX_MELEE];
s16b get_melee_skill()
@@ -745,7 +749,7 @@ s16b get_melee_skill()
return (0);
}
-cptr get_melee_name()
+const char *get_melee_name()
{
return melee_names[get_melee_skill()];
}
@@ -760,11 +764,11 @@ s16b get_melee_skills()
{
if ((s_info[melee_skills[i]].value > 0) && (!s_info[melee_skills[i]].hidden))
{
- melee_bool[i] = TRUE;
+ melee_bool[i] = true;
j++;
}
else
- melee_bool[i] = FALSE;
+ melee_bool[i] = false;
}
return (j);
@@ -773,10 +777,10 @@ s16b get_melee_skills()
static void choose_melee()
{
int i, j, z = 0;
- int force_drop = FALSE, style_unchanged = FALSE;
+ int force_drop = false, style_unchanged = false;
+
+ screen_save_no_flush();
- character_icky = TRUE;
- Term_save();
Term_clear();
j = get_melee_skills();
@@ -785,13 +789,13 @@ static void choose_melee()
{
if (melee_bool[i])
{
- prt(format("%c) %s", I2A(z), melee_names[i]), z + 1, 0);
+ prt(fmt::format("{}) {}", I2A(z), melee_names[i]), z + 1, 0);
melee_num[z] = i;
z++;
}
}
- while (TRUE)
+ while (true)
{
char c = inkey();
@@ -804,13 +808,13 @@ static void choose_melee()
if (p_ptr->melee_style == melee_skills[melee_num[z]])
{
- style_unchanged = TRUE;
+ style_unchanged = true;
break;
}
for (i = INVEN_WIELD; p_ptr->body_parts[i - INVEN_WIELD] == INVEN_WIELD; i++)
{
- if (p_ptr->inventory[i].k_idx)
+ if (p_ptr->inventory[i].k_ptr)
{
if (cursed_p(&p_ptr->inventory[i]))
{
@@ -821,7 +825,7 @@ static void choose_melee()
}
else if (INVEN_PACK == inven_takeoff(i, 255, force_drop))
{
- force_drop = TRUE;
+ force_drop = true;
}
}
}
@@ -839,8 +843,7 @@ static void choose_melee()
/* Redraw monster hitpoint */
p_ptr->redraw |= (PR_FRAME);
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
if (style_unchanged)
{
@@ -889,7 +892,7 @@ static void print_skill_batch(const std::vector<std::tuple<std::string, int>> &p
j++;
}
prt("", 2 + j, 20);
- prt(format("Select a skill (a-%c), @ to select by name, +/- to scroll:", I2A(j - 1)), 0, 0);
+ prt(fmt::format("Select a skill (a-{}), @ to select by name, +/- to scroll:", I2A(j - 1)), 0, 0);
}
static int do_cmd_activate_skill_aux()
@@ -914,14 +917,14 @@ static int do_cmd_activate_skill_aux()
{
if (s_descriptors[i].action_mkey && s_info[i].value && ((!s_info[i].hidden) || (i == SKILL_LEARN)))
{
- bool_ next = FALSE;
+ bool next = false;
/* Already got it ? */
for (size_t j = 0; j < p.size(); j++)
{
if (s_descriptors[i].action_mkey == std::get<1>(p[j]))
{
- next = TRUE;
+ next = true;
break;
}
}
@@ -936,14 +939,14 @@ static int do_cmd_activate_skill_aux()
{
if (ab_info[i].action_mkey && p_ptr->has_ability(i))
{
- bool_ next = FALSE;
+ bool next = false;
/* Already got it ? */
for (size_t j = 0; j < p.size(); j++)
{
if (ab_info[i].action_mkey == std::get<1>(p[j]))
{
- next = TRUE;
+ next = true;
break;
}
}
@@ -960,10 +963,9 @@ static int do_cmd_activate_skill_aux()
return -1;
}
- character_icky = TRUE;
- Term_save();
+ screen_save_no_flush();
- while (1)
+ while (true)
{
print_skill_batch(p, start);
which = inkey();
@@ -980,8 +982,7 @@ static int do_cmd_activate_skill_aux()
{
start -= 20;
}
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
}
else if (which == '-')
{
@@ -990,8 +991,7 @@ static int do_cmd_activate_skill_aux()
{
start += 20;
}
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
}
else if (which == '@')
{
@@ -999,7 +999,7 @@ static int do_cmd_activate_skill_aux()
strcpy(buf, "Cast a spell");
if (!get_string("Skill action? ", buf, 79))
- return FALSE;
+ return false;
/* Find the skill it is related to */
size_t i = 0;
@@ -1035,8 +1035,7 @@ static int do_cmd_activate_skill_aux()
break;
}
}
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
return ret;
}
@@ -1049,12 +1048,12 @@ void do_cmd_activate_skill()
auto const &s_info = game->s_info;
int x_idx;
- bool_ push = TRUE;
+ bool push = true;
/* Get the skill, if available */
if (repeat_pull(&x_idx))
{
- push = FALSE;
+ push = false;
}
else if (!command_arg)
{
@@ -1194,7 +1193,7 @@ void do_cmd_activate_skill()
}
o_ptr = get_object(INVEN_WIELD);
- if ((o_ptr->k_idx <= 0) ||
+ if ((!o_ptr->k_ptr) ||
(o_ptr->tval != TV_MSTAFF))
{
msg_print("You must wield a magestaff to use Geomancy.");
@@ -1204,7 +1203,7 @@ void do_cmd_activate_skill()
s = get_school_spell("cast", BOOK_GEOMANCY);
if (s >= 0)
{
- lua_cast_school_spell(s, FALSE);
+ lua_cast_school_spell(s, false);
}
break;
@@ -1259,23 +1258,23 @@ void do_cmd_activate_skill()
/* Which magic forbids non FA gloves */
-bool_ forbid_gloves()
+bool forbid_gloves()
{
- if (get_skill(SKILL_SORCERY)) return (TRUE);
- if (get_skill(SKILL_MANA)) return (TRUE);
- if (get_skill(SKILL_FIRE)) return (TRUE);
- if (get_skill(SKILL_AIR)) return (TRUE);
- if (get_skill(SKILL_WATER)) return (TRUE);
- if (get_skill(SKILL_EARTH)) return (TRUE);
- if (get_skill(SKILL_THAUMATURGY)) return (TRUE);
- return (FALSE);
+ if (get_skill(SKILL_SORCERY)) return true;
+ if (get_skill(SKILL_MANA)) return true;
+ if (get_skill(SKILL_FIRE)) return true;
+ if (get_skill(SKILL_AIR)) return true;
+ if (get_skill(SKILL_WATER)) return true;
+ if (get_skill(SKILL_EARTH)) return true;
+ if (get_skill(SKILL_THAUMATURGY)) return true;
+ return false;
}
/* Which gods forbid edged weapons */
-bool_ forbid_non_blessed()
+bool forbid_non_blessed()
{
- if (p_ptr->pgod == GOD_ERU) return (TRUE);
- return (FALSE);
+ if (p_ptr->pgod == GOD_ERU) return true;
+ return false;
}
@@ -1386,7 +1385,7 @@ void do_get_new_skill()
auto &s_info = game->s_info;
/* Check if some skills didn't influence other stuff */
- recalc_skills(TRUE);
+ recalc_skills(true);
/* Grab the ones we can gain */
std::vector<size_t> available_skills;
@@ -1462,7 +1461,7 @@ void do_get_new_skill()
}
// Ask for a skill
- while (TRUE)
+ while (true)
{
char last = 'a' + (LOST_SWORD_NSKILLS-1);
char buf[80];
@@ -1474,7 +1473,7 @@ void do_get_new_skill()
{
std::size_t chosen_skill = skl[res];
- bool_ oppose = FALSE;
+ bool oppose = false;
int oppose_skill = -1;
/* Check we don't oppose a skill the player already has */
@@ -1493,7 +1492,7 @@ void do_get_new_skill()
if (found != s_descriptor.excludes.end())
{
- oppose = TRUE;
+ oppose = true;
oppose_skill = i;
break;
}
@@ -1503,8 +1502,6 @@ void do_get_new_skill()
/* Ok we oppose, so be sure */
if (oppose)
{
- cptr msg;
-
/*
* Because this is SO critical a question, we must flush
* input to prevent killing character off -- pelpel
@@ -1512,9 +1509,10 @@ void do_get_new_skill()
flush();
/* Prepare prompt */
- msg = format("This skill is mutually exclusive with "
- "at least %s, continue?",
- s_descriptors[oppose_skill].name.c_str());
+ auto msg = fmt::format(
+ "This skill is mutually exclusive with "
+ "at least {}, continue?",
+ s_descriptors[oppose_skill].name);
/* The player rejected the choice; go back to prompt */
if (!get_check(msg))
@@ -1545,7 +1543,7 @@ void do_get_new_skill()
}
/* Check if some skills didn't influence other stuff */
- recalc_skills(FALSE);
+ recalc_skills(false);
}
@@ -1553,11 +1551,16 @@ void do_get_new_skill()
/**************************************** ABILITIES *****************************************/
+s16b find_ability(std::string const &name)
+{
+ return find_ability(name.c_str());
+}
+
/*
* Given the name of an ability, returns ability index or -1 if no
* such ability is found
*/
-s16b find_ability(cptr name)
+s16b find_ability(const char *name)
{
auto const &ab_info = game->edit_data.ab_info;
@@ -1584,19 +1587,19 @@ static bool can_learn_ability(int ab)
if (p_ptr->has_ability(ab))
{
- return FALSE;
+ return false;
}
if (p_ptr->skill_points < ab_info[ab].cost)
{
- return FALSE;
+ return false;
}
for (auto const &need_skill: ab_ptr->need_skills)
{
if (get_skill(need_skill.skill_idx) < need_skill.level)
{
- return FALSE;
+ return false;
}
}
@@ -1604,7 +1607,7 @@ static bool can_learn_ability(int ab)
{
if (!p_ptr->has_ability(need_ability))
{
- return FALSE;
+ return false;
}
}
@@ -1614,11 +1617,11 @@ static bool can_learn_ability(int ab)
if (ab_ptr->stat[i] > -1)
{
if (p_ptr->stat_ind[i] < ab_ptr->stat[i] - 3)
- return FALSE;
+ return false;
}
}
- return TRUE;
+ return true;
}
/* Learn an ability */
@@ -1697,7 +1700,7 @@ static void print_abilities(const std::vector<std::size_t> &table, int sel, int
int i, j;
int wid, hgt;
- cptr keys;
+ const char *keys;
Term_clear();
Term_get_size(&wid, &hgt);
@@ -1706,7 +1709,7 @@ static void print_abilities(const std::vector<std::size_t> &table, int sel, int
keys = format("#Bup#W/#Bdown#W to move, #Bright#W to buy, #B?#W for help");
display_message(0, 1, strlen(keys), TERM_WHITE, keys);
c_prt((p_ptr->skill_points) ? TERM_L_BLUE : TERM_L_RED,
- format("Skill points left: %d", p_ptr->skill_points), 2, 0);
+ fmt::format("Skill points left: {}", p_ptr->skill_points), 2, 0);
print_desc_aux(ab_info[table[sel]].desc.c_str(), 3, 0);
@@ -1789,7 +1792,7 @@ void do_cmd_ability()
std::end(table),
compare_abilities);
- while (TRUE)
+ while (true)
{
Term_get_size(&wid, &hgt);
diff --git a/src/skills.hpp b/src/skills.hpp
index 8b1437d9..0784c9e6 100644
--- a/src/skills.hpp
+++ b/src/skills.hpp
@@ -1,28 +1,31 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include <cstddef>
+#include <string>
/* Skill functions */
void dump_skills(FILE *fff);
-s16b find_skill(cptr name);
-s16b find_skill_i(cptr name);
+s16b find_skill(const char *name);
+s16b find_skill_i(std::string const &name);
+s16b find_skill_i(const char *name);
s16b get_skill(int skill);
s16b get_skill_scale(int skill, u32b scale);
void do_cmd_skill();
void do_cmd_activate_skill();
-cptr get_melee_name();
+const char *get_melee_name();
s16b get_melee_skills();
s16b get_melee_skill();
-bool_ forbid_gloves();
-bool_ forbid_non_blessed();
+bool forbid_gloves();
+bool forbid_non_blessed();
void compute_skills(s32b *v, s32b *m, std::size_t i);
void select_default_melee();
void do_get_new_skill();
void init_skill(s32b value, s32b mod, std::size_t i);
-s16b find_ability(cptr name);
+s16b find_ability(std::string const &name);
+s16b find_ability(const char *name);
void dump_abilities(FILE *fff);
void do_cmd_ability();
void apply_level_abilities(int level);
-void recalc_skills(bool_ init);
+void recalc_skills(bool init);
diff --git a/src/spell_type.cc b/src/spell_type.cc
index 6cf6e35b..b0b6cc04 100644
--- a/src/spell_type.cc
+++ b/src/spell_type.cc
@@ -19,22 +19,22 @@
*/
struct spell_type
{
- cptr name; /* Name */
+ const char *name; /* Name */
byte skill_level; /* Required level (to learn) */
std::vector<std::string> m_description; /* List of strings */
casting_result (*effect_func)(); /* Spell effect function */
- const char* (*info_func)(); /* Information function */
+ std::string (*info_func)(); /* Information function */
int (*lasting_func)(); /* Lasting effect function */
- bool_ (*depend_func)(); /* Check dependencies */
+ bool (*depend_func)(); /* Check dependencies */
s16b minimum_pval; /* Minimum required pval for item-based spells */
enum casting_type casting_type; /* Type of casting required */
s16b casting_stat; /* Stat used for casting */
- bool_ castable_while_blind;
- bool_ castable_while_confused;
+ bool castable_while_blind;
+ bool castable_while_confused;
dice_type device_charges; /* Number of charges for devices */
std::vector<device_allocation *> m_device_allocation; /* Allocation table for devices */
@@ -53,7 +53,7 @@ struct spell_type
public:
- spell_type(cptr _name)
+ spell_type(const char *_name)
: name(_name)
, skill_level(0)
, m_description()
@@ -64,8 +64,8 @@ public:
, minimum_pval(0)
, casting_type(USE_SPELL_POINTS)
, casting_stat(0)
- , castable_while_blind(FALSE)
- , castable_while_confused(FALSE)
+ , castable_while_blind(false)
+ , castable_while_confused(false)
, device_charges({ 0, 0, 0 })
, m_device_allocation()
, random_type(-1)
@@ -98,7 +98,7 @@ void spell_type_set_inertia(spell_type *spell, s32b difficulty, s32b delay)
void spell_type_init_music(spell_type *spell,
s16b minimum_pval,
- const char* (*info_func)(),
+ std::string (*info_func)(),
casting_result (*effect_func)())
{
assert(spell != NULL);
@@ -118,7 +118,7 @@ void spell_type_init_music(spell_type *spell,
void spell_type_init_music_lasting(spell_type *spell,
s16b minimum_pval,
- const char* (*info_func)(),
+ std::string (*info_func)(),
casting_result (*effect_func)(),
int (*lasting_func)())
{
@@ -134,7 +134,7 @@ void spell_type_init_music_lasting(spell_type *spell,
void spell_type_init_mage(spell_type *spell,
random_type random_type,
s32b school_idx,
- const char* (*info_func)(),
+ std::string (*info_func)(),
casting_result (*effect_func)())
{
assert(spell != NULL);
@@ -155,7 +155,7 @@ void spell_type_init_mage(spell_type *spell,
break;
default:
/* Cannot happen */
- assert(FALSE);
+ assert(false);
}
/* Add first school */
@@ -164,7 +164,7 @@ void spell_type_init_mage(spell_type *spell,
void spell_type_init_priest(spell_type *spell,
s32b school_idx,
- const char* (*info_func)(),
+ std::string (*info_func)(),
casting_result (*effect_func)())
{
assert(spell != NULL);
@@ -180,7 +180,7 @@ void spell_type_init_priest(spell_type *spell,
}
void spell_type_init_device(spell_type *spell,
- const char* (*info_func)(),
+ std::string (*info_func)(),
casting_result (*effect_func)())
{
assert(spell != NULL);
@@ -193,7 +193,7 @@ void spell_type_init_device(spell_type *spell,
}
void spell_type_init_demonology(spell_type *spell,
- const char* (*info_func)(),
+ std::string (*info_func)(),
casting_result (*effect_func)())
{
spell_type_init_mage(spell,
@@ -204,9 +204,9 @@ void spell_type_init_demonology(spell_type *spell,
}
void spell_type_init_geomancy(spell_type *spell,
- const char* (*info_func)(),
+ std::string (*info_func)(),
casting_result (*effect_func)(),
- bool_ (*depend_func)())
+ bool (*depend_func)())
{
spell_type_init_mage(spell,
NO_RANDOM,
@@ -232,21 +232,21 @@ void spell_type_set_mana(spell_type *spell, s32b min, s32b max)
range_init(&spell->mana_range, min, max);
}
-void spell_type_set_castable_while_blind(spell_type *spell, bool_ value)
+void spell_type_set_castable_while_blind(spell_type *spell, bool value)
{
assert(spell != NULL);
spell->castable_while_blind = value;
}
-void spell_type_set_castable_while_confused(spell_type *spell, bool_ value)
+void spell_type_set_castable_while_confused(spell_type *spell, bool value)
{
assert(spell != NULL);
spell->castable_while_confused = value;
}
-void spell_type_describe(spell_type *spell, cptr line)
+void spell_type_describe(spell_type *spell, const char *line)
{
assert(spell != NULL);
@@ -258,7 +258,7 @@ void spell_type_add_school(spell_type *spell, s32b school_idx)
school_idx_add_new(spell, school_idx);
}
-void spell_type_set_device_charges(spell_type *spell, cptr charges_s)
+void spell_type_set_device_charges(spell_type *spell, const char *charges_s)
{
assert(spell != NULL);
@@ -272,7 +272,7 @@ void spell_type_add_device_allocation(spell_type *spell, struct device_allocatio
spell->m_device_allocation.push_back(a);
}
-spell_type *spell_type_new(cptr name)
+spell_type *spell_type_new(const char *name)
{
spell_type *spell = new spell_type(name);
assert(spell != NULL);
@@ -291,7 +291,7 @@ casting_result spell_type_produce_effect(spell_type *spell)
return spell->effect_func();
}
-cptr spell_type_name(spell_type *spell)
+const char *spell_type_name(spell_type *spell)
{
assert(spell != NULL);
@@ -331,19 +331,19 @@ device_allocation *spell_type_device_allocation(spell_type *spell, byte tval)
return NULL;
}
-bool_ spell_type_uses_piety_to_cast(spell_type *spell)
+bool spell_type_uses_piety_to_cast(spell_type *spell)
{
assert(spell != NULL);
return spell->casting_type == USE_PIETY;
}
-bool_ spell_type_castable_while_blind(spell_type *spell)
+bool spell_type_castable_while_blind(spell_type *spell)
{
assert(spell != NULL);
return spell->castable_while_blind;
}
-bool_ spell_type_castable_while_confused(spell_type *spell)
+bool spell_type_castable_while_confused(spell_type *spell)
{
assert(spell != NULL);
return spell->castable_while_confused;
@@ -369,12 +369,12 @@ std::vector<s32b> const spell_type_get_schools(spell_type *spell)
return school_idxs;
}
-bool_ spell_type_inertia(spell_type *spell, s32b *difficulty, s32b *delay)
+bool spell_type_inertia(spell_type *spell, s32b *difficulty, s32b *delay)
{
if ((spell->inertia_difficulty < 0) ||
(spell->inertia_delay < 0))
{
- return FALSE;
+ return false;
}
if (difficulty != NULL)
@@ -387,13 +387,13 @@ bool_ spell_type_inertia(spell_type *spell, s32b *difficulty, s32b *delay)
*delay = spell->inertia_delay;
}
- return TRUE;
+ return true;
}
-cptr spell_type_info(spell_type *spell)
+std::string spell_type_info(spell_type *spell)
{
assert(spell != NULL);
-
+
return spell->info_func();
}
@@ -421,13 +421,13 @@ void spell_type_mana_range(spell_type *spell, range_type *range)
}
}
-bool_ spell_type_dependencies_satisfied(spell_type *spell)
+bool spell_type_dependencies_satisfied(spell_type *spell)
{
assert(spell != NULL);
if (spell->depend_func != NULL) {
return spell->depend_func();
} else {
- return TRUE;
+ return true;
}
}
diff --git a/src/spell_type.hpp b/src/spell_type.hpp
index 43758103..4519832b 100644
--- a/src/spell_type.hpp
+++ b/src/spell_type.hpp
@@ -4,7 +4,7 @@
#include <vector>
#include <string>
#include <functional>
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "device_allocation_fwd.hpp"
#include "range_fwd.hpp"
@@ -24,63 +24,63 @@ enum random_type { RANDOM, NO_RANDOM };
void spell_type_init_music(spell_type *spell,
s16b minimum_pval,
- const char* (*info_func)(),
+ std::string (*info_func)(),
casting_result (*effect_func)());
void spell_type_init_music_lasting(spell_type *spell,
s16b minimum_pval,
- const char* (*info_func)(),
+ std::string (*info_func)(),
casting_result (*effect_func)(),
int (*lasting_func)());
void spell_type_init_mage(spell_type *spell,
random_type random_type,
s32b school_idx,
- const char* (*info_func)(),
+ std::string (*info_func)(),
casting_result (*effect_func)());
void spell_type_init_priest(spell_type *spell,
s32b school_idx,
- const char* (*info_func)(),
+ std::string (*info_func)(),
casting_result (*effect_func)());
void spell_type_init_device(spell_type *spell,
- const char* (*info_func)(),
+ std::string (*info_func)(),
casting_result (*effect_func)());
void spell_type_init_demonology(spell_type *spell,
- const char* (*info_func)(),
+ std::string (*info_func)(),
casting_result (*effect_func)());
void spell_type_init_geomancy(spell_type *spell,
- const char* (*info_func)(),
+ std::string (*info_func)(),
casting_result (*effect_func)(),
- bool_ (*depend_func)());
+ bool (*depend_func)());
void spell_type_set_inertia(spell_type *spell, s32b difficulty, s32b delay);
void spell_type_set_difficulty(spell_type *spell, byte skill_level, s32b failure_rate);
void spell_type_set_mana(spell_type *spell, s32b min, s32b max);
-void spell_type_set_castable_while_blind(spell_type *spell, bool_ value);
-void spell_type_set_castable_while_confused(spell_type *spell, bool_ value);
-void spell_type_describe(spell_type *spell, cptr line);
+void spell_type_set_castable_while_blind(spell_type *spell, bool value);
+void spell_type_set_castable_while_confused(spell_type *spell, bool value);
+void spell_type_describe(spell_type *spell, const char *line);
void spell_type_add_school(spell_type *spell, s32b school_idx);
-void spell_type_set_device_charges(spell_type *spell, cptr charges_s);
+void spell_type_set_device_charges(spell_type *spell, const char *charges_s);
void spell_type_add_device_allocation(spell_type *spell, device_allocation *a);
-spell_type *spell_type_new(cptr name);
+spell_type *spell_type_new(const char *name);
int spell_type_produce_effect_lasting(spell_type *spell);
casting_result spell_type_produce_effect(spell_type *spell);
-cptr spell_type_name(spell_type *spell);
+const char *spell_type_name(spell_type *spell);
int spell_type_skill_level(spell_type *spell);
long spell_type_roll_charges(spell_type *spell);
struct device_allocation *spell_type_device_allocation(spell_type *spell, byte tval);
-bool_ spell_type_uses_piety_to_cast(spell_type *spell);
-bool_ spell_type_castable_while_blind(spell_type *spell);
-bool_ spell_type_castable_while_confused(spell_type *spell);
+bool spell_type_uses_piety_to_cast(spell_type *spell);
+bool spell_type_castable_while_blind(spell_type *spell);
+bool spell_type_castable_while_confused(spell_type *spell);
s16b spell_type_minimum_pval(spell_type *spell);
s16b spell_type_random_type(spell_type *spell);
std::vector<s32b> const spell_type_get_schools(spell_type *spell);
-bool_ spell_type_inertia(spell_type *spell, s32b *difficulty, s32b *delay);
+bool spell_type_inertia(spell_type *spell, s32b *difficulty, s32b *delay);
s32b spell_type_failure_rate(spell_type *spell);
s16b spell_type_casting_stat(spell_type *spell);
-cptr spell_type_info(spell_type *spell);
+std::string spell_type_info(spell_type *spell);
void spell_type_mana_range(spell_type *spell, struct range_type *range);
-bool_ spell_type_dependencies_satisfied(spell_type *spell);
+bool spell_type_dependencies_satisfied(spell_type *spell);
void spell_type_description_foreach(spell_type *spell, std::function<void (std::string const &text)>);
diff --git a/src/spell_type_fwd.hpp b/src/spell_type_fwd.hpp
index a3b27d27..d5b065d1 100644
--- a/src/spell_type_fwd.hpp
+++ b/src/spell_type_fwd.hpp
@@ -5,8 +5,7 @@
*/
typedef enum {
NO_CAST, /* Spell not cast; user aborted */
- CAST_OBVIOUS, /* Cast; caster discovers effect (devices) */
- CAST_HIDDEN /* Cast; caster does NOT discover effect (devices) */
+ CAST, /* Spell was cast */
} casting_result;
/*
diff --git a/src/spellbinder.hpp b/src/spellbinder.hpp
index 078d9eac..d7f41f63 100644
--- a/src/spellbinder.hpp
+++ b/src/spellbinder.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include <vector>
/**
diff --git a/src/spells1.cc b/src/spells1.cc
index 4df1a7c6..d805ea08 100644
--- a/src/spells1.cc
+++ b/src/spells1.cc
@@ -18,6 +18,7 @@
#include "files.hpp"
#include "feature_flag.hpp"
#include "feature_type.hpp"
+#include "format_ext.hpp"
#include "game.hpp"
#include "gods.hpp"
#include "melee2.hpp"
@@ -42,17 +43,19 @@
#include "stats.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "util.h"
#include "variable.hpp"
#include "wizard2.hpp"
#include "xtra1.hpp"
#include "xtra2.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
+#include <boost/algorithm/string/predicate.hpp>
#include <chrono>
#include <fmt/format.h>
#include <thread>
+using boost::algorithm::starts_with;
using std::this_thread::sleep_for;
using std::chrono::milliseconds;
@@ -142,9 +145,9 @@ void teleport_player_directed(int rad, int dir)
int min = rad / 4;
int dis = rad;
int i, d;
- bool_ look = TRUE;
- bool_ y_major = FALSE;
- bool_ x_major = FALSE;
+ bool look = true;
+ bool y_major = false;
+ bool x_major = false;
int y_neg = 1;
int x_neg = 1;
cave_type *c_ptr;
@@ -158,8 +161,8 @@ void teleport_player_directed(int rad, int dir)
/* Rooted means no move */
if (p_ptr->tim_roots) return;
- if (yfoo == 0) x_major = TRUE;
- if (xfoo == 0) y_major = TRUE;
+ if (yfoo == 0) x_major = true;
+ if (xfoo == 0) y_major = true;
if (yfoo < 0) y_neg = -1;
if (xfoo < 0) x_neg = -1;
@@ -177,7 +180,7 @@ void teleport_player_directed(int rad, int dir)
for (i = 0; i < 500; i++)
{
/* Pick a (possibly illegal) location */
- while (1)
+ while (true)
{
if (y_major)
{
@@ -208,7 +211,7 @@ void teleport_player_directed(int rad, int dir)
if (!cave_empty_bold(y, x)) continue;
/* This grid looks good */
- look = FALSE;
+ look = false;
/* Stop looking */
break;
@@ -251,7 +254,7 @@ void teleport_player_directed(int rad, int dir)
*/
void teleport_away(int m_idx, int dis)
{
- bool_ look = TRUE;
+ bool look = true;
monster_type *m_ptr = &m_list[m_idx];
@@ -286,7 +289,7 @@ void teleport_away(int m_idx, int dis)
for (int i = 0; i < 500; i++)
{
/* Pick a (possibly illegal) location */
- while (1)
+ while (true)
{
ny = rand_spread(oy, dis);
nx = rand_spread(ox, dis);
@@ -304,16 +307,12 @@ void teleport_away(int m_idx, int dis)
if (cave[ny][nx].feat == FEAT_GLYPH) continue;
if (cave[ny][nx].feat == FEAT_MINOR_GLYPH) continue;
- /* ...nor onto the Pattern */
- if ((cave[ny][nx].feat >= FEAT_PATTERN_START) &&
- (cave[ny][nx].feat <= FEAT_PATTERN_XTRA2)) continue;
-
/* No teleporting into vaults and such */
if (!(p_ptr->inside_quest))
if (cave[ny][nx].info & (CAVE_ICKY)) continue;
/* This grid looks good */
- look = FALSE;
+ look = false;
/* Stop looking */
break;
@@ -342,7 +341,7 @@ void teleport_away(int m_idx, int dis)
m_ptr->fx = nx;
/* Update the monster (new location) */
- update_mon(m_idx, TRUE);
+ update_mon(m_idx, true);
/* Redraw the old grid */
lite_spot(oy, ox);
@@ -394,7 +393,7 @@ static void teleport_to_player(int m_idx)
int nx = 0;
/* Look until done */
- bool_ look = TRUE;
+ bool look = true;
while (look && --attempts)
{
/* Verify max distance */
@@ -404,7 +403,7 @@ static void teleport_to_player(int m_idx)
for (int i = 0; i < 500; i++)
{
/* Pick a (possibly illegal) location */
- while (1)
+ while (true)
{
ny = rand_spread(p_ptr->py, dis);
nx = rand_spread(p_ptr->px, dis);
@@ -422,15 +421,11 @@ static void teleport_to_player(int m_idx)
if (cave[ny][nx].feat == FEAT_GLYPH) continue;
if (cave[ny][nx].feat == FEAT_MINOR_GLYPH) continue;
- /* ...nor onto the Pattern */
- if ((cave[ny][nx].feat >= FEAT_PATTERN_START) &&
- (cave[ny][nx].feat <= FEAT_PATTERN_XTRA2)) continue;
-
/* No teleporting into vaults and such */
/* if (cave[ny][nx].info & (CAVE_ICKY)) continue; */
/* This grid looks good */
- look = FALSE;
+ look = false;
/* Stop looking */
break;
@@ -458,7 +453,7 @@ static void teleport_to_player(int m_idx)
m_ptr->fx = nx;
/* Update the monster (new location) */
- update_mon(m_idx, TRUE);
+ update_mon(m_idx, true);
/* Redraw the old grid */
lite_spot(oy, ox);
@@ -478,16 +473,18 @@ static void teleport_to_player(int m_idx)
* Try very hard to move the player at least a quarter that distance.
*/
/* It'd be better if this was made an argument ... */
-bool_ teleport_player_bypass = FALSE;
+bool teleport_player_bypass = false;
void teleport_player(int dis)
{
+ auto const &dungeon_flags = game->dungeon_flags;
+
int d, i, min, ox, oy, x = 0, y = 0;
int tries = 0;
int xx = -1, yy = -1;
- bool_ look = TRUE;
+ bool look = true;
if (p_ptr->resist_continuum && (!teleport_player_bypass))
{
@@ -530,7 +527,7 @@ void teleport_player(int dis)
for (i = 0; i < 500; i++)
{
/* Pick a (possibly illegal) location */
- while (1)
+ while (true)
{
y = rand_spread(p_ptr->py, dis);
x = rand_spread(p_ptr->px, dis);
@@ -548,7 +545,7 @@ void teleport_player(int dis)
if (cave[y][x].info & (CAVE_ICKY)) continue;
/* This grid looks good */
- look = FALSE;
+ look = false;
/* Stop looking */
break;
@@ -640,7 +637,7 @@ void get_pos_player(int dis, int *ny, int *nx)
int d, i, min, x = 0, y = 0;
int tries = 0;
- bool_ look = TRUE;
+ bool look = true;
if (dis > 200) dis = 200; /* To be on the safe side... */
@@ -659,7 +656,7 @@ void get_pos_player(int dis, int *ny, int *nx)
for (i = 0; i < 500; i++)
{
/* Pick a (possibly illegal) location */
- while (1)
+ while (true)
{
y = rand_spread(p_ptr->py, dis);
x = rand_spread(p_ptr->px, dis);
@@ -677,7 +674,7 @@ void get_pos_player(int dis, int *ny, int *nx)
if (cave[y][x].info & (CAVE_ICKY)) continue;
/* This grid looks good */
- look = FALSE;
+ look = false;
/* Stop looking */
break;
@@ -720,10 +717,10 @@ void teleport_monster_to(int m_idx, int ny, int nx)
}
/* Find a usable location */
- while (1)
+ while (true)
{
/* Pick a nearby legal location */
- while (1)
+ while (true)
{
y = rand_spread(ny, dis);
x = rand_spread(nx, dis);
@@ -755,7 +752,7 @@ void teleport_monster_to(int m_idx, int ny, int nx)
last_teleportation_x = x;
/* Update the monster (new location) */
- update_mon(m_idx, TRUE);
+ update_mon(m_idx, true);
/* Redraw the old spot */
lite_spot(oy, ox);
@@ -773,6 +770,8 @@ void teleport_monster_to(int m_idx, int ny, int nx)
*/
void teleport_player_to(int ny, int nx)
{
+ auto const &dungeon_flags = game->dungeon_flags;
+
int y, x, oy, ox, dis = 0, ctr = 0;
if (p_ptr->resist_continuum)
@@ -797,10 +796,10 @@ void teleport_player_to(int ny, int nx)
if (p_ptr->tim_roots) return;
/* Find a usable location */
- while (1)
+ while (true)
{
/* Pick a nearby legal location */
- while (1)
+ while (true)
{
y = rand_spread(ny, dis);
x = rand_spread(nx, dis);
@@ -857,6 +856,8 @@ void teleport_player_to(int ny, int nx)
*/
void teleport_player_level()
{
+ auto const &dungeon_flags = game->dungeon_flags;
+
/* No effect in arena or quest */
if (p_ptr->inside_quest)
{
@@ -905,7 +906,7 @@ void teleport_player_level()
dun_level++;
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
}
else if (is_quest(dun_level) || (dun_level >= MAX_DEPTH - 1))
{
@@ -916,7 +917,7 @@ void teleport_player_level()
dun_level--;
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
}
else if (rand_int(100) < 50)
{
@@ -927,7 +928,7 @@ void teleport_player_level()
dun_level--;
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
}
else
{
@@ -938,7 +939,7 @@ void teleport_player_level()
dun_level++;
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
}
}
@@ -1207,7 +1208,7 @@ void spellbinder_trigger()
for (auto spell_idx: spellbinder->spell_idxs)
{
msg_format("Triggering spell %s.", spell_type_name(spell_at(spell_idx)));
- lua_cast_school_spell(spell_idx, TRUE);
+ lua_cast_school_spell(spell_idx, true);
}
spellbinder->spell_idxs.clear();
@@ -1224,13 +1225,13 @@ void spellbinder_trigger()
* the game when he dies, since the "You die." message is shown before
* setting the player to "dead".
*/
-void take_hit(int damage, cptr hit_from)
+void take_hit(int damage, const char *hit_from)
{
object_type *o_ptr = &p_ptr->inventory[INVEN_CARRY];
int old_chp = p_ptr->chp;
- bool_ pen_invuln = FALSE;
- bool_ monster_take = FALSE;
+ bool pen_invuln = false;
+ bool monster_take = false;
char death_message[80];
@@ -1248,7 +1249,7 @@ void take_hit(int damage, cptr hit_from)
{
if (randint(PENETRATE_INVULNERABILITY) == 1)
{
- pen_invuln = TRUE;
+ pen_invuln = true;
}
else
{
@@ -1276,7 +1277,7 @@ void take_hit(int damage, cptr hit_from)
}
/* Hurt the wielded monster if any */
- if ((o_ptr->k_idx) && (magik(5 + get_skill(SKILL_SYMBIOTIC))) && (!carried_monster_hit))
+ if (o_ptr->k_ptr && (magik(5 + get_skill(SKILL_SYMBIOTIC))) && (!carried_monster_hit))
{
auto sym_name = symbiote_name(true);
@@ -1294,10 +1295,10 @@ void take_hit(int damage, cptr hit_from)
{
msg_format("%s takes the damage instead of you.", sym_name.c_str());
o_ptr->pval2 -= damage;
- monster_take = TRUE;
+ monster_take = true;
}
- carried_monster_hit = FALSE;
+ carried_monster_hit = false;
/* Display the monster hitpoints */
p_ptr->redraw |= (PR_FRAME);
@@ -1341,14 +1342,14 @@ void take_hit(int damage, cptr hit_from)
}
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
/* No longer a winner */
- total_winner = FALSE;
+ total_winner = false;
/* Note death */
- death = TRUE;
+ death = true;
if (get_check("Dump the screen? "))
{
@@ -1454,7 +1455,7 @@ void take_hit(int damage, cptr hit_from)
chance /= 10;
if (chance < 1) chance = 1;
for (i = 0; i < chance; i++)
- summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level / 2, type, FALSE);
+ summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level / 2, type, false);
msg_print("Melkor summons monsters to help you!");
}
}
@@ -1466,9 +1467,14 @@ void take_hit(int damage, cptr hit_from)
}
}
+void take_hit(int damage, std::string const &kb_str)
+{
+ take_hit(damage, kb_str.c_str());
+}
+
/* Decrease player's sanity. This is a copy of the function above. */
-void take_sanity_hit(int damage, cptr hit_from)
+void take_sanity_hit(int damage, const char *hit_from)
{
int old_csane = p_ptr->csane;
@@ -1517,10 +1523,10 @@ void take_sanity_hit(int damage, cptr hit_from)
}
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
/* Note death */
- death = TRUE;
+ death = true;
if (get_check("Dump the screen? "))
{
@@ -1557,7 +1563,7 @@ void take_sanity_hit(int damage, cptr hit_from)
* Does a given class of objects (usually) hate acid?
* Note that acid can either melt or corrode something.
*/
-static bool_ hates_acid(object_type *o_ptr)
+static bool hates_acid(object_type *o_ptr)
{
/* Analyze the type */
switch (o_ptr->tval)
@@ -1580,20 +1586,14 @@ static bool_ hates_acid(object_type *o_ptr)
case TV_HARD_ARMOR:
case TV_DRAG_ARMOR:
{
- return (TRUE);
+ return true;
}
/* Staffs/Scrolls are wood/paper */
case TV_STAFF:
case TV_SCROLL:
{
- return (TRUE);
- }
-
- /* Ouch */
- case TV_CHEST:
- {
- return (TRUE);
+ return true;
}
/* Junk is useless */
@@ -1601,18 +1601,18 @@ static bool_ hates_acid(object_type *o_ptr)
case TV_BOTTLE:
case TV_EGG:
{
- return (TRUE);
+ return true;
}
}
- return (FALSE);
+ return false;
}
/*
* Does a given object (usually) hate electricity?
*/
-static bool_ hates_elec(object_type *o_ptr)
+static bool hates_elec(object_type *o_ptr)
{
switch (o_ptr->tval)
{
@@ -1620,11 +1620,11 @@ static bool_ hates_elec(object_type *o_ptr)
case TV_WAND:
case TV_EGG:
{
- return (TRUE);
+ return true;
}
}
- return (FALSE);
+ return false;
}
@@ -1633,7 +1633,7 @@ static bool_ hates_elec(object_type *o_ptr)
* Hafted/Polearm weapons have wooden shafts.
* Arrows/Bows are mostly wooden.
*/
-static bool_ hates_fire(object_type *o_ptr)
+static bool hates_fire(object_type *o_ptr)
{
/* Analyze the type */
switch (o_ptr->tval)
@@ -1641,7 +1641,7 @@ static bool_ hates_fire(object_type *o_ptr)
/* Special case for archers */
case TV_ARROW:
{
- return TRUE;
+ return true;
};
/* Wearable */
@@ -1654,7 +1654,7 @@ static bool_ hates_fire(object_type *o_ptr)
case TV_CLOAK:
case TV_SOFT_ARMOR:
{
- return (TRUE);
+ return true;
}
/* Books */
@@ -1662,13 +1662,7 @@ static bool_ hates_fire(object_type *o_ptr)
case TV_SYMBIOTIC_BOOK:
case TV_MUSIC_BOOK:
{
- return (TRUE);
- }
-
- /* Chests */
- case TV_CHEST:
- {
- return (TRUE);
+ return true;
}
/* Staffs/Scrolls burn */
@@ -1676,18 +1670,18 @@ static bool_ hates_fire(object_type *o_ptr)
case TV_SCROLL:
case TV_EGG:
{
- return (TRUE);
+ return true;
}
}
- return (FALSE);
+ return false;
}
/*
* Does a given object (usually) hate cold?
*/
-static bool_ hates_cold(object_type *o_ptr)
+static bool hates_cold(object_type *o_ptr)
{
switch (o_ptr->tval)
{
@@ -1697,11 +1691,11 @@ static bool_ hates_cold(object_type *o_ptr)
case TV_BOTTLE:
case TV_EGG:
{
- return (TRUE);
+ return true;
}
}
- return (FALSE);
+ return false;
}
@@ -1717,11 +1711,11 @@ static bool_ hates_cold(object_type *o_ptr)
*/
static int set_acid_destroy(object_type *o_ptr)
{
- if (!hates_acid(o_ptr)) return (FALSE);
+ if (!hates_acid(o_ptr)) return false;
auto const f = object_flags(o_ptr);
- if (f & TR_IGNORE_ACID) return (FALSE);
- return (TRUE);
+ if (f & TR_IGNORE_ACID) return false;
+ return true;
}
@@ -1730,11 +1724,11 @@ static int set_acid_destroy(object_type *o_ptr)
*/
static int set_elec_destroy(object_type *o_ptr)
{
- if (!hates_elec(o_ptr)) return (FALSE);
+ if (!hates_elec(o_ptr)) return false;
auto const f = object_flags(o_ptr);
- if (f & TR_IGNORE_ELEC) return (FALSE);
- return (TRUE);
+ if (f & TR_IGNORE_ELEC) return false;
+ return true;
}
@@ -1743,11 +1737,11 @@ static int set_elec_destroy(object_type *o_ptr)
*/
static int set_fire_destroy(object_type *o_ptr)
{
- if (!hates_fire(o_ptr)) return (FALSE);
+ if (!hates_fire(o_ptr)) return false;
auto const f = object_flags(o_ptr);
- if (f & TR_IGNORE_FIRE) return (FALSE);
- return (TRUE);
+ if (f & TR_IGNORE_FIRE) return false;
+ return true;
}
@@ -1756,11 +1750,11 @@ static int set_fire_destroy(object_type *o_ptr)
*/
static int set_cold_destroy(object_type *o_ptr)
{
- if (!hates_cold(o_ptr)) return (FALSE);
+ if (!hates_cold(o_ptr)) return false;
auto const f = object_flags(o_ptr);
- if (f & (TR_IGNORE_COLD)) return (FALSE);
- return (TRUE);
+ if (f & (TR_IGNORE_COLD)) return false;
+ return true;
}
@@ -1779,25 +1773,21 @@ typedef int (*inven_func)(object_type *);
*/
static int inven_damage(inven_func typ, int perc)
{
- auto const &k_info = game->edit_data.k_info;
-
- int i, j, k, amt;
-
- object_type *o_ptr;
-
- char o_name[80];
-
+ int j, k, amt;
/* Count the casualties */
k = 0;
/* Scan through the slots backwards */
- for (i = 0; i < INVEN_PACK; i++)
+ for (int i = 0; i < INVEN_PACK; i++)
{
- o_ptr = &p_ptr->inventory[i];
+ object_type *o_ptr = &p_ptr->inventory[i];
/* Skip non-objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Hack -- for now, skip artifacts */
if (artifact_p(o_ptr)) continue;
@@ -1815,7 +1805,8 @@ static int inven_damage(inven_func typ, int perc)
if (amt)
{
/* Get a description */
- object_desc(o_name, o_ptr, FALSE, 3);
+ char o_name[80];
+ object_desc(o_name, o_ptr, false, 3);
/* Message */
msg_format("%sour %s (%c) %s destroyed!",
@@ -1826,7 +1817,7 @@ static int inven_damage(inven_func typ, int perc)
((amt > 1) ? "were" : "was"));
/* Potions smash open */
- if (k_info[o_ptr->k_idx].tval == TV_POTION)
+ if (o_ptr->k_ptr->tval == TV_POTION)
{
potion_smash_effect(0, p_ptr->py, p_ptr->px, o_ptr->sval);
}
@@ -1896,14 +1887,14 @@ static int minus_ac()
}
/* Nothing to damage */
- if (!o_ptr->k_idx) return (FALSE);
+ if (!o_ptr->k_ptr) return false;
/* No damage left to be done */
- if (o_ptr->ac + o_ptr->to_a <= 0) return (FALSE);
+ if (o_ptr->ac + o_ptr->to_a <= 0) return false;
/* Describe */
- object_desc(o_name, o_ptr, FALSE, 0);
+ object_desc(o_name, o_ptr, false, 0);
/* Extract the flags */
auto const flags = object_flags(o_ptr);
@@ -1913,7 +1904,7 @@ static int minus_ac()
{
msg_format("Your %s is unaffected!", o_name);
- return (TRUE);
+ return true;
}
/* Message */
@@ -1929,14 +1920,14 @@ static int minus_ac()
p_ptr->window |= (PW_EQUIP | PW_PLAYER);
/* Item was damaged */
- return (TRUE);
+ return true;
}
/*
* Hurt the player with Acid
*/
-void acid_dam(int dam, cptr kb_str)
+void acid_dam(int dam, const char *kb_str)
{
int inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
@@ -1966,7 +1957,7 @@ void acid_dam(int dam, cptr kb_str)
/*
* Hurt the player with electricity
*/
-void elec_dam(int dam, cptr kb_str)
+void elec_dam(int dam, const char *kb_str)
{
int inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
@@ -1995,7 +1986,7 @@ void elec_dam(int dam, cptr kb_str)
/*
* Hurt the player with Fire
*/
-void fire_dam(int dam, cptr kb_str)
+void fire_dam(int dam, const char *kb_str)
{
int inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
@@ -2024,7 +2015,7 @@ void fire_dam(int dam, cptr kb_str)
/*
* Hurt the player with Cold
*/
-void cold_dam(int dam, cptr kb_str)
+void cold_dam(int dam, const char *kb_str)
{
int inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
@@ -2061,9 +2052,9 @@ void cold_dam(int dam, cptr kb_str)
* if your stat is already drained, the "max" value will not drop all
* the way down to the "cur" value.
*/
-bool_ dec_stat(int stat, int amount, int mode)
+bool dec_stat(int stat, int amount, int mode)
{
- int cur, max, loss = 0, same, res = FALSE;
+ int cur, max, loss = 0, same, res = false;
/* Acquire current value */
@@ -2113,7 +2104,7 @@ bool_ dec_stat(int stat, int amount, int mode)
if (cur < 3) cur = 3;
/* Something happened */
- if (cur != p_ptr->stat_cur[stat]) res = TRUE;
+ if (cur != p_ptr->stat_cur[stat]) res = true;
}
/* Damage "max" value */
@@ -2149,7 +2140,7 @@ bool_ dec_stat(int stat, int amount, int mode)
if (same || (max < cur)) max = cur;
/* Something happened */
- if (max != p_ptr->stat_max[stat]) res = TRUE;
+ if (max != p_ptr->stat_max[stat]) res = true;
}
/* Apply changes */
@@ -2195,9 +2186,9 @@ bool_ dec_stat(int stat, int amount, int mode)
/*
- * Restore a stat. Return TRUE only if this actually makes a difference.
+ * Restore a stat. Return true only if this actually makes a difference.
*/
-bool_ res_stat(int stat, bool_ full)
+bool res_stat(int stat, bool full)
{
/* Fully restore */
if (full)
@@ -2216,7 +2207,7 @@ bool_ res_stat(int stat, bool_ full)
p_ptr->update |= (PU_BONUS);
/* Something happened */
- return (TRUE);
+ return true;
}
}
@@ -2237,12 +2228,12 @@ bool_ res_stat(int stat, bool_ full)
p_ptr->update |= (PU_BONUS);
/* Something happened */
- return (TRUE);
+ return true;
}
}
/* Nothing to restore */
- return (FALSE);
+ return false;
}
@@ -2256,9 +2247,9 @@ bool_ res_stat(int stat, bool_ full)
* If "mode is set to 0 then a random slot will be used, if not the "mode"
* slot will be used.
*
- * Return "TRUE" if the player notices anything
+ * Return "true" if the player notices anything
*/
-bool_ apply_disenchant(int mode)
+bool apply_disenchant(int mode)
{
int t = mode;
object_type *o_ptr;
@@ -2300,19 +2291,19 @@ bool_ apply_disenchant(int mode)
o_ptr = &p_ptr->inventory[t];
/* No item, nothing happens */
- if (!o_ptr->k_idx) return (FALSE);
+ if (!o_ptr->k_ptr) return false;
/* Nothing to disenchant */
if ((o_ptr->to_h <= 0) && (o_ptr->to_d <= 0) && (o_ptr->to_a <= 0))
{
/* Nothing to notice */
- return (FALSE);
+ return false;
}
/* Describe the object */
- object_desc(o_name, o_ptr, FALSE, 0);
+ object_desc(o_name, o_ptr, false, 0);
/* Artifacts have 71% chance to resist */
@@ -2324,7 +2315,7 @@ bool_ apply_disenchant(int mode)
((o_ptr->number != 1) ? "" : "s"));
/* Notice */
- return (TRUE);
+ return true;
}
@@ -2352,7 +2343,7 @@ bool_ apply_disenchant(int mode)
p_ptr->window |= (PW_EQUIP | PW_PLAYER);
/* Notice */
- return (TRUE);
+ return true;
}
@@ -2383,6 +2374,8 @@ void corrupt_player()
*/
static void apply_nexus(monster_type *m_ptr)
{
+ auto const &dungeon_flags = game->dungeon_flags;
+
if (m_ptr == NULL) return;
if (!(dungeon_flags & DF_NO_TELEPORT))
@@ -2616,7 +2609,7 @@ static std::vector<std::tuple<int, int>> project_path(unsigned int range, int y1
x = x1 + ddx[dir];
/* Create the projection path */
- while (1)
+ while (true)
{
/* Save grid */
gp.push_back(std::make_tuple(y, x));
@@ -2702,7 +2695,7 @@ static std::vector<std::tuple<int, int>> project_path(unsigned int range, int y1
int k = 0;
/* Create the projection path */
- while (1)
+ while (true)
{
/* Save grid */
gp.push_back(std::make_tuple(y, x));
@@ -2773,7 +2766,7 @@ static std::vector<std::tuple<int, int>> project_path(unsigned int range, int y1
int k = 0;
/* Create the projection path */
- while (1)
+ while (true)
{
/* Save grid */
gp.push_back(std::make_tuple(y, x));
@@ -2835,7 +2828,7 @@ static std::vector<std::tuple<int, int>> project_path(unsigned int range, int y1
x = x1 + sx;
/* Create the projection path */
- while (1)
+ while (true)
{
/* Save grid */
gp.push_back(std::make_tuple(y, x));
@@ -2897,22 +2890,22 @@ static int project_m_y;
* Note that we determine if the player can "see" anything that happens
* by taking into account: blindness, line-of-sight, and illumination.
*
- * We return "TRUE" if the effect of the projection is "obvious".
+ * We return "true" if the effect of the projection is "obvious".
*
* XXX XXX XXX We also "see" grids which are "memorized", probably a hack
*
* XXX XXX XXX Perhaps we should affect doors?
*/
-static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
+static bool project_f(int who, int r, int y, int x, int dam, int typ)
{
cave_type *c_ptr = &cave[y][x];
auto const &f_info = game->edit_data.f_info;
- bool_ obvious = FALSE;
+ bool obvious = false;
- bool_ flag = FALSE;
+ bool flag = false;
- bool_ seen;
+ bool seen;
/* XXX XXX XXX */
@@ -2954,7 +2947,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
{
cave_set_feat(y, x, FEAT_ICE);
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
}
break;
@@ -3001,13 +2994,13 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
if (seen)
{
- obvious = TRUE;
+ obvious = true;
note_spot(y, x);
}
if (player_can_see_bold(y2, x2))
{
- obvious = TRUE;
+ obvious = true;
note_spot(y2, x2);
}
@@ -3032,7 +3025,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
/* Silly thing to destroy trees when a yavanna worshipper */
inc_piety(GOD_YAVANNA, -50);
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
}
/* Trees *will* burn */
@@ -3043,7 +3036,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
/* Silly thing to destroy trees when a yavanna worshipper */
inc_piety(GOD_YAVANNA, -60);
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
}
/* Ice can melt (chance == 30%) */
@@ -3057,7 +3050,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
if (k < 10) cave_set_feat(y, x, FEAT_DIRT);
else if (k < 30) cave_set_feat(y, x, FEAT_SHAL_WATER);
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
}
/* Floors can become ash or lava (chance == 25%) */
@@ -3071,7 +3064,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
if (k < 10) cave_set_feat(y, x, FEAT_SHAL_LAVA);
else if (k < 25) cave_set_feat(y, x, FEAT_ASH);
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
}
/* Sandwall can be turned into glass (chance == 30%) */
@@ -3089,7 +3082,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
/* Visibility change */
p_ptr->update |= (PU_VIEW | PU_MONSTERS | PU_MON_LITE);
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
}
}
@@ -3162,7 +3155,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
if (f == FEAT_FLOOR) place_floor_convert_glass(y, x);
else cave_set_feat(y, x, f);
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
}
break;
@@ -3188,7 +3181,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
/* Silly thing to destroy trees when a yavanna worshipper */
inc_piety(GOD_YAVANNA, -50);
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
}
break;
@@ -3216,7 +3209,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
/* Visibility change */
p_ptr->update |= (PU_VIEW | PU_MONSTERS | PU_MON_LITE);
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
}
break;
@@ -3236,7 +3229,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
{
/* Message */
msg_print("There is a bright flash of light!");
- obvious = TRUE;
+ obvious = true;
/* Visibility change */
if ((c_ptr->feat >= FEAT_DOOR_HEAD) &&
@@ -3278,7 +3271,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
{
/* Message */
msg_print("The door seems stuck.");
- obvious = TRUE;
+ obvious = true;
}
}
@@ -3302,7 +3295,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
if (c_ptr->info & (CAVE_MARK))
{
msg_print("The wall turns into mud!");
- obvious = TRUE;
+ obvious = true;
}
/* Forget the wall */
@@ -3322,7 +3315,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
{
msg_print("The vein turns into mud!");
msg_print("You have found something!");
- obvious = TRUE;
+ obvious = true;
}
/* Forget the wall */
@@ -3345,7 +3338,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
if (c_ptr->info & (CAVE_MARK))
{
msg_print("The vein turns into mud!");
- obvious = TRUE;
+ obvious = true;
}
/* Forget the wall */
@@ -3362,7 +3355,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
if (c_ptr->info & (CAVE_MARK))
{
msg_print("The rubble turns into mud!");
- obvious = TRUE;
+ obvious = true;
}
/* Forget the wall */
@@ -3378,11 +3371,11 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
if (seen)
{
msg_print("There was something buried in the rubble!");
- obvious = TRUE;
+ obvious = true;
}
/* Place gold */
- place_object(y, x, FALSE, FALSE, OBJ_FOUND_RUBBLE);
+ place_object(y, x, false, false, OBJ_FOUND_RUBBLE);
}
}
@@ -3395,7 +3388,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
if (c_ptr->info & (CAVE_MARK))
{
msg_print("The door turns into mud!");
- obvious = TRUE;
+ obvious = true;
}
/* Forget the wall */
@@ -3426,7 +3419,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
cave_set_feat(y, x, FEAT_DOOR_HEAD + 0x00);
/* Observe */
- if (c_ptr->info & (CAVE_MARK)) obvious = TRUE;
+ if (c_ptr->info & (CAVE_MARK)) obvious = true;
/* Update some things */
p_ptr->update |= (PU_VIEW | PU_MONSTERS | PU_MON_LITE);
@@ -3443,7 +3436,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
cave_set_feat(y, x, FEAT_GLYPH);
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
break;
}
@@ -3461,7 +3454,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
/* Place a wall */
cave_set_feat(y, x, FEAT_WALL_EXTRA);
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Update some things */
p_ptr->update |= (PU_VIEW | PU_MONSTERS | PU_MON_LITE);
@@ -3510,7 +3503,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
/* Place a shallow lava */
cave_set_feat(y, x, FEAT_SHAL_LAVA);
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
}
/* Deep Lava */
@@ -3522,7 +3515,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
/* Place a deep lava */
cave_set_feat(y, x, FEAT_DEEP_LAVA);
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Dam is used as a counter for the number of grid to convert */
dam--;
@@ -3545,13 +3538,13 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
lite_spot(y, x);
/* Observe */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/*
* Mega-Hack -- Update the monster in the affected grid
* This allows "spear of light" (etc) to work "correctly"
*/
- if (c_ptr->m_idx) update_mon(c_ptr->m_idx, FALSE);
+ if (c_ptr->m_idx) update_mon(c_ptr->m_idx, false);
break;
}
@@ -3561,7 +3554,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
case GF_DARK:
{
/* Notice */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Turn off the light. */
c_ptr->info &= ~(CAVE_GLOW);
@@ -3583,7 +3576,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
* Mega-Hack -- Update the monster in the affected grid
* This allows "spear of light" (etc) to work "correctly"
*/
- if (c_ptr->m_idx) update_mon(c_ptr->m_idx, FALSE);
+ if (c_ptr->m_idx) update_mon(c_ptr->m_idx, false);
/* All done */
break;
@@ -3603,7 +3596,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
if ((x == p_ptr->px) && (y == p_ptr->py))
{
/* Hurt the player later */
- flag = TRUE;
+ flag = true;
/* Do not hurt this grid */
break;
@@ -3663,7 +3656,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
p_ptr->update |= (PU_VIEW | PU_FLOW | PU_MONSTERS | PU_MON_LITE);
}
- obvious = TRUE;
+ obvious = true;
break;
}
@@ -3677,7 +3670,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ)
case GF_ELEMENTAL_GROWTH:
{
- geomancy_random_floor(y, x, FALSE);
+ geomancy_random_floor(y, x, false);
break;
}
}
@@ -3732,21 +3725,20 @@ static int raise_ego[MAX_RAISE] =
*
* XXX XXX XXX We also "see" grids which are "memorized", probably a hack
*
- * We return "TRUE" if the effect of the projection is "obvious".
+ * We return "true" if the effect of the projection is "obvious".
*/
-static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
+static bool project_o(int who, int r, int y, int x, int dam, int typ)
{
auto const &r_info = game->edit_data.r_info;
- auto const &k_info = game->edit_data.k_info;
cave_type *c_ptr = &cave[y][x];
- bool_ obvious = FALSE;
+ bool obvious = false;
char o_name[80];
int o_sval = 0;
- bool_ is_potion = FALSE;
+ bool is_potion = false;
/* XXX XXX XXX */
@@ -3764,12 +3756,12 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
/* Scan all objects in the grid */
for (auto const this_o_idx: object_idxs)
{
- bool_ is_art = FALSE;
- bool_ ignore = FALSE;
- bool_ plural = FALSE;
- bool_ do_kill = FALSE;
+ bool is_art = false;
+ bool ignore = false;
+ bool plural = false;
+ bool do_kill = false;
- cptr note_kill = NULL;
+ const char *note_kill = NULL;
/* Acquire object */
object_type * o_ptr = &o_list[this_o_idx];
@@ -3778,10 +3770,10 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
auto const flags = object_flags(o_ptr);
/* Get the "plural"-ness */
- if (o_ptr->number > 1) plural = TRUE;
+ if (o_ptr->number > 1) plural = true;
/* Check for artifact */
- if (artifact_p(o_ptr)) is_art = TRUE;
+ if (artifact_p(o_ptr)) is_art = true;
/* Analyze the type */
switch (typ)
@@ -3806,7 +3798,7 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
/* Adjust the radius */
radius = radius * dam / 100;
- do_kill = TRUE;
+ do_kill = true;
note_kill = (plural ? " explode!" : " explodes!");
project(who, radius, y, x, dama, GF_SHARDS, PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL);
}
@@ -3818,9 +3810,9 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
{
if (hates_acid(o_ptr))
{
- do_kill = TRUE;
+ do_kill = true;
note_kill = (plural ? " melt!" : " melts!");
- if (flags & TR_IGNORE_ACID) ignore = TRUE;
+ if (flags & TR_IGNORE_ACID) ignore = true;
}
break;
}
@@ -3830,9 +3822,9 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
{
if (hates_elec(o_ptr))
{
- do_kill = TRUE;
+ do_kill = true;
note_kill = (plural ? " are destroyed!" : " is destroyed!");
- if (flags & TR_IGNORE_ELEC) ignore = TRUE;
+ if (flags & TR_IGNORE_ELEC) ignore = true;
}
break;
}
@@ -3842,9 +3834,9 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
{
if (hates_fire(o_ptr))
{
- do_kill = TRUE;
+ do_kill = true;
note_kill = (plural ? " burn up!" : " burns up!");
- if (flags & TR_IGNORE_FIRE) ignore = TRUE;
+ if (flags & TR_IGNORE_FIRE) ignore = true;
}
break;
}
@@ -3855,8 +3847,8 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
if (hates_cold(o_ptr))
{
note_kill = (plural ? " shatter!" : " shatters!");
- do_kill = TRUE;
- if (flags & TR_IGNORE_COLD) ignore = TRUE;
+ do_kill = true;
+ if (flags & TR_IGNORE_COLD) ignore = true;
}
break;
}
@@ -3866,16 +3858,16 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
{
if (hates_fire(o_ptr))
{
- do_kill = TRUE;
+ do_kill = true;
note_kill = (plural ? " burn up!" : " burns up!");
- if (flags & TR_IGNORE_FIRE) ignore = TRUE;
+ if (flags & TR_IGNORE_FIRE) ignore = true;
}
if (hates_elec(o_ptr))
{
- ignore = FALSE;
- do_kill = TRUE;
+ ignore = false;
+ do_kill = true;
note_kill = (plural ? " are destroyed!" : " is destroyed!");
- if (flags & TR_IGNORE_ELEC) ignore = TRUE;
+ if (flags & TR_IGNORE_ELEC) ignore = true;
}
break;
}
@@ -3885,16 +3877,16 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
{
if (hates_fire(o_ptr))
{
- do_kill = TRUE;
+ do_kill = true;
note_kill = (plural ? " burn up!" : " burns up!");
- if (flags & TR_IGNORE_FIRE) ignore = TRUE;
+ if (flags & TR_IGNORE_FIRE) ignore = true;
}
if (hates_cold(o_ptr))
{
- ignore = FALSE;
- do_kill = TRUE;
+ ignore = false;
+ do_kill = true;
note_kill = (plural ? " shatter!" : " shatters!");
- if (flags & TR_IGNORE_COLD) ignore = TRUE;
+ if (flags & TR_IGNORE_COLD) ignore = true;
}
break;
}
@@ -3908,7 +3900,7 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
if (hates_cold(o_ptr))
{
note_kill = (plural ? " shatter!" : " shatters!");
- do_kill = TRUE;
+ do_kill = true;
}
break;
}
@@ -3916,23 +3908,23 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
/* Mana and Chaos -- destroy everything */
case GF_MANA:
{
- do_kill = TRUE;
+ do_kill = true;
note_kill = (plural ? " are destroyed!" : " is destroyed!");
break;
}
case GF_DISINTEGRATE:
{
- do_kill = TRUE;
+ do_kill = true;
note_kill = (plural ? " evaporate!" : " evaporates!");
break;
}
case GF_CHAOS:
{
- do_kill = TRUE;
+ do_kill = true;
note_kill = (plural ? " are destroyed!" : " is destroyed!");
- if (flags & TR_RES_CHAOS) ignore = TRUE;
+ if (flags & TR_RES_CHAOS) ignore = true;
break;
}
@@ -3942,55 +3934,11 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
{
if (cursed_p(o_ptr))
{
- do_kill = TRUE;
+ do_kill = true;
note_kill = (plural ? " are destroyed!" : " is destroyed!");
}
break;
}
-
- /* Unlock chests */
- case GF_KILL_DOOR:
- {
- /* Chests are noticed only if trapped or locked */
- if (o_ptr->tval == TV_CHEST)
- {
- /* Disarm/Unlock traps */
- if (o_ptr->pval > 0)
- {
- /* Disarm or Unlock */
- o_ptr->pval = (0 - o_ptr->pval);
-
- /* Identify */
- object_known(o_ptr);
-
- /* Notice */
- if (o_ptr->marked)
- {
- msg_print("Click!");
- obvious = TRUE;
- }
- }
- }
-
- break;
- }
- case GF_STAR_IDENTIFY:
- {
- /* Identify it fully */
- object_aware(o_ptr);
- object_known(o_ptr);
-
- /* Mark the item as fully known */
- o_ptr->ident |= (IDENT_MENTAL);
-
- /* Process the appropriate hooks */
- identify_hooks(0 - this_o_idx, o_ptr, IDENT_FULL);
-
- /* Squelch ! */
- squeltch_grid();
-
- break;
- }
case GF_RAISE:
{
get_pos_player(7, &y, &x);
@@ -4000,16 +3948,16 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
{
int ego = raise_ego[rand_int(MAX_RAISE)];
- if (place_monster_one(y, x, o_ptr->pval2, ego, FALSE, (!who) ? MSTATUS_PET : MSTATUS_ENEMY))
+ if (place_monster_one(y, x, o_ptr->pval2, ego, false, (!who) ? MSTATUS_PET : MSTATUS_ENEMY))
msg_print("A monster rises from the grave!");
- do_kill = TRUE;
+ do_kill = true;
}
break;
}
case GF_RAISE_DEMON:
{
auto r_ptr = &r_info[o_ptr->pval2];
- cptr name;
+ const char *name;
if (o_ptr->tval != TV_CORPSE) break;
@@ -4028,11 +3976,11 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
else if (r_ptr->level < 90) name = "Marilith";
else name = "Nycadaemon";
- if (place_monster_one(y, x, test_monster_name(name), 0, FALSE, (!who) ? MSTATUS_PET : MSTATUS_ENEMY))
+ if (place_monster_one(y, x, test_monster_name(name), 0, false, (!who) ? MSTATUS_PET : MSTATUS_ENEMY))
msg_print("A demon emerges from Hell!");
}
- do_kill = TRUE;
+ do_kill = true;
break;
}
default:
@@ -4046,8 +3994,8 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
/* Effect "observed" */
if (o_ptr->marked)
{
- obvious = TRUE;
- object_desc(o_name, o_ptr, FALSE, 0);
+ obvious = true;
+ object_desc(o_name, o_ptr, false, 0);
}
/* Artifacts, and other objects, get to resist */
@@ -4071,7 +4019,7 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
}
o_sval = o_ptr->sval;
- is_potion = ((k_info[o_ptr->k_idx].tval == TV_POTION) || (k_info[o_ptr->k_idx].tval == TV_POTION2));
+ is_potion = ((o_ptr->k_ptr->tval == TV_POTION) || (o_ptr->k_ptr->tval == TV_POTION2));
/* Delete the object */
@@ -4095,10 +4043,10 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
}
/* Can the monster be hurt ? */
-bool_ hurt_monster(monster_type *m_ptr)
+bool hurt_monster(monster_type *m_ptr)
{
- if (m_ptr->status == MSTATUS_COMPANION) return FALSE;
- else return TRUE;
+ if (m_ptr->status == MSTATUS_COMPANION) return false;
+ else return true;
}
/*
@@ -4150,12 +4098,14 @@ bool_ hurt_monster(monster_type *m_ptr)
* In this function, "result" messages are postponed until the end, where
* the "note" string is appended to the monster name, if not NULL. So,
* to make a spell have "no effect" just set "note" to NULL. You should
- * also set "notice" to FALSE, or the player will learn what the spell does.
+ * also set "notice" to false, or the player will learn what the spell does.
*
- * We attempt to return "TRUE" if the player saw anything "useful" happen.
+ * We attempt to return "true" if the player saw anything "useful" happen.
*/
-bool_ project_m(int who, int r, int y, int x, int dam, int typ)
+bool project_m(int who, int r, int y, int x, int dam, int typ)
{
+ auto const &dungeon_flags = game->dungeon_flags;
+
int tmp;
cave_type *c_ptr = &cave[y][x];
@@ -4165,13 +4115,13 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
char killer [80];
/* Is the monster "seen"? */
- bool_ seen;
+ bool seen;
/* Were the effects "obvious" (if seen)? */
- bool_ obvious = FALSE;
+ bool obvious = false;
/* Were the effects "irrelevant"? */
- bool_ skipped = FALSE;
+ bool skipped = false;
/* Move setting */
@@ -4210,27 +4160,27 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
char m_name[80];
/* Assume no note */
- cptr note = NULL;
+ const char *note = NULL;
/* Assume a default death */
- cptr note_dies = " dies.";
+ const char *note_dies = " dies.";
/* Nobody here */
- if (!c_ptr->m_idx) return (FALSE);
+ if (!c_ptr->m_idx) return false;
/* Never affect projector */
- if (who && (c_ptr->m_idx == who)) return (FALSE);
+ if (who && (c_ptr->m_idx == who)) return false;
/*
* Don't affect already dead monsters
* Prevents problems with chain reactions of exploding monsters
*/
- if (m_ptr->hp < 0) return (FALSE);
+ if (m_ptr->hp < 0) return false;
/* Remember if the monster is within player's line of sight */
- seen = (m_ptr->ml && ((who != -101) && (who != -100))) ? TRUE : FALSE;
+ seen = (m_ptr->ml && ((who != -101) && (who != -100))) ? true : false;
/* Reduce damage by distance */
dam = (dam + r) / (r + 1);
@@ -4265,7 +4215,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (!who && (is_friend(m_ptr) >= 0))
{
- bool_ get_angry = FALSE;
+ bool get_angry = false;
/* Grrr? */
switch (typ)
{
@@ -4287,70 +4237,70 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
break; /* none of the above anger */
case GF_TRAP_DEMONSOUL:
if (r_ptr->flags & RF_DEMON)
- get_angry = TRUE;
+ get_angry = true;
break;
case GF_KILL_WALL:
if (r_ptr->flags & RF_HURT_ROCK)
- get_angry = TRUE;
+ get_angry = true;
break;
case GF_HOLY_FIRE:
if (!(r_ptr->flags & RF_GOOD))
- get_angry = TRUE;
+ get_angry = true;
break;
case GF_TURN_UNDEAD:
case GF_DISP_UNDEAD:
if (r_ptr->flags & RF_UNDEAD)
- get_angry = TRUE;
+ get_angry = true;
break;
case GF_TURN_EVIL:
case GF_DISP_EVIL:
if (r_ptr->flags & RF_EVIL)
- get_angry = TRUE;
+ get_angry = true;
break;
case GF_DISP_GOOD:
if (r_ptr->flags & RF_GOOD)
- get_angry = TRUE;
+ get_angry = true;
break;
case GF_DISP_DEMON:
if (r_ptr->flags & RF_DEMON)
- get_angry = TRUE;
+ get_angry = true;
break;
case GF_DISP_LIVING:
case GF_UNBREATH:
if (!(r_ptr->flags & RF_UNDEAD) &&
!(r_ptr->flags & RF_NONLIVING))
- get_angry = TRUE;
+ get_angry = true;
break;
case GF_PSI:
case GF_PSI_DRAIN:
if (!(r_ptr->flags & RF_EMPTY_MIND))
- get_angry = TRUE;
+ get_angry = true;
break;
case GF_DOMINATION:
if (!(r_ptr->flags & RF_NO_CONF))
- get_angry = TRUE;
+ get_angry = true;
break;
case GF_OLD_POLY:
case GF_OLD_CLONE:
if (randint(8) == 1)
- get_angry = TRUE;
+ get_angry = true;
break;
case GF_LITE:
case GF_LITE_WEAK:
if (r_ptr->flags & RF_HURT_LITE)
- get_angry = TRUE;
+ get_angry = true;
break;
case GF_INSTA_DEATH:
- get_angry = TRUE;
+ get_angry = true;
break;
case GF_ELEMENTAL_GROWTH:
case GF_ELEMENTAL_WALL:
- get_angry = FALSE;
+ get_angry = false;
break;
}
/* Now anger it if appropriate */
- if (get_angry == TRUE && !(who))
+ if (get_angry == true && !(who))
{
switch (is_friend(m_ptr))
{
@@ -4371,11 +4321,11 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
{
case GF_ATTACK:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
py_attack(y, x, dam);
- skipped = TRUE;
+ skipped = true;
dam = 0;
break;
@@ -4384,7 +4334,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Death -- instant death */
case GF_DEATH:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->flags & RF_UNIQUE)
{
@@ -4401,14 +4351,14 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Magic Missile -- pure damage */
case GF_MISSILE:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
break;
}
/* Acid */
case GF_ACID:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->flags & RF_SUSCEP_ACID)
{
note = " is hit hard.";
@@ -4425,7 +4375,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Electricity */
case GF_ELEC:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->flags & RF_SUSCEP_ELEC)
{
note = " is hit hard.";
@@ -4442,7 +4392,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Fire damage */
case GF_FIRE:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->flags & RF_SUSCEP_FIRE)
{
note = " is hit hard.";
@@ -4459,7 +4409,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Cold */
case GF_COLD:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->flags & RF_SUSCEP_COLD)
{
note = " is hit hard.";
@@ -4476,7 +4426,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Poison */
case GF_POIS:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (magik(25)) do_pois = (10 + randint(11) + r) / (r + 1);
if (r_ptr->flags & RF_SUSCEP_POIS)
{
@@ -4497,7 +4447,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Thick Poison */
case GF_UNBREATH:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (magik(15)) do_pois = (10 + randint(11) + r) / (r + 1);
if ((r_ptr->flags & RF_NONLIVING) || (r_ptr->flags & RF_UNDEAD))
{
@@ -4511,7 +4461,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Nuclear waste */
case GF_NUKE:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->flags & RF_IM_POIS)
{
@@ -4519,14 +4469,14 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
dam *= 3;
dam /= (randint(6) + 6);
}
- else if (randint(3) == 1) do_poly = TRUE;
+ else if (randint(3) == 1) do_poly = true;
break;
}
/* Holy Orb -- hurts Evil (replaced with Hellfire) */
case GF_HELL_FIRE:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->flags & RF_EVIL)
{
dam *= 2;
@@ -4538,7 +4488,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Holy Fire -- hurts Evil, Good are immune, others _resist_ */
case GF_HOLY_FIRE:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->flags & RF_GOOD)
{
dam = 0;
@@ -4561,14 +4511,14 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Arrow -- XXX no defense */
case GF_ARROW:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
break;
}
/* Plasma -- XXX perhaps check ELEC or FIRE */
case GF_PLASMA:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->flags & RF_RES_PLAS)
{
note = " resists.";
@@ -4581,7 +4531,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Nether -- see above */
case GF_NETHER:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->flags & RF_UNDEAD)
{
note = " is immune.";
@@ -4604,9 +4554,9 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Water (acid) damage -- Water spirits/elementals are immune */
case GF_WATER:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if ((r_ptr->d_char == 'E') &&
- (prefix(r_ptr->name, "W") ||
+ (starts_with(r_ptr->name, "W") ||
(strstr(r_ptr->name, "Unmaker"))))
{
note = " is immune.";
@@ -4624,9 +4574,9 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Wave = Water + Force */
case GF_WAVE:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if ((r_ptr->d_char == 'E') &&
- (prefix(r_ptr->name, "W") ||
+ (starts_with(r_ptr->name, "W") ||
(strstr(r_ptr->name, "Unmaker"))))
{
note = " is immune.";
@@ -4717,8 +4667,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Chaos -- Chaos breathers resist */
case GF_CHAOS:
{
- if (seen) obvious = TRUE;
- do_poly = TRUE;
+ if (seen) obvious = true;
+ do_poly = true;
do_conf = (5 + randint(11) + r) / (r + 1);
if ((r_ptr->spells & SF_BR_CHAO) ||
((r_ptr->flags & RF_DEMON) && (randint(3) == 1)))
@@ -4726,7 +4676,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
note = " resists.";
dam *= 3;
dam /= (randint(6) + 6);
- do_poly = FALSE;
+ do_poly = false;
}
break;
}
@@ -4734,7 +4684,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Shards -- Shard breathers resist */
case GF_SHARDS:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (magik(33)) do_cut = (10 + randint(15) + r) / (r + 1);
if (r_ptr->spells & SF_BR_SHAR)
{
@@ -4749,7 +4699,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Rocket: Shard resistance helps */
case GF_ROCKET:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (magik(12)) do_cut = (10 + randint(15) + r) / (r + 1);
if (r_ptr->spells & SF_BR_SHAR)
@@ -4765,7 +4715,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Sound -- Sound breathers resist */
case GF_SOUND:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (who <= 0)
{
if (rand_int(100 - p_ptr->lev) < 50)
@@ -4785,7 +4735,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Confusion */
case GF_CONFUSION:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
do_conf = (10 + randint(15) + r) / (r + 1);
if (r_ptr->spells & SF_BR_CONF)
{
@@ -4804,7 +4754,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Disenchantment -- Breathers and Disenchanters resist */
case GF_DISENCHANT:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->flags & RF_RES_DISE)
{
note = " resists.";
@@ -4817,7 +4767,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Nexus -- Breathers and Existers resist */
case GF_NEXUS:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->flags & RF_RES_NEXU)
{
note = " resists.";
@@ -4830,7 +4780,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Force */
case GF_FORCE:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/*
* If fired by player, try pushing monster.
@@ -4927,7 +4877,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Inertia -- breathers resist */
case GF_INERTIA:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->spells & SF_BR_INER)
{
note = " resists.";
@@ -4939,7 +4889,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Powerful monsters can resist */
if (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10)
{
- obvious = FALSE;
+ obvious = false;
}
/* Normal monsters slow down */
else
@@ -4954,7 +4904,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Time -- breathers resist */
case GF_TIME:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->spells & SF_BR_TIME)
{
note = " resists.";
@@ -4967,21 +4917,21 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Gravity -- breathers resist */
case GF_GRAVITY:
{
- bool_ resist_tele = FALSE;
+ bool resist_tele = false;
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->flags & RF_RES_TELE)
{
if (r_ptr->flags & RF_UNIQUE)
{
note = " is unaffected!";
- resist_tele = TRUE;
+ resist_tele = true;
}
else if (m_ptr->level > randint(100))
{
note = " resists!";
- resist_tele = TRUE;
+ resist_tele = true;
}
}
@@ -5002,7 +4952,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if ((r_ptr->flags & RF_UNIQUE) ||
(m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
{
- obvious = FALSE;
+ obvious = false;
}
/* Normal monsters slow down */
else
@@ -5022,7 +4972,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
do_stun = 0;
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
}
break;
@@ -5031,7 +4981,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Pure damage */
case GF_MANA:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
break;
}
@@ -5039,7 +4989,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Pure damage */
case GF_DISINTEGRATE:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->flags & RF_HURT_ROCK)
{
note = " loses some skin!";
@@ -5072,7 +5022,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
case GF_PSI:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->flags & RF_EMPTY_MIND)
{
dam = 0;
@@ -5160,7 +5110,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
case GF_PSI_DRAIN:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->flags & RF_EMPTY_MIND)
{
dam = 0;
@@ -5196,7 +5146,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Injure + mana drain */
monster_desc(killer, m_ptr, 0x88);
msg_print("Your psychic energy is drained!");
- p_ptr->csp = MAX(0, p_ptr->csp - damroll(5, dam) / 2);
+ p_ptr->csp = std::max(0, p_ptr->csp - damroll(5, dam) / 2);
p_ptr->redraw |= PR_FRAME;
take_hit(dam, killer); /* has already been /3 */
}
@@ -5205,11 +5155,10 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
}
else if (dam > 0)
{
- int b = damroll(5, dam) / 4;
msg_format("You convert %s%s pain into psychic energy!",
m_name, (seen ? "'s" : "s"));
- b = MIN(p_ptr->msp, p_ptr->csp + b);
- p_ptr->csp = b;
+
+ p_ptr->csp = std::min<int>(p_ptr->msp, p_ptr->csp + damroll(5, dam) / 4);
p_ptr->redraw |= PR_FRAME;
}
@@ -5219,7 +5168,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
case GF_TELEKINESIS:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
do_dist = 7;
/* 1. stun */
do_stun = damroll((p_ptr->lev / 10) + 3 , (dam)) + 1;
@@ -5231,7 +5180,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Resist */
do_stun = 0;
/* No obvious effect */
- obvious = FALSE;
+ obvious = false;
}
break;
}
@@ -5239,14 +5188,14 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Meteor -- powerful magic missile */
case GF_METEOR:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
break;
}
case GF_DOMINATION:
{
if (is_friend(m_ptr) > 0) break;
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Attempt a saving throw */
if ((r_ptr->flags & RF_UNIQUE) ||
@@ -5298,7 +5247,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
{
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
}
else
@@ -5336,7 +5285,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Ice -- Cold + Cuts + Stun */
case GF_ICE:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
do_stun = (randint(15) + 1) / (r + 1);
if (magik(33)) do_cut = (10 + randint(15) + r) / (r + 1);
if (r_ptr->flags & RF_SUSCEP_COLD)
@@ -5358,7 +5307,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Drain Life */
case GF_OLD_DRAIN:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if ((r_ptr->flags & RF_UNDEAD) ||
(r_ptr->flags & RF_DEMON) ||
@@ -5366,7 +5315,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
(strchr("Egv", r_ptr->d_char)))
{
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
dam = 0;
}
@@ -5376,12 +5325,12 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Death Ray */
case GF_DEATH_RAY:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if ((r_ptr->flags & RF_UNDEAD) ||
(r_ptr->flags & RF_NONLIVING))
{
note = " is immune.";
- obvious = FALSE;
+ obvious = false;
dam = 0;
}
else if (((r_ptr->flags & RF_UNIQUE) &&
@@ -5390,7 +5339,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
randint(100) != 66 ))
{
note = " resists!";
- obvious = FALSE;
+ obvious = false;
dam = 0;
}
@@ -5402,10 +5351,10 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Polymorph monster (Use "dam" as "power") */
case GF_OLD_POLY:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Attempt to polymorph (see below) */
- do_poly = TRUE;
+ do_poly = true;
/* Powerful monsters can resist */
if ((r_ptr->flags & RF_UNIQUE) ||
@@ -5413,8 +5362,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
(m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
{
note = " is unaffected!";
- do_poly = FALSE;
- obvious = FALSE;
+ do_poly = false;
+ obvious = false;
}
/* No "real" damage */
@@ -5427,11 +5376,11 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Clone monsters (Ignore "dam") */
case GF_OLD_CLONE:
{
- bool_ is_frien = FALSE;
+ bool is_frien = false;
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if ((is_friend(m_ptr) > 0) && (randint(3) != 1))
- is_frien = TRUE;
+ is_frien = true;
/* Heal fully */
m_ptr->hp = m_ptr->maxhp;
@@ -5440,7 +5389,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (m_ptr->mspeed < 150) m_ptr->mspeed += 10;
/* Attempt to clone. */
- if (multiply_monster(c_ptr->m_idx, is_frien, TRUE))
+ if (multiply_monster(c_ptr->m_idx, is_frien, true))
{
note = " spawns!";
}
@@ -5455,7 +5404,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Heal Monster (use "dam" as amount of healing) */
case GF_OLD_HEAL:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Wake up */
m_ptr->csleep = 0;
@@ -5481,7 +5430,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Speed Monster (Ignore "dam") */
case GF_OLD_SPEED:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Speed up */
if (m_ptr->mspeed < m_ptr->speed + 15) m_ptr->mspeed += 10;
@@ -5496,14 +5445,14 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Slow Monster (Use "dam" as "power") */
case GF_OLD_SLOW:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Powerful monsters can resist */
if ((r_ptr->flags & RF_UNIQUE) ||
(m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
{
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
/* Normal monsters slow down */
@@ -5522,7 +5471,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Sleep (Use "dam" as "power") */
case GF_OLD_SLEEP:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Attempt a saving throw */
if ((r_ptr->flags & RF_NO_SLEEP) ||
@@ -5530,7 +5479,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
{
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
else
{
@@ -5548,14 +5497,14 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Sleep (Use "dam" as "power") */
case GF_STASIS:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Attempt a saving throw */
if ((r_ptr->flags & RF_UNIQUE) ||
(m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
{
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
else
{
@@ -5574,7 +5523,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
{
dam += (adj_con_fix[p_ptr->stat_ind[A_CHR]] - 1);
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Attempt a saving throw */
if ((m_ptr->mflag & MFLAG_QUEST) ||
@@ -5584,7 +5533,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Resist */
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
else if (p_ptr->aggravate)
{
@@ -5611,7 +5560,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
{
dam += (adj_con_fix[p_ptr->stat_ind[A_CHR]] - 1);
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Attempt a saving throw */
if ((m_ptr->mflag & MFLAG_QUEST) ||
@@ -5621,7 +5570,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Resist */
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
else if (p_ptr->aggravate)
{
@@ -5648,7 +5597,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Control undead */
case GF_CONTROL_UNDEAD:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Attempt a saving throw */
if ((r_ptr->flags & RF_UNIQUE) ||
@@ -5659,7 +5608,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Resist */
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
else if (p_ptr->aggravate)
{
@@ -5679,7 +5628,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Control never-moving */
case GF_CHARM_UNMOVING:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Attempt a saving throw */
if ((r_ptr->flags & RF_UNIQUE) ||
@@ -5690,7 +5639,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Resist */
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
else if (p_ptr->aggravate)
{
@@ -5710,7 +5659,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Tame animal */
case GF_CONTROL_ANIMAL:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Attempt a saving throw */
if ((r_ptr->flags & RF_UNIQUE) ||
@@ -5722,7 +5671,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Resist */
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
else if (p_ptr->aggravate)
{
@@ -5743,7 +5692,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Control demon */
case GF_CONTROL_DEMON:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Attempt a saving throw */
if ((r_ptr->flags & RF_UNIQUE) ||
@@ -5754,7 +5703,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Resist */
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
else if (p_ptr->aggravate)
{
@@ -5774,7 +5723,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Confusion (Use "dam" as "power") */
case GF_OLD_CONF:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Get confused later */
do_conf = damroll(3, (dam / 2)) + 1;
@@ -5788,7 +5737,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
/* No "real" damage */
@@ -5798,7 +5747,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
case GF_STUN:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
do_stun = damroll((p_ptr->lev / 10) + 3 , (dam)) + 1;
@@ -5810,7 +5759,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
/* No "real" damage */
@@ -5821,7 +5770,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Confusion (Use "dam" as "power") */
case GF_CONF_DAM:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Get confused later */
do_conf = damroll(3, (dam / 2)) + 1;
@@ -5835,14 +5784,14 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
break;
}
case GF_STUN_DAM:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
do_stun = damroll((p_ptr->lev / 10) + 3 , (dam)) + 1;
@@ -5854,7 +5803,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
break;
}
@@ -5862,7 +5811,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Implosion is the same than Stun_dam but only affect the living */
case GF_IMPLOSION:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
do_stun = damroll((p_ptr->lev / 10) + 3 , (dam)) + 1;
@@ -5875,7 +5824,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
/* Non_living resists */
@@ -5887,7 +5836,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
break;
}
@@ -5895,7 +5844,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Confusion & Stunning (Use "dam" as "power") */
case GF_STUN_CONF:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Get confused later */
do_conf = damroll(3, (dam / 2)) + 1;
@@ -5909,7 +5858,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
do_stun = damroll((p_ptr->lev / 10) + 3 , (dam)) + 1;
@@ -5922,7 +5871,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
}
break;
}
@@ -5935,7 +5884,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (r_ptr->flags & RF_HURT_LITE)
{
/* Obvious effect */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Special effect */
note = " cringes from the light!";
@@ -5957,7 +5906,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Lite -- opposite of Dark */
case GF_LITE:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
if (r_ptr->spells & SF_BR_LITE)
{
note = " resists.";
@@ -5977,7 +5926,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Dark -- opposite of Lite */
case GF_DARK:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Likes darkness... */
if ((r_ptr->spells & SF_BR_DARK) ||
@@ -5999,7 +5948,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (r_ptr->flags & RF_HURT_ROCK)
{
/* Notice effect */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Cute little message */
note = " loses some skin!";
@@ -6025,25 +5974,25 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Only affect undead */
if (r_ptr->flags & RF_UNDEAD)
{
- bool_ resists_tele = FALSE;
+ bool resists_tele = false;
if (r_ptr->flags & RF_RES_TELE)
{
if (r_ptr->flags & RF_UNIQUE)
{
note = " is unaffected!";
- resists_tele = TRUE;
+ resists_tele = true;
}
else if (m_ptr->level > randint(100))
{
note = " resists!";
- resists_tele = TRUE;
+ resists_tele = true;
}
}
if (!resists_tele)
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
do_dist = dam;
}
}
@@ -6052,7 +6001,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
else
{
/* Irrelevant */
- skipped = TRUE;
+ skipped = true;
}
/* No "real" damage */
@@ -6068,25 +6017,25 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Only affect evil */
if (r_ptr->flags & RF_EVIL)
{
- bool_ resists_tele = FALSE;
+ bool resists_tele = false;
if (r_ptr->flags & RF_RES_TELE)
{
if (r_ptr->flags & RF_UNIQUE)
{
note = " is unaffected!";
- resists_tele = TRUE;
+ resists_tele = true;
}
else if (m_ptr->level > randint(100))
{
note = " resists!";
- resists_tele = TRUE;
+ resists_tele = true;
}
}
if (!resists_tele)
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
do_dist = dam;
}
}
@@ -6095,7 +6044,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
else
{
/* Irrelevant */
- skipped = TRUE;
+ skipped = true;
}
/* No "real" damage */
@@ -6107,7 +6056,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Teleport monster (Use "dam" as "power") */
case GF_AWAY_ALL:
{
- bool_ resists_tele = FALSE;
+ bool resists_tele = false;
if (dungeon_flags & DF_NO_TELEPORT) break; /* No teleport on special levels */
if (r_ptr->flags & RF_RES_TELE)
@@ -6115,19 +6064,19 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (r_ptr->flags & RF_UNIQUE)
{
note = " is unaffected!";
- resists_tele = TRUE;
+ resists_tele = true;
}
else if (m_ptr->level > randint(100))
{
note = " resists!";
- resists_tele = TRUE;
+ resists_tele = true;
}
}
if (!resists_tele)
{
/* Obvious */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Prepare to teleport */
do_dist = dam;
@@ -6146,7 +6095,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (r_ptr->flags & RF_UNDEAD)
{
/* Obvious */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Apply some fear */
do_fear = damroll(3, (dam / 2)) + 1;
@@ -6156,7 +6105,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
{
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
do_fear = 0;
}
}
@@ -6165,7 +6114,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
else
{
/* Irrelevant */
- skipped = TRUE;
+ skipped = true;
}
/* No "real" damage */
@@ -6181,7 +6130,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (r_ptr->flags & RF_EVIL)
{
/* Obvious */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Apply some fear */
do_fear = damroll(3, (dam / 2)) + 1;
@@ -6191,7 +6140,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
{
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
do_fear = 0;
}
}
@@ -6200,7 +6149,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
else
{
/* Irrelevant */
- skipped = TRUE;
+ skipped = true;
}
/* No "real" damage */
@@ -6213,7 +6162,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
case GF_TURN_ALL:
{
/* Obvious */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Apply some fear */
do_fear = damroll(3, (dam / 2)) + 1;
@@ -6225,7 +6174,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
{
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
do_fear = 0;
}
@@ -6242,7 +6191,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (r_ptr->flags & RF_UNDEAD)
{
/* Obvious */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Message */
note = " shudders.";
@@ -6253,7 +6202,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
else
{
/* Irrelevant */
- skipped = TRUE;
+ skipped = true;
/* No damage */
dam = 0;
@@ -6270,7 +6219,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (r_ptr->flags & RF_EVIL)
{
/* Obvious */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Message */
note = " shudders.";
@@ -6281,7 +6230,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
else
{
/* Irrelevant */
- skipped = TRUE;
+ skipped = true;
/* No damage */
dam = 0;
@@ -6297,7 +6246,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (r_ptr->flags & RF_GOOD)
{
/* Obvious */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Message */
note = " shudders.";
@@ -6308,7 +6257,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
else
{
/* Irrelevant */
- skipped = TRUE;
+ skipped = true;
/* No damage */
dam = 0;
@@ -6325,7 +6274,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
!(r_ptr->flags & RF_NONLIVING))
{
/* Obvious */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Message */
note = " shudders.";
@@ -6336,7 +6285,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
else
{
/* Irrelevant */
- skipped = TRUE;
+ skipped = true;
/* No damage */
dam = 0;
@@ -6352,7 +6301,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (r_ptr->flags & RF_DEMON)
{
/* Obvious */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Message */
note = " shudders.";
@@ -6363,7 +6312,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
else
{
/* Irrelevant */
- skipped = TRUE;
+ skipped = true;
/* No damage */
dam = 0;
@@ -6376,7 +6325,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
case GF_DISP_ALL:
{
/* Obvious */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Message */
note = " shudders.";
@@ -6388,7 +6337,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Raise Death -- Heal monster */
case GF_RAISE:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Wake up */
m_ptr->csleep = 0;
@@ -6413,7 +6362,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Trap the soul of a demon and leave body */
case GF_TRAP_DEMONSOUL:
{
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Check race */
if ((r_ptr->flags & RF_UNIQUE) ||
@@ -6422,7 +6371,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
{
/* No obvious effect */
note = " is unaffected!";
- obvious = FALSE;
+ obvious = false;
dam = 0;
}
/* Hack : drop corpse if the demon is killed by this
@@ -6470,30 +6419,30 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
note_dies = " is sucked out of life.";
} else {
/* No effect */
- skipped = TRUE;
+ skipped = true;
}
break;
}
default:
- skipped = TRUE;
+ skipped = true;
break;
}
/* Absolutely no effect */
- if (skipped) return (FALSE);
+ if (skipped) return false;
/* "Unique" monsters cannot be polymorphed */
- if (r_ptr->flags & RF_UNIQUE) do_poly = FALSE;
+ if (r_ptr->flags & RF_UNIQUE) do_poly = false;
/*
* "Quest" monsters cannot be polymorphed
*/
if (m_ptr->mflag & MFLAG_QUEST)
- do_poly = FALSE;
+ do_poly = false;
/* "Unique" monsters can only be "killed" by the player unless they are player's friends */
if ((r_ptr->flags & RF_UNIQUE) && (m_ptr->status <= MSTATUS_NEUTRAL_P))
@@ -6541,7 +6490,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (do_poly_monster(y, x))
{
/* Obvious */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Monster polymorphs */
note = " changes!";
@@ -6568,7 +6517,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
int back = 0;
/* Obvious */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
back = 0; /* Default of no movement */
@@ -6632,7 +6581,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
else if (do_dist)
{
/* Obvious */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Message */
note = " disappears!";
@@ -6654,7 +6603,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
!(r_ptr->spells & SF_BR_WALL) && hurt_monster(m_ptr))
{
/* Obvious */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Get confused */
if (m_ptr->stunned)
@@ -6679,7 +6628,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
!(r_ptr->spells & SF_BR_CHAO) && hurt_monster(m_ptr))
{
/* Obvious */
- if (seen) obvious = TRUE;
+ if (seen) obvious = true;
/* Already partially confused */
if (m_ptr->confused)
@@ -6714,13 +6663,10 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* If another monster did the damage, hurt the monster by hand */
if (who > 0)
{
- bool_ fear = FALSE;
-
- /* Dead monster */
- if (mon_take_hit_mon(who, c_ptr->m_idx, dam, &fear, note_dies))
- {}
-
- /* Damaged monster */
+ if (mon_take_hit_mon(who, c_ptr->m_idx, dam, note_dies))
+ {
+ // No message, death message already handled
+ }
else
{
/* Give detailed messages if visible or destroyed */
@@ -6736,7 +6682,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* If the player did it, give him experience, check fear */
else if (hurt_monster(m_ptr))
{
- bool_ fear = FALSE;
+ bool fear = false;
/* Hurt the monster, check for fear and death */
if (mon_take_hit(c_ptr->m_idx, dam, &fear, note_dies))
@@ -6769,7 +6715,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* XXX XXX XXX Verify this code */
/* Update the monster */
- update_mon(c_ptr->m_idx, FALSE);
+ update_mon(c_ptr->m_idx, false);
/* Redraw the monster grid */
lite_spot(y, x);
@@ -6810,44 +6756,32 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
* if this is actually a ball or a bolt spell
*
*
- * We return "TRUE" if any "obvious" effects were observed. XXX XXX Actually,
+ * We return "true" if any "obvious" effects were observed. XXX XXX Actually,
* we just assume that the effects were obvious, for historical reasons.
*/
-static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad)
+static bool project_p(int who, int r, int y, int x, int dam, int typ, int a_rad)
{
auto const &d_info = game->edit_data.d_info;
auto const &r_info = game->edit_data.r_info;
auto const &f_info = game->edit_data.f_info;
+ auto const &dungeon_flags = game->dungeon_flags;
int k = 0, do_move = 0, a = 0, b = 0, x1 = 0, y1 = 0;
- /* Hack -- assume obvious */
- bool_ obvious = TRUE;
-
/* Player blind-ness */
- bool_ blind = (p_ptr->blind ? TRUE : FALSE);
+ bool blind = (p_ptr->blind ? true : false);
/* Player needs a "description" (he is blind) */
- bool_ fuzzy = FALSE;
-
- /* Source monster */
- monster_type *m_ptr = NULL;
-
- /* Monster name (for attacks) */
- char m_name[80];
+ bool fuzzy = false;
/* Monster name (for damage) */
- char killer[80];
-
- /* Hack -- messages */
- cptr act = NULL;
-
+ std::string killer;
/* Player is not here */
- if ((x != p_ptr->px) || (y != p_ptr->py)) return (FALSE);
+ if ((x != p_ptr->px) || (y != p_ptr->py)) return false;
/* Player cannot hurt himself */
- if (!who) return (FALSE);
+ if (!who) return false;
/* Bolt attack from a monster */
if ((!a_rad) && get_skill(SKILL_DODGE) && (who > 0))
@@ -6857,7 +6791,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
if ((chance > 0) && magik(chance))
{
msg_print("You dodge a magical attack!");
- return (TRUE);
+ return true;
}
}
@@ -6889,7 +6823,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
project(0, 0, t_y, t_x, dam, typ, (PROJECT_STOP | PROJECT_KILL));
disturb();
- return TRUE;
+ return true;
}
/* XXX XXX XXX */
@@ -6901,7 +6835,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
/* If the player is blind, be more descriptive */
- if (blind) fuzzy = TRUE;
+ if (blind) fuzzy = true;
/* Did ``God'' do it? */
if (who == -99)
@@ -6909,32 +6843,40 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
if (p_ptr->pgod)
{
/* Find out the name of player's god. */
- sprintf(killer, "%s",
- deity_info[p_ptr->pgod].name);
+ killer = deity_info[p_ptr->pgod].name;
+ }
+ else
+ {
+ killer = "Divine Wrath";
}
- else strcpy(killer, "Divine Wrath");
}
/* Did the dungeon do it? */
if (who == -100)
{
- sprintf(killer, "%s", d_info[dungeon_type].name.c_str());
+ killer = d_info[dungeon_type].name;
}
if (who == -101)
{
- sprintf(killer, "%s", f_info[cave[p_ptr->py][p_ptr->px].feat].name);
+ killer = fmt::format("{}", singular_prefix(
+ f_info[cave[p_ptr->py][p_ptr->px].feat].name));
}
if (who >= -1)
{
+ /* Monster name (for attacks) */
+ char m_name[80];
+
/* Get the source monster */
- m_ptr = &m_list[who];
+ auto m_ptr = &m_list[who];
/* Get the monster name */
monster_desc(m_name, m_ptr, 0);
/* Get the monster's real name */
- monster_desc(killer, m_ptr, 0x88);
+ char m_desc[80];
+ monster_desc(m_desc, m_ptr, 0x88);
+ killer += m_desc;
}
/* Analyze the damage */
@@ -6951,7 +6893,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
case GF_ACID:
{
if (fuzzy) msg_print("You are hit by acid!");
- acid_dam(dam, killer);
+ acid_dam(dam, killer.c_str());
break;
}
@@ -6959,7 +6901,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
case GF_FIRE:
{
if (fuzzy) msg_print("You are hit by fire!");
- fire_dam(dam, killer);
+ fire_dam(dam, killer.c_str());
break;
}
@@ -6967,7 +6909,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
case GF_COLD:
{
if (fuzzy) msg_print("You are hit by cold!");
- cold_dam(dam, killer);
+ cold_dam(dam, killer.c_str());
break;
}
@@ -6975,7 +6917,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
case GF_ELEC:
{
if (fuzzy) msg_print("You are hit by lightning!");
- elec_dam(dam, killer);
+ elec_dam(dam, killer.c_str());
break;
}
@@ -7270,7 +7212,13 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
/* Nexus -- see above */
case GF_NEXUS:
{
- if (fuzzy) msg_print("You are hit by something strange!");
+ auto m_ptr = &m_list[who];
+
+ if (fuzzy)
+ {
+ msg_print("You are hit by something strange!");
+ }
+
if (p_ptr->resist_nexus)
{
dam *= 6;
@@ -7280,6 +7228,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
{
apply_nexus(m_ptr);
}
+
take_hit(dam, killer);
break;
}
@@ -7300,6 +7249,8 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
*/
if (who > 0)
{
+ auto m_ptr = &m_list[who];
+
a = 0;
b = 0;
@@ -7493,6 +7444,8 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
case 8:
case 9:
{
+ const char *act = nullptr;
+
switch (randint(6))
{
case 1:
@@ -7642,7 +7595,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
case GF_ICE:
{
if (fuzzy) msg_print("You are hit by something sharp and cold!");
- cold_dam(dam, killer);
+ cold_dam(dam, killer.c_str());
if (!p_ptr->resist_shard)
{
set_cut(p_ptr->cut + damroll(5, 8));
@@ -7771,7 +7724,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
/* Return "Anything seen?" */
- return (obvious);
+ return true;
}
@@ -7789,7 +7742,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
* flg: Extra bit flags (see PROJECT_xxxx in "defines.h")
*
* Return:
- * TRUE if any "effects" of the projection were observed, else FALSE
+ * true if any "effects" of the projection were observed, else false
*
* Allows a monster (or player) to project a beam/bolt/ball of a given kind
* towards a given location (optionally passing over the heads of interposing
@@ -7919,7 +7872,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
* in the blast radius, in case the "illumination" of the grid was changed,
* and "update_view()" and "update_monsters()" need to be called.
*/
-bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
+bool project(int who, int rad, int y, int x, int dam, int typ, int flg)
{
int t, dist;
@@ -7933,16 +7886,16 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
auto const msec = options->delay_factor_ms();
/* Assume the player sees nothing */
- bool_ notice = FALSE;
+ bool notice = false;
/* Assume the player has seen nothing */
- bool_ visual = FALSE;
+ bool visual = false;
/* Assume the player has seen no blast grids */
- bool_ drawn = FALSE;
+ bool drawn = false;
/* Is the player blind? */
- bool_ blind = (p_ptr->blind ? TRUE : FALSE);
+ bool blind = (p_ptr->blind ? true : false);
/* Actual grids in the "path" */
std::vector<std::tuple<int, int>> path_g;
@@ -7950,8 +7903,6 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
/* Number of grids in the "blast area" (including the "beam" path) */
int grids = 0;
- int effect = 0;
-
/* Coordinates of the affected grids */
byte gx[1024], gy[1024];
@@ -8111,7 +8062,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
}
/* Hack -- Activate delay */
- visual = TRUE;
+ visual = true;
}
/* Hack -- delay anyway for consistency */
@@ -8137,7 +8088,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
dist_hack = dist;
/* Explode */
- if (TRUE)
+ if (true)
{
/* Hack -- remove final beam grid */
if (flg & (PROJECT_BEAM))
@@ -8162,10 +8113,10 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
/* Ball explosions are stopped by walls */
if (typ == GF_DISINTEGRATE)
{
- if (cave_valid_bold(y, x) &&
- (cave[y][x].feat < FEAT_PATTERN_START
- || cave[y][x].feat > FEAT_PATTERN_XTRA2))
+ if (cave_valid_bold(y, x))
+ {
cave_set_feat(y, x, FEAT_FLOOR);
+ }
/* Update some things -- similar to GF_KILL_WALL */
p_ptr->update |= (PU_VIEW | PU_FLOW | PU_MONSTERS | PU_MON_LITE);
@@ -8189,7 +8140,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
/* Speed -- ignore "non-explosions" */
- if (!grids) return (FALSE);
+ if (!grids) return false;
/* Display the "blast area" if requested */
@@ -8213,7 +8164,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
byte a;
char c;
- drawn = TRUE;
+ drawn = true;
/* Obtain the explosion pict */
p = bolt_pict(y, x, y, x, typ);
@@ -8272,10 +8223,13 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
/* Start with "dist" of zero */
dist = 0;
+ /* Which effect? */
+ boost::optional<s16b> maybe_effect = boost::none;
+
/* Effect ? */
if (flg & PROJECT_STAY)
{
- effect = new_effect(typ, dam, project_time, p_ptr->py, p_ptr->px, rad, project_time_effect);
+ maybe_effect = new_effect(typ, dam, project_time, p_ptr->py, p_ptr->px, rad, project_time_effect);
project_time = 0;
project_time_effect = 0;
}
@@ -8291,12 +8245,12 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
x = gx[i];
/* Affect the feature in that grid */
- if (project_f(who, dist, y, x, dam, typ)) notice = TRUE;
+ if (project_f(who, dist, y, x, dam, typ)) notice = true;
/* Effect ? */
if (flg & PROJECT_STAY)
{
- cave[y][x].effect = effect;
+ cave[y][x].maybe_effect = maybe_effect;
lite_spot(y, x);
}
}
@@ -8324,7 +8278,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
x = gx[i];
/* Affect the object in the grid */
- if (project_o(who, dist, y, x, dam, typ)) notice = TRUE;
+ if (project_o(who, dist, y, x, dam, typ)) notice = true;
}
}
@@ -8353,7 +8307,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
if (grids > 1)
{
/* Affect the monster in the grid */
- if (project_m(who, dist, y, x, dam, typ)) notice = TRUE;
+ if (project_m(who, dist, y, x, dam, typ)) notice = true;
}
else
{
@@ -8391,7 +8345,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
}
else
{
- if (project_m(who, dist, y, x, dam, typ)) notice = TRUE;
+ if (project_m(who, dist, y, x, dam, typ)) notice = true;
}
}
}
@@ -8435,7 +8389,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
x = gx[i];
/* Affect the player */
- if (project_p(who, dist, y, x, dam, typ, rad)) notice = TRUE;
+ if (project_p(who, dist, y, x, dam, typ, rad)) notice = true;
}
}
@@ -8463,13 +8417,13 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
* the potion was in her inventory);
* o_ptr --- pointer to the potion object.
*/
-bool_ potion_smash_effect(int who, int y, int x, int o_sval)
+bool potion_smash_effect(int who, int y, int x, int o_sval)
{
int radius = 2;
int dt = 0;
int dam = 0;
- bool_ ident = FALSE;
- bool_ angry = FALSE;
+ bool ident = false;
+ bool angry = false;
switch (o_sval)
{
@@ -8484,7 +8438,7 @@ bool_ potion_smash_effect(int who, int y, int x, int o_sval)
case SV_POTION_DEC_CHR:
case SV_POTION_WATER: /* perhaps a 'water' attack? */
case SV_POTION_APPLE_JUICE:
- return TRUE;
+ return true;
case SV_POTION_INFRAVISION:
case SV_POTION_DETECT_INVIS:
@@ -8516,85 +8470,85 @@ bool_ potion_smash_effect(int who, int y, int x, int o_sval)
case SV_POTION_INVULNERABILITY:
case SV_POTION_NEW_LIFE:
/* All of the above potions have no effect when shattered */
- return FALSE;
+ return false;
case SV_POTION_SLOWNESS:
dt = GF_OLD_SLOW;
dam = 5;
- ident = TRUE;
- angry = TRUE;
+ ident = true;
+ angry = true;
break;
case SV_POTION_POISON:
dt = GF_POIS;
dam = 3;
- ident = TRUE;
- angry = TRUE;
+ ident = true;
+ angry = true;
break;
case SV_POTION_BLINDNESS:
dt = GF_DARK;
- ident = TRUE;
- angry = TRUE;
+ ident = true;
+ angry = true;
break;
case SV_POTION_CONFUSION: /* Booze */
dt = GF_OLD_CONF;
- ident = TRUE;
- angry = TRUE;
+ ident = true;
+ angry = true;
break;
case SV_POTION_SLEEP:
dt = GF_OLD_SLEEP;
- angry = TRUE;
- ident = TRUE;
+ angry = true;
+ ident = true;
break;
case SV_POTION_RUINATION:
case SV_POTION_DETONATIONS:
dt = GF_SHARDS;
dam = damroll(25, 25);
- angry = TRUE;
- ident = TRUE;
+ angry = true;
+ ident = true;
break;
case SV_POTION_DEATH:
dt = GF_MANA; /* !! */
dam = damroll(10, 10);
- angry = TRUE;
+ angry = true;
radius = 1;
- ident = TRUE;
+ ident = true;
break;
case SV_POTION_SPEED:
dt = GF_OLD_SPEED;
- ident = TRUE;
+ ident = true;
break;
case SV_POTION_CURE_LIGHT:
dt = GF_OLD_HEAL;
dam = damroll(2, 3);
- ident = TRUE;
+ ident = true;
break;
case SV_POTION_CURE_SERIOUS:
dt = GF_OLD_HEAL;
dam = damroll(4, 3);
- ident = TRUE;
+ ident = true;
break;
case SV_POTION_CURE_CRITICAL:
case SV_POTION_CURING:
dt = GF_OLD_HEAL;
dam = damroll(6, 3);
- ident = TRUE;
+ ident = true;
break;
case SV_POTION_HEALING:
dt = GF_OLD_HEAL;
dam = damroll(10, 10);
- ident = TRUE;
+ ident = true;
break;
case SV_POTION_STAR_HEALING:
case SV_POTION_LIFE:
dt = GF_OLD_HEAL;
dam = damroll(50, 50);
radius = 1;
- ident = TRUE;
+ ident = true;
break;
case SV_POTION_RESTORE_MANA: /* MANA */
dt = GF_MANA;
dam = damroll(10, 10);
radius = 1;
- ident = TRUE;
+ ident = true;
break;
default:
/* Do nothing */
@@ -8775,7 +8729,7 @@ static void describe_attack_fully(int type, char* r)
std::string name_spell(random_spell const *s_ptr)
{
char buff[30];
- cptr buff2 = "???";
+ const char *buff2 = "???";
if (s_ptr->proj_flags & PROJECT_STOP && s_ptr->radius == 0)
{
@@ -8814,7 +8768,6 @@ void generate_spell(int plev)
bool destruc_gen = false;
bool simple_gen = true;
- bool ball_desc = false;
// Calculate power, dice, etc.
int const power = rand_int(5);
@@ -8856,7 +8809,6 @@ void generate_spell(int plev)
rspell.radius = dice / 3;
rspell.dam_dice = dice;
rspell.dam_sides = sides;
- ball_desc = true;
}
else if (chance < 83)
{
@@ -8950,7 +8902,7 @@ s16b do_poly_monster(int y, int x)
* Handle polymorph --
* Create a new monster (no groups)
*/
- if (place_monster_aux(y, x, new_r_idx, FALSE, FALSE, m_ptr->status))
+ if (place_monster_aux(y, x, new_r_idx, false, false, m_ptr->status))
{
/* Get a "new" monster */
new_m_idx = c_ptr->m_idx;
diff --git a/src/spells1.hpp b/src/spells1.hpp
index ec8f2cc9..3a196fd6 100644
--- a/src/spells1.hpp
+++ b/src/spells1.hpp
@@ -2,13 +2,13 @@
#include <string>
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "random_spell_fwd.hpp"
byte spell_color(int type);
s16b poly_r_idx(int r_idx);
void get_pos_player(int dis, int *ny, int *nx);
-extern bool_ teleport_player_bypass;
+extern bool teleport_player_bypass;
void teleport_player_directed(int rad, int dir);
void teleport_away(int m_idx, int dis);
void teleport_player(int dis);
@@ -16,18 +16,19 @@ void teleport_player_to(int ny, int nx);
void teleport_monster_to(int m_idx, int ny, int nx);
void teleport_player_level();
void recall_player(int d, int f);
-void take_hit(int damage, cptr kb_str);
-void take_sanity_hit(int damage, cptr hit_from);
-void acid_dam(int dam, cptr kb_str);
-void elec_dam(int dam, cptr kb_str);
-void fire_dam(int dam, cptr kb_str);
-void cold_dam(int dam, cptr kb_str);
-bool_ dec_stat(int stat, int amount, int mode);
-bool_ res_stat(int stat, bool_ full);
-bool_ apply_disenchant(int mode);
-bool_ project_m(int who, int r, int y, int x, int dam, int typ);
-bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg);
-bool_ potion_smash_effect(int who, int y, int x, int o_sval);
+void take_hit(int damage, const char *kb_str);
+void take_hit(int damage, std::string const &kb_str);
+void take_sanity_hit(int damage, const char *hit_from);
+void acid_dam(int dam, const char *kb_str);
+void elec_dam(int dam, const char *kb_str);
+void fire_dam(int dam, const char *kb_str);
+void cold_dam(int dam, const char *kb_str);
+bool dec_stat(int stat, int amount, int mode);
+bool res_stat(int stat, bool full);
+bool apply_disenchant(int mode);
+bool project_m(int who, int r, int y, int x, int dam, int typ);
+bool project(int who, int rad, int y, int x, int dam, int typ, int flg);
+bool potion_smash_effect(int who, int y, int x, int o_sval);
void do_poly_self();
void corrupt_player();
std::string name_spell(random_spell const *);
diff --git a/src/spells2.cc b/src/spells2.cc
index c0d435ea..cadaed2d 100644
--- a/src/spells2.cc
+++ b/src/spells2.cc
@@ -42,11 +42,10 @@
#include "stats.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "xtra1.hpp"
#include "xtra2.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
#include <boost/algorithm/string/predicate.hpp>
@@ -143,9 +142,9 @@ void grow_grass(int rad)
/*
* Increase players hit points, notice effects
*/
-bool_ hp_player(int num)
+void hp_player(int num)
{
- bool_ dead = p_ptr->chp < 0;
+ bool dead = p_ptr->chp < 0;
/* Healing needed */
if (p_ptr->chp < p_ptr->mhp)
@@ -191,13 +190,7 @@ bool_ hp_player(int num)
{
msg_print("You feel very good.");
}
-
- /* Notice */
- return (TRUE);
}
-
- /* Ignore */
- return (FALSE);
}
@@ -236,7 +229,7 @@ void explosive_rune()
/*
* Array of stat "descriptions"
*/
-static cptr desc_stat_pos[] =
+static const char *desc_stat_pos[] =
{
"strong",
"smart",
@@ -250,7 +243,7 @@ static cptr desc_stat_pos[] =
* Array of long descriptions of stat
*/
-static cptr long_desc_stat[] =
+static const char *long_desc_stat[] =
{
"strength",
"intelligence",
@@ -263,7 +256,7 @@ static cptr long_desc_stat[] =
/*
* Array of stat "descriptions"
*/
-static cptr desc_stat_neg[] =
+static const char *desc_stat_neg[] =
{
"weak",
"stupid",
@@ -277,30 +270,30 @@ static cptr desc_stat_neg[] =
/*
* Lose a "point"
*/
-bool_ do_dec_stat(int stat, int mode)
+void do_dec_stat(int stat, int mode)
{
- bool_ sust = FALSE;
+ bool sust = false;
/* Access the "sustain" */
switch (stat)
{
case A_STR:
- if (p_ptr->sustain_str) sust = TRUE;
+ if (p_ptr->sustain_str) sust = true;
break;
case A_INT:
- if (p_ptr->sustain_int) sust = TRUE;
+ if (p_ptr->sustain_int) sust = true;
break;
case A_WIS:
- if (p_ptr->sustain_wis) sust = TRUE;
+ if (p_ptr->sustain_wis) sust = true;
break;
case A_DEX:
- if (p_ptr->sustain_dex) sust = TRUE;
+ if (p_ptr->sustain_dex) sust = true;
break;
case A_CON:
- if (p_ptr->sustain_con) sust = TRUE;
+ if (p_ptr->sustain_con) sust = true;
break;
case A_CHR:
- if (p_ptr->sustain_chr) sust = TRUE;
+ if (p_ptr->sustain_chr) sust = true;
break;
}
@@ -310,9 +303,7 @@ bool_ do_dec_stat(int stat, int mode)
/* Message */
msg_format("You feel %s for a moment, but the feeling passes.",
desc_stat_neg[stat]);
-
- /* Notice effect */
- return (TRUE);
+ return;
}
/* Attempt to reduce the stat */
@@ -320,20 +311,15 @@ bool_ do_dec_stat(int stat, int mode)
{
/* Message */
msg_format("You feel very %s.", desc_stat_neg[stat]);
-
- /* Notice effect */
- return (TRUE);
+ return;
}
-
- /* Nothing obvious */
- return (FALSE);
}
/*
* Restore lost "points" in a stat
*/
-bool_ do_res_stat(int stat, bool_ full)
+bool do_res_stat(int stat, bool full)
{
/* Keep a copy of the current stat, so we can evaluate it if necessary */
int cur_stat = p_ptr->stat_cur[stat];
@@ -352,11 +338,11 @@ bool_ do_res_stat(int stat, bool_ full)
}
/* Notice */
- return (TRUE);
+ return true;
}
/* Nothing obvious */
- return (FALSE);
+ return false;
}
@@ -366,7 +352,7 @@ bool_ do_res_stat(int stat, bool_ full)
* Note that this function (used by stat potions) now restores
* the stat BEFORE increasing it.
*/
-static bool_ inc_stat(int stat)
+static bool inc_stat(int stat)
{
int value, gain;
@@ -418,23 +404,23 @@ static bool_ inc_stat(int stat)
p_ptr->update |= (PU_BONUS);
/* Success */
- return (TRUE);
+ return true;
}
/* Nothing to gain */
- return (FALSE);
+ return false;
}
/*
* Gain a "point" in a stat
*/
-bool_ do_inc_stat(int stat)
+bool do_inc_stat(int stat)
{
- bool_ res;
+ bool res;
/* Restore strength */
- res = res_stat(stat, TRUE);
+ res = res_stat(stat, true);
/* Attempt to increase */
if (inc_stat(stat))
@@ -443,7 +429,7 @@ bool_ do_inc_stat(int stat)
msg_format("Wow! You feel very %s!", desc_stat_pos[stat]);
/* Notice */
- return (TRUE);
+ return true;
}
/* Restoration worked */
@@ -453,21 +439,21 @@ bool_ do_inc_stat(int stat)
msg_format("You feel less %s.", desc_stat_neg[stat]);
/* Notice */
- return (TRUE);
+ return true;
}
/* Nothing obvious */
- return (FALSE);
+ return false;
}
/*
* Process all identify hooks
*/
-void identify_hooks(int i, object_type *o_ptr, identify_mode mode)
+void identify_hooks(object_type *o_ptr)
{
/* Process the appropriate hooks */
- hook_identify_in in = { o_ptr, mode };
+ hook_identify_in in = { o_ptr };
process_hooks_new(HOOK_IDENTIFY, &in, NULL);
}
@@ -476,42 +462,27 @@ void identify_hooks(int i, object_type *o_ptr, identify_mode mode)
* Identify everything being carried.
* Done by a potion of "self knowledge".
*/
-bool_ identify_pack()
+bool identify_pack()
{
- int i;
-
/* Simply identify and know every item */
- for (i = 0; i < INVEN_TOTAL; i++)
+ for (int i = 0; i < INVEN_TOTAL; i++)
{
object_type *o_ptr = &p_ptr->inventory[i];
/* Skip non-objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Aware and Known */
object_aware(o_ptr);
object_known(o_ptr);
-
- /* Process the appropriate hooks */
- identify_hooks(i, o_ptr, IDENT_NORMAL);
}
p_ptr->notice |= (PN_COMBINE | PN_REORDER);
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
- return TRUE;
-}
-
-/*
- * common portions of identify_fully and identify_pack_fully
- */
-static void make_item_fully_identified(object_type *o_ptr)
-{
- /* Identify it fully */
- object_aware(o_ptr);
- object_known(o_ptr);
-
- /* Mark the item as fully known */
- o_ptr->ident |= (IDENT_MENTAL);
+ return true;
}
/*
@@ -528,12 +499,13 @@ void identify_pack_fully()
object_type *o_ptr = &p_ptr->inventory[i];
/* Skip non-objects */
- if (!o_ptr->k_idx) continue;
-
- make_item_fully_identified(o_ptr);
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
- /* Process the appropriate hooks */
- identify_hooks(i, o_ptr, IDENT_FULL);
+ object_aware(o_ptr);
+ object_known(o_ptr);
}
p_ptr->update |= (PU_BONUS);
@@ -553,36 +525,27 @@ static int enchant_table[16] =
1000
};
-static bool_ remove_curse_object(object_type *o_ptr, bool_ all)
+static bool remove_curse_object(object_type *o_ptr, bool all)
{
/* Skip non-objects */
- if (!o_ptr->k_idx) return FALSE;
+ if (!o_ptr->k_ptr) return false;
/* Uncursed already */
- if (!cursed_p(o_ptr)) return FALSE;
+ if (!cursed_p(o_ptr)) return false;
/* Extract the flags */
auto const flags = object_flags(o_ptr);
/* Heavily Cursed Items need a special spell */
- if (!all && (flags & TR_HEAVY_CURSE)) return FALSE;
+ if (!all && (flags & TR_HEAVY_CURSE)) return false;
/* Perma-Cursed Items can NEVER be uncursed */
- if (flags & TR_PERMA_CURSE) return FALSE;
-
- /* Uncurse it */
- o_ptr->ident &= ~(IDENT_CURSED);
-
- /* Hack -- Assume felt */
- o_ptr->ident |= (IDENT_SENSE);
+ if (flags & TR_PERMA_CURSE) return false;
/* Strip curse flags */
o_ptr->art_flags &= ~TR_CURSED;
o_ptr->art_flags &= ~TR_HEAVY_CURSE;
- /* Take note */
- o_ptr->sense = SENSE_UNCURSED;
-
/* Reverse the curse effect */
/* jk - scrolls of *remove curse* have a 1 in (55-level chance to */
/* reverse the curse effects - a ring of damage(-15) {cursed} then */
@@ -605,7 +568,7 @@ static bool_ remove_curse_object(object_type *o_ptr, bool_ all)
/* Window stuff */
p_ptr->window |= (PW_EQUIP);
- return TRUE;
+ return true;
}
/*
@@ -614,7 +577,7 @@ static bool_ remove_curse_object(object_type *o_ptr, bool_ all)
* Note that Items which are "Perma-Cursed" (The One Ring,
* The Crown of Morgoth) can NEVER be uncursed.
*
- * Note that if "all" is FALSE, then Items which are
+ * Note that if "all" is false, then Items which are
* "Heavy-Cursed" (Mormegil, Calris, and Weapons of Morgul)
* will not be uncursed.
*/
@@ -641,17 +604,17 @@ static int remove_curse_aux(int all)
/*
* Remove most curses
*/
-bool_ remove_curse()
+bool remove_curse()
{
- return (remove_curse_aux(FALSE) ? TRUE : FALSE);
+ return (remove_curse_aux(false) ? true : false);
}
/*
* Remove all curses
*/
-bool_ remove_all_curse()
+bool remove_all_curse()
{
- return (remove_curse_aux(TRUE) ? TRUE : FALSE);
+ return (remove_curse_aux(true) ? true : false);
}
@@ -659,7 +622,7 @@ bool_ remove_all_curse()
/*
* Restores any drained experience
*/
-bool_ restore_level()
+bool restore_level()
{
/* Restore experience */
if (p_ptr->exp < p_ptr->max_exp)
@@ -674,25 +637,25 @@ bool_ restore_level()
check_experience();
/* Did something */
- return (TRUE);
+ return true;
}
/* No effect */
- return (FALSE);
+ return false;
}
-bool_ alchemy() /* Turns an object into gold, gain some of its value in a shop */
+void alchemy()
{
int item, amt = 1;
int old_number;
long price;
- bool_ force = FALSE;
+ bool force = false;
char o_name[80];
char out_val[160];
/* Hack -- force destruction */
- if (command_arg > 0) force = TRUE;
+ if (command_arg > 0) force = true;
/* Get an item */
if (!get_item(&item,
@@ -701,7 +664,7 @@ bool_ alchemy() /* Turns an object into gold, gain some of its value in a shop *
(USE_INVEN | USE_FLOOR),
object_filter::True()))
{
- return (FALSE);
+ return;
}
/* Get the item */
@@ -714,14 +677,17 @@ bool_ alchemy() /* Turns an object into gold, gain some of its value in a shop *
amt = get_quantity(NULL, o_ptr->number);
/* Allow user abort */
- if (amt <= 0) return FALSE;
+ if (amt <= 0)
+ {
+ return;
+ }
}
/* Describe the object */
old_number = o_ptr->number;
o_ptr->number = amt;
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
o_ptr->number = old_number;
/* Verify unless quantity given */
@@ -729,34 +695,20 @@ bool_ alchemy() /* Turns an object into gold, gain some of its value in a shop *
{
/* Make a verification */
sprintf(out_val, "Really turn %s to gold? ", o_name);
- if (!get_check(out_val)) return FALSE;
+ if (!get_check(out_val))
+ {
+ return;
+ }
}
/* Artifacts cannot be destroyed */
if (artifact_p(o_ptr))
{
- byte feel = SENSE_SPECIAL;
-
/* Message */
msg_format("You fail to turn %s to gold!", o_name);
- /* Hack -- Handle icky artifacts */
- if (cursed_p(o_ptr)) feel = SENSE_TERRIBLE;
-
- /* Hack -- inscribe the artifact */
- o_ptr->sense = feel;
-
- /* We have "felt" it (again) */
- o_ptr->ident |= (IDENT_SENSE);
-
- /* Combine the pack */
- p_ptr->notice |= (PN_COMBINE);
-
- /* Window stuff */
- p_ptr->window |= (PW_INVEN | PW_EQUIP);
-
/* Done */
- return FALSE;
+ return;
}
price = object_value_real(o_ptr);
@@ -783,8 +735,6 @@ bool_ alchemy() /* Turns an object into gold, gain some of its value in a shop *
/* Eliminate the item */
inc_stack_size(item, -amt);
-
- return TRUE;
}
@@ -821,7 +771,7 @@ static int report_magics_aux(int dur)
}
}
-static cptr report_magic_durations[] =
+static const char *report_magic_durations[] =
{
"for a short time",
"for a little while",
@@ -840,7 +790,7 @@ void report_magics()
char Dummy[80];
- cptr info[128];
+ const char *info[128];
int info2[128];
if (p_ptr->blind)
@@ -941,8 +891,7 @@ void report_magics()
}
/* Save the screen */
- character_icky = TRUE;
- Term_save();
+ screen_save_no_flush();
/* Erase the screen */
for (k = 1; k < 24; k++) prt("", k, 13);
@@ -972,8 +921,7 @@ void report_magics()
inkey();
/* Restore the screen */
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
}
@@ -981,34 +929,8 @@ void report_magics()
/*
* Forget everything
*/
-bool_ lose_all_info()
+bool lose_all_info()
{
- int i;
-
- /* Forget info about objects */
- for (i = 0; i < INVEN_TOTAL; i++)
- {
- object_type *o_ptr = &p_ptr->inventory[i];
-
- /* Skip non-objects */
- if (!o_ptr->k_idx) continue;
-
- /* Allow "protection" by the MENTAL flag */
- if (o_ptr->ident & (IDENT_MENTAL)) continue;
-
- /* Remove sensing */
- o_ptr->sense = SENSE_NONE;
-
- /* Hack -- Clear the "empty" flag */
- o_ptr->ident &= ~(IDENT_EMPTY);
-
- /* Hack -- Clear the "known" flag */
- o_ptr->ident &= ~(IDENT_KNOWN);
-
- /* Hack -- Clear the "felt" flag */
- o_ptr->ident &= ~(IDENT_SENSE);
- }
-
/* Recalculate bonuses */
p_ptr->update |= (PU_BONUS);
@@ -1022,18 +944,18 @@ bool_ lose_all_info()
wiz_dark();
/* It worked */
- return (TRUE);
+ return true;
}
/*
* Detect all doors on current panel
*/
-bool_ detect_doors(int rad)
+bool detect_doors(int rad)
{
int y, x;
- bool_ detect = FALSE;
+ bool detect = false;
cave_type *c_ptr;
@@ -1075,7 +997,7 @@ bool_ detect_doors(int rad)
lite_spot(y, x);
/* Obvious */
- detect = TRUE;
+ detect = true;
}
}
}
@@ -1094,11 +1016,11 @@ bool_ detect_doors(int rad)
/*
* Detect all stairs on current panel
*/
-bool_ detect_stairs(int rad)
+bool detect_stairs(int rad)
{
int y, x;
- bool_ detect = FALSE;
+ bool detect = false;
cave_type *c_ptr;
@@ -1129,7 +1051,7 @@ bool_ detect_stairs(int rad)
lite_spot(y, x);
/* Obvious */
- detect = TRUE;
+ detect = true;
}
}
}
@@ -1148,11 +1070,11 @@ bool_ detect_stairs(int rad)
/*
* Detect any treasure on the current panel
*/
-bool_ detect_treasure(int rad)
+bool detect_treasure(int rad)
{
int y, x;
- bool_ detect = FALSE;
+ bool detect = false;
cave_type *c_ptr;
@@ -1193,7 +1115,7 @@ bool_ detect_treasure(int rad)
lite_spot(y, x);
/* Detect */
- detect = TRUE;
+ detect = true;
}
}
}
@@ -1244,19 +1166,19 @@ template<typename P> static bool detect_monsters_fn(int radius, P p) {
if (p(r_ptr.get()))
{
/* Repair visibility later */
- repair_monsters = TRUE;
+ repair_monsters = true;
/* Hack -- Detect monster */
m_ptr->mflag |= (MFLAG_MARK | MFLAG_SHOW);
/* Hack -- See monster */
- m_ptr->ml = TRUE;
+ m_ptr->ml = true;
/* Redraw */
if (panel_contains(y, x)) lite_spot(y, x);
/* Detect */
- flag = TRUE;
+ flag = true;
}
}
/* Result */
@@ -1266,7 +1188,7 @@ template<typename P> static bool detect_monsters_fn(int radius, P p) {
/*
* Detect all (string) monsters on current panel
*/
-static bool_ detect_monsters_string(cptr chars, int rad)
+static bool detect_monsters_string(const char *chars, int rad)
{
auto predicate = [chars](monster_race *r_ptr) -> bool {
return strchr(chars, r_ptr->d_char);
@@ -1277,11 +1199,11 @@ static bool_ detect_monsters_string(cptr chars, int rad)
{
/* Describe result */
msg_print("You sense the presence of monsters!");
- return TRUE;
+ return true;
}
else
{
- return FALSE;
+ return false;
}
}
@@ -1299,7 +1221,7 @@ template <typename P> bool detect_objects_fn(int radius, const char *object_mess
object_type *o_ptr = &o_list[i];
/* Skip dead objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr) continue;
/* Location */
int y, x;
@@ -1339,13 +1261,13 @@ template <typename P> bool detect_objects_fn(int radius, const char *object_mess
if (p(o_ptr))
{
/* Hack -- memorize it */
- o_ptr->marked = TRUE;
+ o_ptr->marked = true;
/* Redraw */
if (panel_contains(y, x)) lite_spot(y, x);
/* Detect */
- detect = TRUE;
+ detect = true;
}
}
@@ -1404,7 +1326,7 @@ bool detect_objects_normal(int rad)
/*
* Detect all "normal" monsters on the current panel
*/
-bool_ detect_monsters_normal(int rad)
+bool detect_monsters_normal(int rad)
{
auto predicate = [](monster_race *r_ptr) -> bool {
return (!(r_ptr->flags & RF_INVISIBLE)) ||
@@ -1415,11 +1337,11 @@ bool_ detect_monsters_normal(int rad)
{
/* Describe result */
msg_print("You sense the presence of monsters!");
- return TRUE;
+ return true;
}
else
{
- return FALSE;
+ return false;
}
}
@@ -1427,7 +1349,7 @@ bool_ detect_monsters_normal(int rad)
/*
* Detect all "invisible" monsters on current panel
*/
-bool_ detect_monsters_invis(int rad)
+bool detect_monsters_invis(int rad)
{
auto predicate = [](monster_race *r_ptr) -> bool {
return bool(r_ptr->flags & RF_INVISIBLE);
@@ -1437,11 +1359,11 @@ bool_ detect_monsters_invis(int rad)
{
/* Describe result */
msg_print("You sense the presence of invisible creatures!");
- return TRUE;
+ return true;
}
else
{
- return FALSE;
+ return false;
}
}
@@ -1467,18 +1389,18 @@ void detect_monsters_orcs(int rad)
/*
* Detect everything
*/
-bool_ detect_all(int rad)
+bool detect_all(int rad)
{
- bool_ detect = FALSE;
+ bool detect = false;
/* Detect everything */
- if (detect_doors(rad)) detect = TRUE;
- if (detect_stairs(rad)) detect = TRUE;
- if (detect_treasure(rad)) detect = TRUE;
- if (detect_objects_gold(rad)) detect = TRUE;
- if (detect_objects_normal(rad)) detect = TRUE;
- if (detect_monsters_invis(rad)) detect = TRUE;
- if (detect_monsters_normal(rad)) detect = TRUE;
+ if (detect_doors(rad)) detect = true;
+ if (detect_stairs(rad)) detect = true;
+ if (detect_treasure(rad)) detect = true;
+ if (detect_objects_gold(rad)) detect = true;
+ if (detect_objects_normal(rad)) detect = true;
+ if (detect_monsters_invis(rad)) detect = true;
+ if (detect_monsters_normal(rad)) detect = true;
/* Result */
return (detect);
@@ -1491,6 +1413,8 @@ bool_ detect_all(int rad)
*/
void stair_creation()
{
+ auto const &dungeon_flags = game->dungeon_flags;
+
/* XXX XXX XXX */
if (!cave_valid_bold(p_ptr->py, p_ptr->px))
{
@@ -1629,10 +1553,10 @@ object_filter_t const &item_tester_hook_artifactable()
* Note that this function can now be used on "piles" of items, and
* the larger the pile, the lower the chance of success.
*/
-bool_ enchant(object_type *o_ptr, int n, int eflag)
+bool enchant(object_type *o_ptr, int n, int eflag)
{
int i, chance, prob;
- bool_ res = FALSE;
+ bool res = false;
auto const a = artifact_p(o_ptr);
/* Extract the flags */
@@ -1644,15 +1568,7 @@ bool_ enchant(object_type *o_ptr, int n, int eflag)
if (cursed_p(o_ptr) && (!(flags & TR_PERMA_CURSE)))
{
msg_print("The curse is broken!");
- o_ptr->ident &= ~(IDENT_CURSED);
- o_ptr->ident |= (IDENT_SENSE);
-
- if (o_ptr->art_flags & TR_CURSED)
- o_ptr->art_flags &= ~TR_CURSED;
- if (o_ptr->art_flags & TR_HEAVY_CURSE)
- o_ptr->art_flags &= ~TR_HEAVY_CURSE;
-
- o_ptr->sense = SENSE_UNCURSED;
+ o_ptr->art_flags &= ~(TR_CURSED | TR_HEAVY_CURSE);
}
};
@@ -1683,7 +1599,7 @@ bool_ enchant(object_type *o_ptr, int n, int eflag)
if ((randint(1000) > chance) && (!a || (rand_int(100) < 50)))
{
o_ptr->to_h++;
- res = TRUE;
+ res = true;
/* break curse? */
if ((o_ptr->to_h >= 0) && (rand_int(100) < 25))
@@ -1703,7 +1619,7 @@ bool_ enchant(object_type *o_ptr, int n, int eflag)
if ((randint(1000) > chance) && (!a || (rand_int(100) < 50)))
{
o_ptr->to_d++;
- res = TRUE;
+ res = true;
/* break curse? */
if ((o_ptr->to_d >= 0) && (rand_int(100) < 25))
@@ -1724,7 +1640,7 @@ bool_ enchant(object_type *o_ptr, int n, int eflag)
if ((randint(1000) > chance) && (!a || (rand_int(100) < 50)))
{
o_ptr->pval++;
- res = TRUE;
+ res = true;
/* break curse? */
if ((o_ptr->pval >= 0) && (rand_int(100) < 25))
@@ -1744,7 +1660,7 @@ bool_ enchant(object_type *o_ptr, int n, int eflag)
if ((randint(1000) > chance) && (!a || (rand_int(100) < 50)))
{
o_ptr->to_a++;
- res = TRUE;
+ res = true;
/* break curse? */
if ((o_ptr->to_a >= 0) && (rand_int(100) < 25))
@@ -1756,7 +1672,7 @@ bool_ enchant(object_type *o_ptr, int n, int eflag)
}
/* Failure */
- if (!res) return (FALSE);
+ if (!res) return false;
/* Recalculate bonuses */
p_ptr->update |= (PU_BONUS);
@@ -1768,7 +1684,7 @@ bool_ enchant(object_type *o_ptr, int n, int eflag)
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
/* Success */
- return (TRUE);
+ return true;
}
@@ -1776,14 +1692,15 @@ bool_ enchant(object_type *o_ptr, int n, int eflag)
/*
* Enchant an item (in the inventory or on the floor)
* Note that "num_ac" requires armour, else weapon
- * Returns TRUE if attempted, FALSE if cancelled
+ * Returns true if attempted, false if cancelled
*/
-bool_ enchant_spell(int num_hit, int num_dam, int num_ac, int num_pval)
+bool enchant_spell(int num_hit, int num_dam, int num_ac, int num_pval)
{
int item;
- bool_ okay = FALSE;
+ bool okay = false;
char o_name[80];
- cptr q, s;
+ const char *q;
+ const char *s;
/* Assume enchant weapon */
@@ -1798,13 +1715,13 @@ bool_ enchant_spell(int num_hit, int num_dam, int num_ac, int num_pval)
/* Get an item */
q = "Enchant which item? ";
s = "You have nothing to enchant.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR), object_filter)) return (FALSE);
+ if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR), object_filter)) return false;
/* Get the item */
object_type *o_ptr = get_object(item);
/* Description */
- object_desc(o_name, o_ptr, FALSE, 0);
+ object_desc(o_name, o_ptr, false, 0);
/* Describe */
msg_format("%s %s glow%s brightly!",
@@ -1812,10 +1729,10 @@ bool_ enchant_spell(int num_hit, int num_dam, int num_ac, int num_pval)
((o_ptr->number > 1) ? "" : "s"));
/* Enchant */
- if (enchant(o_ptr, num_hit, ENCH_TOHIT)) okay = TRUE;
- if (enchant(o_ptr, num_dam, ENCH_TODAM)) okay = TRUE;
- if (enchant(o_ptr, num_ac, ENCH_TOAC)) okay = TRUE;
- if (enchant(o_ptr, num_pval, ENCH_PVAL)) okay = TRUE;
+ if (enchant(o_ptr, num_hit, ENCH_TOHIT)) okay = true;
+ if (enchant(o_ptr, num_dam, ENCH_TODAM)) okay = true;
+ if (enchant(o_ptr, num_ac, ENCH_TOAC)) okay = true;
+ if (enchant(o_ptr, num_pval, ENCH_PVAL)) okay = true;
/* Failure */
if (!okay)
@@ -1828,7 +1745,7 @@ bool_ enchant_spell(int num_hit, int num_dam, int num_ac, int num_pval)
}
/* Something happened */
- return (TRUE);
+ return true;
}
void curse_artifact(object_type * o_ptr)
@@ -1844,7 +1761,6 @@ void curse_artifact(object_type * o_ptr)
if (randint(3) == 1) o_ptr-> art_flags |= TR_BLACK_BREATH;
if (randint(2) == 1) o_ptr-> art_flags |= TR_TELEPORT;
else if (randint(3) == 1) o_ptr->art_flags |= TR_NO_TELE;
- o_ptr->ident |= IDENT_CURSED;
}
@@ -2165,7 +2081,7 @@ static void note_found_object(object_type *o_ptr)
if (artifact_p(o_ptr))
{
- object_desc(item_name, o_ptr, FALSE, 0);
+ object_desc(item_name, o_ptr, false, 0);
/* Build note and write */
sprintf(note, "Found The %s", item_name);
@@ -2179,9 +2095,9 @@ static void note_found_object(object_type *o_ptr)
/*
* Identify an object in the inventory (or on the floor)
* This routine does *not* automatically combine objects.
- * Returns TRUE if something was identified, else FALSE.
+ * Returns true if something was identified, else false.
*/
-bool_ ident_spell()
+bool ident_spell()
{
/* Get an item */
int item;
@@ -2189,7 +2105,7 @@ bool_ ident_spell()
"Identify which item? ",
"You have nothing to identify.",
(USE_EQUIP | USE_INVEN | USE_FLOOR),
- object_filter::Not(object_known_p))) return (FALSE);
+ object_filter::Not(object_known_p))) return false;
/* Get the item */
object_type *o_ptr = get_object(item);
@@ -2209,7 +2125,7 @@ bool_ ident_spell()
/* Description */
char o_name[80];
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Describe */
if (item >= INVEN_WIELD)
@@ -2231,17 +2147,14 @@ bool_ ident_spell()
/* Make note of found artifacts */
note_found_object(o_ptr);
- /* Process the appropriate hooks */
- identify_hooks(item, o_ptr, IDENT_NORMAL);
-
/* Something happened */
- return (TRUE);
+ return true;
}
/*
* Identify all objects in the level
*/
-bool_ ident_all()
+bool ident_all()
{
int i;
@@ -2258,94 +2171,14 @@ bool_ ident_all()
/* Make note of found artifacts */
note_found_object(o_ptr);
-
- /* Process the appropriate hooks */
- identify_hooks(-i, o_ptr, IDENT_NORMAL);
}
/* Something happened */
- return (TRUE);
-}
-
-
-
-/*
- * Determine if an object is not fully identified
- */
-static bool item_tester_hook_no_mental(object_type const *o_ptr)
-{
- return ((o_ptr->ident & (IDENT_MENTAL)) ? false : true);
-}
-
-/*
- * Fully "identify" an object in the inventory -BEN-
- * This routine returns TRUE if an item was identified.
- */
-bool_ identify_fully()
-{
- /* Get an item */
- int item;
- if (!get_item(&item,
- "Identify which item? ",
- "You have nothing to identify.",
- (USE_EQUIP | USE_INVEN | USE_FLOOR),
- item_tester_hook_no_mental))
- {
- return (FALSE);
- }
-
- /* Get the item */
- object_type *o_ptr = get_object(item);
-
- /* Do the identification */
- make_item_fully_identified(o_ptr);
-
- /* Recalculate bonuses */
- p_ptr->update |= (PU_BONUS);
-
- /* Combine / Reorder the pack (later) */
- p_ptr->notice |= (PN_COMBINE | PN_REORDER);
-
- /* Window stuff */
- p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
-
- /* Description */
- char o_name[80];
- object_desc(o_name, o_ptr, TRUE, 3);
-
- /* Describe */
- if (item >= INVEN_WIELD)
- {
- msg_format("%^s: %s (%c).",
- describe_use(item), o_name, index_to_label(item));
- }
- else if (item >= 0)
- {
- msg_format("In your pack: %s (%c).",
- o_name, index_to_label(item));
- }
- else
- {
- msg_format("On the ground: %s.",
- o_name);
- }
-
- /* Make note of found artifacts */
- note_found_object(o_ptr);
-
- /* Describe it fully */
- object_out_desc(o_ptr, NULL, FALSE, TRUE);
-
- /* Process the appropriate hooks */
- identify_hooks(item, o_ptr, IDENT_FULL);
-
- /* Success */
- return (TRUE);
+ return true;
}
-
/*
* Hook for "get_item()". Determine if something is rechargable.
*/
@@ -2385,13 +2218,11 @@ object_filter_t const &item_tester_hook_recharge()
*
* XXX XXX XXX Beware of "sliding index errors".
*/
-bool_ recharge(int power)
+bool recharge(int power)
{
- auto const &k_info = game->edit_data.k_info;
-
int recharge_strength, recharge_amount;
int lev;
- bool_ fail = FALSE;
+ bool fail = false;
byte fail_type = 1;
char o_name[80];
@@ -2404,7 +2235,7 @@ bool_ recharge(int power)
(USE_INVEN | USE_FLOOR),
item_tester_hook_recharge()))
{
- return (FALSE);
+ return false;
}
/* Get the item */
@@ -2414,7 +2245,7 @@ bool_ recharge(int power)
auto const flags = object_flags(o_ptr);
/* Extract the object "level" */
- lev = k_info[o_ptr->k_idx].level;
+ lev = o_ptr->k_ptr->level;
/* Recharge a rod */
if (o_ptr->tval == TV_ROD_MAIN)
@@ -2429,7 +2260,7 @@ bool_ recharge(int power)
if ((rand_int(recharge_strength) == 0) && (!(flags & TR_RECHARGE)))
{
/* Activate the failure code. */
- fail = TRUE;
+ fail = true;
}
/* Recharge */
@@ -2467,7 +2298,7 @@ bool_ recharge(int power)
(flags & TR_NO_RECHARGE))
{
/* Activate the failure code. */
- fail = TRUE;
+ fail = true;
}
/* If the spell didn't backfire, recharge the wand or staff. */
@@ -2496,15 +2327,6 @@ bool_ recharge(int power)
/* Recharge the wand or staff. */
o_ptr->pval += recharge_amount;
-
- if (!(flags & TR_RECHARGE))
- {
- /* Hack -- we no longer "know" the item */
- o_ptr->ident &= ~(IDENT_KNOWN);
- }
-
- /* Hack -- we no longer think the item is empty */
- o_ptr->ident &= ~(IDENT_EMPTY);
}
}
@@ -2517,7 +2339,7 @@ bool_ recharge(int power)
/* Artifacts are never destroyed. */
if (artifact_p(o_ptr))
{
- object_desc(o_name, o_ptr, TRUE, 0);
+ object_desc(o_name, o_ptr, true, 0);
msg_format("The recharging backfires - %s is completely drained!", o_name);
/* Artifact rods. */
@@ -2531,7 +2353,7 @@ bool_ recharge(int power)
else
{
/* Get the object description */
- object_desc(o_name, o_ptr, FALSE, 0);
+ object_desc(o_name, o_ptr, false, 0);
/*** Determine Seriousness of Failure ***/
@@ -2637,7 +2459,7 @@ bool_ recharge(int power)
p_ptr->window |= (PW_INVEN);
/* Something was done */
- return (TRUE);
+ return true;
}
@@ -2647,11 +2469,11 @@ bool_ recharge(int power)
*
* Note that affected monsters are NOT auto-tracked by this usage.
*/
-bool_ project_hack(int typ, int dam)
+bool project_hack(int typ, int dam)
{
int i, x, y;
int flg = PROJECT_JUMP | PROJECT_KILL | PROJECT_HIDE;
- bool_ obvious = FALSE;
+ bool obvious = false;
/* Affect all (nearby) monsters */
@@ -2670,7 +2492,7 @@ bool_ project_hack(int typ, int dam)
if (!player_has_los_bold(y, x)) continue;
/* Jump directly to the target monster */
- if (project(0, 0, y, x, dam, typ, flg)) obvious = TRUE;
+ if (project(0, 0, y, x, dam, typ, flg)) obvious = true;
}
/* Result */
@@ -2715,7 +2537,7 @@ void project_meteor(int radius, int typ, int dam, u32b flg)
/*
* Banish evil monsters
*/
-bool_ banish_evil(int dist)
+bool banish_evil(int dist)
{
return (project_hack(GF_AWAY_EVIL, dist));
}
@@ -2725,33 +2547,33 @@ bool_ banish_evil(int dist)
/*
* Dispel undead monsters
*/
-bool_ dispel_undead(int dam)
+void dispel_undead(int dam)
{
- return (project_hack(GF_DISP_UNDEAD, dam));
+ project_hack(GF_DISP_UNDEAD, dam);
}
/*
* Dispel evil monsters
*/
-bool_ dispel_evil(int dam)
+void dispel_evil(int dam)
{
- return (project_hack(GF_DISP_EVIL, dam));
+ project_hack(GF_DISP_EVIL, dam);
}
/*
* Dispel good monsters
*/
-bool_ dispel_good(int dam)
+void dispel_good(int dam)
{
- return (project_hack(GF_DISP_GOOD, dam));
+ project_hack(GF_DISP_GOOD, dam);
}
/*
* Dispel all monsters
*/
-bool_ dispel_monsters(int dam)
+void dispel_monsters(int dam)
{
- return (project_hack(GF_DISP_ALL, dam));
+ project_hack(GF_DISP_ALL, dam);
}
@@ -2761,8 +2583,8 @@ bool_ dispel_monsters(int dam)
void aggravate_monsters(int who)
{
int i;
- bool_ sleep = FALSE;
- bool_ speed = FALSE;
+ bool sleep = false;
+ bool speed = false;
/* Aggravate everyone nearby */
@@ -2784,7 +2606,7 @@ void aggravate_monsters(int who)
{
/* Wake up */
m_ptr->csleep = 0;
- sleep = TRUE;
+ sleep = true;
}
}
@@ -2798,7 +2620,7 @@ void aggravate_monsters(int who)
{
/* Speed up */
m_ptr->mspeed = r_ptr->speed + 10;
- speed = TRUE;
+ speed = true;
}
/* Pets may get angry (50% chance) */
@@ -2820,13 +2642,13 @@ void aggravate_monsters(int who)
/*
* Generic genocide race selection
*/
-static bool get_genocide_race(cptr msg, char *typ)
+static bool get_genocide_race(const char *msg, char *typ)
{
int i, j;
cave_type *c_ptr;
msg_print(msg);
- if (!tgt_pt(&i, &j)) return FALSE;
+ if (!tgt_pt(&i, &j)) return false;
c_ptr = &cave[j][i];
@@ -2847,10 +2669,9 @@ static bool get_genocide_race(cptr msg, char *typ)
/*
* Delete all non-unique/non-quest monsters of a given "type" from the level
*/
-bool_ genocide_aux(bool_ player_cast, char typ)
+static void genocide_aux(char typ)
{
int i;
- bool_ result = FALSE;
auto const msec = options->delay_factor_ms();
int dam = 0;
@@ -2887,22 +2708,19 @@ bool_ genocide_aux(bool_ player_cast, char typ)
}
while (!(in_bounds(wy, wx) && cave_floor_bold(wy, wx)) && --attempts);
- if (place_monster_aux(wy, wx, m_ptr->r_idx, FALSE, TRUE, MSTATUS_ENEMY))
+ if (place_monster_aux(wy, wx, m_ptr->r_idx, false, true, MSTATUS_ENEMY))
{
cmsg_format(TERM_L_BLUE, "The spell seems to produce an ... interesting effect on the %s.", buf);
}
- return TRUE;
+ return;
}
/* Delete the monster */
delete_monster_idx(i);
- if (player_cast)
- {
- /* Keep track of damage */
- dam += randint(4);
- }
+ /* Keep track of damage */
+ dam += randint(4);
/* Handle */
handle_stuff();
@@ -2912,62 +2730,62 @@ bool_ genocide_aux(bool_ player_cast, char typ)
/* Delay */
sleep_for(milliseconds(msec));
-
- /* Take note */
- result = TRUE;
}
- if (player_cast)
- {
- /* Take damage */
- take_hit(dam, "the strain of casting Genocide");
-
- /* Visual feedback */
- move_cursor_relative(p_ptr->py, p_ptr->px);
+ /* Take damage */
+ take_hit(dam, "the strain of casting Genocide");
- /* Redraw */
- p_ptr->redraw |= (PR_FRAME);
+ /* Visual feedback */
+ move_cursor_relative(p_ptr->py, p_ptr->px);
- /* Window stuff */
- p_ptr->window |= (PW_PLAYER);
+ /* Redraw */
+ p_ptr->redraw |= (PR_FRAME);
- /* Handle */
- handle_stuff();
+ /* Window stuff */
+ p_ptr->window |= (PW_PLAYER);
- /* Fresh */
- Term_fresh();
- }
+ /* Handle */
+ handle_stuff();
- return (result);
+ /* Fresh */
+ Term_fresh();
}
-bool_ genocide(bool_ player_cast)
+void genocide()
{
- char typ;
+ auto const &dungeon_flags = game->dungeon_flags;
- if (dungeon_flags & DF_NO_GENO) return (FALSE);
+ if (dungeon_flags & DF_NO_GENO)
+ {
+ return;
+ }
/* Hack -- when you are fated to die, you cant cheat :) */
if (dungeon_type == DUNGEON_DEATH)
{
msg_print("A mysterious force stops the genocide.");
- return FALSE;
+ return;
}
/* Mega-Hack -- Get a monster symbol */
- if (!get_genocide_race("Target a monster to select the race to genocide.", &typ)) return FALSE;
+ char typ;
+ if (!get_genocide_race("Target a monster to select the race to genocide.", &typ))
+ {
+ return;
+ }
- return (genocide_aux(player_cast, typ));
+ genocide_aux(typ);
}
/*
* Delete all nearby (non-unique) monsters
*/
-bool_ mass_genocide(bool_ player_cast)
+void mass_genocide()
{
+ auto const &dungeon_flags = game->dungeon_flags;
+
int i;
- bool_ result = FALSE;
auto const msec = options->delay_factor_ms();
int dam = 0;
@@ -2975,7 +2793,7 @@ bool_ mass_genocide(bool_ player_cast)
if ((dungeon_flags & DF_NO_GENO) || (dungeon_type == DUNGEON_DEATH))
{
msg_print("A mysterious force stops the genocide.");
- return FALSE;
+ return;
}
/* Delete the (nearby) monsters */
@@ -3011,22 +2829,19 @@ bool_ mass_genocide(bool_ player_cast)
}
while (!(in_bounds(wy, wx) && cave_floor_bold(wy, wx)) && --attempts);
- if (place_monster_aux(wy, wx, m_ptr->r_idx, FALSE, TRUE, MSTATUS_ENEMY))
+ if (place_monster_aux(wy, wx, m_ptr->r_idx, false, true, MSTATUS_ENEMY))
{
cmsg_format(TERM_L_BLUE, "The spell seems to produce an ... interesting effect on the %s.", buf);
}
- return TRUE;
+ return;
}
/* Delete the monster */
delete_monster_idx(i);
- if (player_cast)
- {
- /* Keep track of damage. */
- dam += randint(3);
- }
+ /* Keep track of damage. */
+ dam += randint(3);
/* Handle */
handle_stuff();
@@ -3036,33 +2851,25 @@ bool_ mass_genocide(bool_ player_cast)
/* Delay */
sleep_for(milliseconds(msec));
-
- /* Note effect */
- result = TRUE;
}
- if (player_cast)
- {
- /* Take damage */
- take_hit(dam, "the strain of casting Mass Genocide");
-
- /* Visual feedback */
- move_cursor_relative(p_ptr->py, p_ptr->px);
+ /* Take damage */
+ take_hit(dam, "the strain of casting Mass Genocide");
- /* Redraw */
- p_ptr->redraw |= (PR_FRAME);
+ /* Visual feedback */
+ move_cursor_relative(p_ptr->py, p_ptr->px);
- /* Window stuff */
- p_ptr->window |= (PW_PLAYER);
+ /* Redraw */
+ p_ptr->redraw |= (PR_FRAME);
- /* Handle */
- handle_stuff();
+ /* Window stuff */
+ p_ptr->window |= (PW_PLAYER);
- /* Fresh */
- Term_fresh();
- }
+ /* Handle */
+ handle_stuff();
- return (result);
+ /* Fresh */
+ Term_fresh();
}
@@ -3076,11 +2883,13 @@ bool_ mass_genocide(bool_ player_cast)
*/
void destroy_area(int y1, int x1, int r)
{
+ auto const &dungeon_flags = game->dungeon_flags;
+
int y, x, k, t;
cave_type *c_ptr;
- bool_ flag = FALSE;
+ bool flag = false;
if (dungeon_flags & DF_NO_GENO)
@@ -3120,7 +2929,7 @@ void destroy_area(int y1, int x1, int r)
if ((x == p_ptr->px) && (y == p_ptr->py))
{
/* Hurt the player later */
- flag = TRUE;
+ flag = true;
/* Do not hurt this grid */
continue;
@@ -3231,9 +3040,9 @@ void earthquake(int cy, int cx, int r)
int i, t, y, x, yy, xx, dy, dx, oy, ox;
int damage = 0;
int sn = 0, sy = 0, sx = 0;
- bool_ hurt = FALSE;
+ bool hurt = false;
cave_type *c_ptr;
- bool_ map[32][32];
+ bool map[32][32];
if (p_ptr->inside_quest)
{
@@ -3248,7 +3057,7 @@ void earthquake(int cy, int cx, int r)
{
for (x = 0; x < 32; x++)
{
- map[y][x] = FALSE;
+ map[y][x] = false;
}
}
@@ -3283,10 +3092,10 @@ void earthquake(int cy, int cx, int r)
if (rand_int(100) < 85) continue;
/* Damage this grid */
- map[16 + yy - cy][16 + xx - cx] = TRUE;
+ map[16 + yy - cy][16 + xx - cx] = true;
/* Hack -- Take note of player damage */
- if ((yy == p_ptr->py) && (xx == p_ptr->px)) hurt = TRUE;
+ if ((yy == p_ptr->py) && (xx == p_ptr->px)) hurt = true;
}
}
@@ -3392,7 +3201,7 @@ void earthquake(int cy, int cx, int r)
}
/* Important -- no wall on player */
- map[16 + p_ptr->py - cy][16 + p_ptr->px - cx] = FALSE;
+ map[16 + p_ptr->py - cy][16 + p_ptr->px - cx] = false;
/* Semi-wraiths have to be hurt *some*, says DG */
if (race_flags_p(PR_SEMI_WRAITH))
@@ -3450,11 +3259,6 @@ void earthquake(int cy, int cx, int r)
if (cave[y][x].feat == FEAT_GLYPH) continue;
if (cave[y][x].feat == FEAT_MINOR_GLYPH) continue;
- /* ... nor on the Pattern */
- if ((cave[y][x].feat <= FEAT_PATTERN_XTRA2) &&
- (cave[y][x].feat >= FEAT_PATTERN_START))
- continue;
-
/* Important -- Skip "quake" grids */
if (map[16 + y - cy][16 + x - cx]) continue;
@@ -3514,7 +3318,7 @@ void earthquake(int cy, int cx, int r)
m_ptr->fx = sx;
/* Update the monster (new location) */
- update_mon(m_idx, TRUE);
+ update_mon(m_idx, true);
/* Redraw the old grid */
lite_spot(yy, xx);
@@ -3549,7 +3353,7 @@ void earthquake(int cy, int cx, int r)
/* Destroy location (if valid) */
if (cave_valid_bold(yy, xx))
{
- bool_ floor = cave_floor_bold(yy, xx);
+ bool floor = cave_floor_bold(yy, xx);
/* Delete objects */
delete_object(yy, xx);
@@ -3673,7 +3477,7 @@ static void cave_temp_room_lite()
auto const r_ptr = m_ptr->race();
/* Update the monster */
- update_mon(c_ptr->m_idx, FALSE);
+ update_mon(c_ptr->m_idx, false);
/* Stupid monsters rarely wake up */
if (r_ptr->flags & RF_STUPID) chance = 10;
@@ -3876,7 +3680,7 @@ void unlite_room(int y1, int x1)
* Hack -- call light around the player
* Affect all monsters in the projection radius
*/
-bool_ lite_area(int dam, int rad)
+void lite_area(int dam, int rad)
{
int flg = PROJECT_GRID | PROJECT_KILL;
@@ -3891,9 +3695,6 @@ bool_ lite_area(int dam, int rad)
/* Lite up the room */
lite_room(p_ptr->py, p_ptr->px);
-
- /* Assume seen */
- return (TRUE);
}
@@ -3901,7 +3702,7 @@ bool_ lite_area(int dam, int rad)
* Hack -- call darkness around the player
* Affect all monsters in the projection radius
*/
-bool_ unlite_area(int dam, int rad)
+void unlite_area(int dam, int rad)
{
int flg = PROJECT_GRID | PROJECT_KILL;
@@ -3916,9 +3717,6 @@ bool_ unlite_area(int dam, int rad)
/* Lite up the room */
unlite_room(p_ptr->py, p_ptr->px);
-
- /* Assume seen */
- return (TRUE);
}
@@ -3928,7 +3726,7 @@ bool_ unlite_area(int dam, int rad)
* Allow "target" mode to pass over monsters
* Affect grids, objects, and monsters
*/
-bool_ fire_ball(int typ, int dir, int dam, int rad)
+bool fire_ball(int typ, int dir, int dam, int rad)
{
int tx, ty;
@@ -3956,7 +3754,7 @@ bool_ fire_ball(int typ, int dir, int dam, int rad)
* Allow "target" mode to pass over monsters
* Affect grids, objects, and monsters
*/
-bool_ fire_cloud(int typ, int dir, int dam, int rad, int time)
+void fire_cloud(int typ, int dir, int dam, int rad, int time)
{
int tx, ty;
@@ -3976,7 +3774,7 @@ bool_ fire_cloud(int typ, int dir, int dam, int rad, int time)
project_time = time;
/* Analyze the "dir" and the "target". Hurt items on floor. */
- return (project(0, (rad > 16) ? 16 : rad, ty, tx, dam, typ, flg));
+ project(0, (rad > 16) ? 16 : rad, ty, tx, dam, typ, flg);
}
/*
@@ -3985,10 +3783,10 @@ bool_ fire_cloud(int typ, int dir, int dam, int rad, int time)
* Allow "target" mode to pass over monsters
* Affect grids, objects, and monsters
*/
-bool_ fire_wave(int typ, int dir, int dam, int rad, int time, s32b eff)
+void fire_wave(int typ, int dir, int dam, int rad, int time, s32b eff)
{
project_time_effect = eff;
- return (fire_cloud(typ, dir, dam, rad, time));
+ fire_cloud(typ, dir, dam, rad, time);
}
/*
@@ -3996,11 +3794,11 @@ bool_ fire_wave(int typ, int dir, int dam, int rad, int time, s32b eff)
* Pass through monsters, as a "beam"
* Affect monsters (not grids or objects)
*/
-bool_ fire_wall(int typ, int dir, int dam, int time)
+void fire_wall(int typ, int dir, int dam, int time)
{
int flg = PROJECT_BEAM | PROJECT_KILL | PROJECT_STAY | PROJECT_GRID;
project_time = time;
- return (project_hook(typ, dir, dam, flg));
+ project_hook(typ, dir, dam, flg);
}
@@ -4059,7 +3857,7 @@ void teleport_swap(int dir)
ty = m_ptr->fy;
/* Update the monster (new location) */
- update_mon(cave[ty][tx].m_idx, TRUE);
+ update_mon(cave[ty][tx].m_idx, true);
/* Redraw the old grid */
lite_spot(ty, tx);
@@ -4170,7 +3968,7 @@ void swap_position(int lty, int ltx)
ty = m_ptr->fy;
/* Update the monster (new location) */
- update_mon(cave[ty][tx].m_idx, TRUE);
+ update_mon(cave[ty][tx].m_idx, true);
/* Redraw the old grid */
lite_spot(ty, tx);
@@ -4199,7 +3997,7 @@ void swap_position(int lty, int ltx)
/*
* Hack -- apply a "projection()" in a direction (or at the target)
*/
-bool_ project_hook(int typ, int dir, int dam, int flg)
+bool project_hook(int typ, int dir, int dam, int flg)
{
int tx, ty;
@@ -4227,10 +4025,9 @@ bool_ project_hook(int typ, int dir, int dam, int flg)
* Stop if we hit a monster, as a "bolt"
* Affect monsters (not grids or objects)
*/
-bool_ fire_bolt(int typ, int dir, int dam)
+void fire_bolt(int typ, int dir, int dam)
{
- int flg = PROJECT_STOP | PROJECT_KILL;
- return (project_hook(typ, dir, dam, flg));
+ project_hook(typ, dir, dam, PROJECT_STOP | PROJECT_KILL);
}
@@ -4239,25 +4036,24 @@ bool_ fire_bolt(int typ, int dir, int dam)
* Pass through monsters, as a "beam"
* Affect monsters (not grids or objects)
*/
-bool_ fire_beam(int typ, int dir, int dam)
+void fire_beam(int typ, int dir, int dam)
{
- int flg = PROJECT_BEAM | PROJECT_KILL;
- return (project_hook(typ, dir, dam, flg));
+ project_hook(typ, dir, dam, PROJECT_BEAM | PROJECT_KILL);
}
/*
* Cast a bolt spell, or rarely, a beam spell
*/
-bool_ fire_bolt_or_beam(int prob, int typ, int dir, int dam)
+void fire_bolt_or_beam(int prob, int typ, int dir, int dam)
{
if (rand_int(100) < prob)
{
- return (fire_beam(typ, dir, dam));
+ fire_beam(typ, dir, dam);
}
else
{
- return (fire_bolt(typ, dir, dam));
+ fire_bolt(typ, dir, dam);
}
}
@@ -4265,82 +4061,77 @@ bool_ fire_bolt_or_beam(int prob, int typ, int dir, int dam)
/*
* Some of the old functions
*/
-bool_ lite_line(int dir)
+void lite_line(int dir)
{
int flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_KILL;
- return (project_hook(GF_LITE_WEAK, dir, damroll(6, 8), flg));
+ project_hook(GF_LITE_WEAK, dir, damroll(6, 8), flg);
}
-bool_ drain_life(int dir, int dam)
+bool drain_life(int dir, int dam)
{
int flg = PROJECT_STOP | PROJECT_KILL;
return (project_hook(GF_OLD_DRAIN, dir, dam, flg));
}
-bool_ wall_to_mud(int dir)
+void wall_to_mud(int dir)
{
- int flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
- return (project_hook(GF_KILL_WALL, dir, 20 + randint(30), flg));
+ project_hook(GF_KILL_WALL, dir, 20 + randint(30),
+ PROJECT_BEAM | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL);
}
-bool_ wizard_lock(int dir)
+void wizard_lock(int dir)
{
- int flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
- return (project_hook(GF_JAM_DOOR, dir, 20 + randint(30), flg));
+ project_hook(GF_JAM_DOOR, dir, 20 + randint(30),
+ PROJECT_BEAM | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL);
}
-bool_ slow_monster(int dir)
+void slow_monster(int dir)
{
- int flg = PROJECT_STOP | PROJECT_KILL;
- return (project_hook(GF_OLD_SLOW, dir, p_ptr->lev, flg));
+ project_hook(GF_OLD_SLOW, dir, p_ptr->lev, PROJECT_STOP | PROJECT_KILL);
}
-bool_ sleep_monster(int dir)
+void sleep_monster(int dir)
{
- int flg = PROJECT_STOP | PROJECT_KILL;
- return (project_hook(GF_OLD_SLEEP, dir, p_ptr->lev, flg));
+ project_hook(GF_OLD_SLEEP, dir, p_ptr->lev, PROJECT_STOP | PROJECT_KILL);
}
-bool_ confuse_monster(int dir, int plev)
+void confuse_monster(int dir, int plev)
{
- int flg = PROJECT_STOP | PROJECT_KILL;
- return (project_hook(GF_OLD_CONF, dir, plev, flg));
+ project_hook(GF_OLD_CONF, dir, plev, PROJECT_STOP | PROJECT_KILL);
}
-bool_ poly_monster(int dir)
+void poly_monster(int dir)
{
- int flg = PROJECT_STOP | PROJECT_KILL;
- return (project_hook(GF_OLD_POLY, dir, p_ptr->lev, flg));
+ project_hook(GF_OLD_POLY, dir, p_ptr->lev, PROJECT_STOP | PROJECT_KILL);
}
-bool_ fear_monster(int dir, int plev)
+void fear_monster(int dir, int plev)
{
- int flg = PROJECT_STOP | PROJECT_KILL;
- return (project_hook(GF_TURN_ALL, dir, plev, flg));
+ project_hook(GF_TURN_ALL, dir, plev, PROJECT_STOP | PROJECT_KILL);
}
-bool_ teleport_monster(int dir)
+void teleport_monster(int dir)
{
int flg = PROJECT_BEAM | PROJECT_KILL;
if (p_ptr->resist_continuum)
{
msg_print("The space-time continuum can't be disrupted.");
- return FALSE;
+ return;
}
- return (project_hook(GF_AWAY_ALL, dir, MAX_SIGHT * 5, flg));
+ project_hook(GF_AWAY_ALL, dir, MAX_SIGHT * 5, flg);
}
-bool_ wall_stone(int y, int x)
+void wall_stone(int y, int x)
{
auto const &f_info = game->edit_data.f_info;
@@ -4348,7 +4139,7 @@ bool_ wall_stone(int y, int x)
int flg = PROJECT_GRID | PROJECT_ITEM;
auto const featflags = f_info[c_ptr->feat].flags;
- bool_ dummy = (project(0, 1, y, x, 0, GF_STONE_WALL, flg));
+ project(0, 1, y, x, 0, GF_STONE_WALL, flg);
if (!(featflags & FF_PERMANENT) && !(featflags & FF_WALL))
cave_set_feat(y, x, FEAT_FLOOR);
@@ -4364,21 +4155,18 @@ bool_ wall_stone(int y, int x)
/* Window stuff */
p_ptr->window |= (PW_OVERHEAD);
-
- return dummy;
}
-bool_ destroy_doors_touch()
+void destroy_doors_touch()
{
- int flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
- return (project(0, 1, p_ptr->py, p_ptr->px, 0, GF_KILL_DOOR, flg));
+ project(0, 1, p_ptr->py, p_ptr->px, 0, GF_KILL_DOOR,
+ PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE);
}
-bool_ sleep_monsters_touch()
+void sleep_monsters_touch()
{
- int flg = PROJECT_KILL | PROJECT_HIDE;
- return (project(0, 1, p_ptr->py, p_ptr->px, p_ptr->lev, GF_OLD_SLEEP, flg));
+ project(0, 1, p_ptr->py, p_ptr->px, p_ptr->lev, GF_OLD_SLEEP, PROJECT_KILL | PROJECT_HIDE);
}
@@ -4386,7 +4174,7 @@ void call_chaos()
{
int Chaos_type, dummy, dir;
int plev = p_ptr->lev;
- bool_ line_chaos = FALSE;
+ bool line_chaos = false;
int hurt_types[30] =
{
@@ -4401,7 +4189,7 @@ void call_chaos()
};
Chaos_type = hurt_types[randint(30) - 1];
- if (randint(4) == 1) line_chaos = TRUE;
+ if (randint(4) == 1) line_chaos = true;
if (randint(6) == 1)
{
@@ -4505,7 +4293,7 @@ static void activate_hi_summon()
void activate_ty_curse()
{
int i = 0;
- bool_ stop_ty = FALSE;
+ bool stop_ty = false;
do
{
@@ -4542,7 +4330,7 @@ case 13: case 14: case 15: case 19: case 20:
set_paralyzed(randint(3));
else
set_paralyzed(randint(13));
- stop_ty = TRUE;
+ stop_ty = true;
}
if (randint(6) != 1) break;
case 21: case 22: case 23:
@@ -4559,7 +4347,7 @@ case 21: case 22: case 23:
if ((dun_level > 65) && !stop_ty)
{
summon_cyber();
- stop_ty = TRUE;
+ stop_ty = true;
break;
}
default:
@@ -4584,7 +4372,7 @@ case 21: case 22: case 23:
void activate_dg_curse()
{
int i = 0;
- bool_ stop_dg = FALSE;
+ bool stop_dg = false;
do
{
@@ -4617,7 +4405,7 @@ void activate_dg_curse()
if (rand_int(2))
{
msg_print("You feel the coldness of the Black Breath attacking you!");
- p_ptr->black_breath = TRUE;
+ p_ptr->black_breath = true;
}
if (randint(8) != 1) break;
case 13:
@@ -4634,7 +4422,7 @@ void activate_dg_curse()
set_paralyzed(randint(3));
else
set_paralyzed(randint(13));
- stop_dg = TRUE;
+ stop_dg = true;
}
if (randint(7) != 1) break;
case 19:
@@ -4642,7 +4430,7 @@ void activate_dg_curse()
{
msg_print("Woah! You see 10 little Morgoths dancing before you!");
set_confused(p_ptr->confused + randint(13 * 2));
- if (rand_int(2)) stop_dg = TRUE;
+ if (rand_int(2)) stop_dg = true;
}
if (randint(7) != 1) break;
case 21:
@@ -4655,7 +4443,7 @@ void activate_dg_curse()
lose_all_info();
break;
case 27: case 28: case 29:
- if (p_ptr->inventory[INVEN_WIELD].k_idx)
+ if (p_ptr->inventory[INVEN_WIELD].k_ptr)
{
msg_print("Your weapon now seems useless...");
p_ptr->inventory[INVEN_WIELD].art_flags = TR_NEVER_BLOW;
@@ -4671,7 +4459,7 @@ case 27: case 28: case 29:
summon_dragon_riders();
/* This is evil -- DG */
- if (rand_int(2)) stop_dg = TRUE;
+ if (rand_int(2)) stop_dg = true;
break;
}
default:
@@ -4713,88 +4501,54 @@ static void summon_dragon_riders()
}
}
-
-
-/*
- * Confuse monsters
- */
-bool_ confuse_monsters(int dam)
+void confuse_monsters(int dam)
{
- return (project_hack(GF_OLD_CONF, dam));
+ project_hack(GF_OLD_CONF, dam);
}
-
-/*
- * Charm monsters
- */
-bool_ charm_monsters(int dam)
+void charm_monsters(int dam)
{
- return (project_hack(GF_CHARM, dam));
+ project_hack(GF_CHARM, dam);
}
-
-/*
- * Charm animals
- */
-bool_ charm_animals(int dam)
+void charm_animals(int dam)
{
- return (project_hack(GF_CONTROL_ANIMAL, dam));
+ project_hack(GF_CONTROL_ANIMAL, dam);
}
-
-/*
- * Stun monsters
- */
-bool_ stun_monsters(int dam)
+void stun_monsters(int dam)
{
- return (project_hack(GF_STUN, dam));
+ project_hack(GF_STUN, dam);
}
-
-/*
- * Mindblast monsters
- */
-bool_ mindblast_monsters(int dam)
+void mindblast_monsters(int dam)
{
- return (project_hack(GF_PSI, dam));
+ project_hack(GF_PSI, dam);
}
-
-/*
- * Banish all monsters
- */
-bool_ banish_monsters(int dist)
+void banish_monsters(int dist)
{
- return (project_hack(GF_AWAY_ALL, dist));
+ project_hack(GF_AWAY_ALL, dist);
}
-
-/*
- * Turn everyone
- */
-bool_ turn_monsters(int dam)
+void turn_monsters(int dam)
{
- return (project_hack(GF_TURN_ALL, dam));
+ project_hack(GF_TURN_ALL, dam);
}
-
-bool_ charm_monster(int dir, int plev)
+void charm_monster(int dir, int plev)
{
- int flg = PROJECT_STOP | PROJECT_KILL;
- return (project_hook(GF_CHARM, dir, plev, flg));
+ project_hook(GF_CHARM, dir, plev, PROJECT_STOP | PROJECT_KILL);
}
-bool_ control_one_undead(int dir, int plev)
+void control_one_undead(int dir, int plev)
{
- int flg = PROJECT_STOP | PROJECT_KILL;
- return (project_hook(GF_CONTROL_UNDEAD, dir, plev, flg));
+ project_hook(GF_CONTROL_UNDEAD, dir, plev, PROJECT_STOP | PROJECT_KILL);
}
-
-bool_ charm_animal(int dir, int plev)
+void charm_animal(int dir, int plev)
{
- int flg = PROJECT_STOP | PROJECT_KILL;
- return (project_hook(GF_CONTROL_ANIMAL, dir, plev, flg));
+ project_hook(GF_CONTROL_ANIMAL, dir, plev, PROJECT_STOP | PROJECT_KILL);
}
void change_wild_mode()
@@ -4815,7 +4569,7 @@ void change_wild_mode()
autosave_checkpoint();
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
}
@@ -4826,11 +4580,10 @@ void alter_reality()
autosave_checkpoint();
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
}
-/* Heal insanity. */
-bool_ heal_insanity(int val)
+void heal_insanity(int val)
{
if (p_ptr->csane < p_ptr->msane)
{
@@ -4861,20 +4614,17 @@ bool_ heal_insanity(int val)
{
msg_print("You feel very good.");
}
-
- return TRUE;
}
-
- return FALSE;
}
/*
* Send the player shooting through walls in the given direction until
* they reach a non-wall space, or a monster, or a permanent wall.
*/
-bool_ passwall(int dir, bool_ safe)
+bool passwall(int dir, bool safe)
{
auto const &f_info = game->edit_data.f_info;
+ auto const &dungeon_flags = game->dungeon_flags;
int x = p_ptr->px;
int y = p_ptr->py;
@@ -4883,16 +4633,16 @@ bool_ passwall(int dir, bool_ safe)
int lx = p_ptr->px;
int ly = p_ptr->py;
cave_type *c_ptr;
- bool_ ok = FALSE;
+ bool ok = false;
- if (p_ptr->wild_mode) return FALSE;
- if (p_ptr->inside_quest) return FALSE;
- if (dungeon_flags & DF_NO_TELEPORT) return FALSE;
+ if (p_ptr->wild_mode) return false;
+ if (p_ptr->inside_quest) return false;
+ if (dungeon_flags & DF_NO_TELEPORT) return false;
/* Must go somewhere */
- if (dir == 5) return FALSE;
+ if (dir == 5) return false;
- while (TRUE)
+ while (true)
{
x += ddx[dir];
y += ddy[dir];
@@ -4904,7 +4654,7 @@ bool_ passwall(int dir, bool_ safe)
/* get the last working position */
x -= ddx[dir];
y -= ddy[dir];
- ok = FALSE;
+ ok = false;
break;
}
@@ -4922,7 +4672,7 @@ bool_ passwall(int dir, bool_ safe)
if (f_info[c_ptr->feat].flags & FF_WALL) continue;
/* So it must be ok */
- ok = TRUE;
+ ok = true;
break;
}
@@ -4964,7 +4714,7 @@ bool_ passwall(int dir, bool_ safe)
/* Handle stuff XXX XXX XXX */
handle_stuff();
- return (TRUE);
+ return true;
}
/*
@@ -4972,7 +4722,7 @@ bool_ passwall(int dir, bool_ safe)
*/
static void print_dungeon_batch(std::vector<int> const &dungeon_idxs,
int start,
- bool_ mode)
+ bool mode)
{
auto const &d_info = game->edit_data.d_info;
@@ -5029,7 +4779,7 @@ static int reset_recall_aux()
char which;
int start = 0;
int ret;
- bool_ mode = FALSE;
+ bool mode = false;
// Dungeons available for recall
std::vector<int> dungeons;
@@ -5044,10 +4794,9 @@ static int reset_recall_aux()
}
}
- character_icky = TRUE;
- Term_save();
+ screen_save_no_flush();
- while (1)
+ while (true)
{
print_dungeon_batch(dungeons, start, mode);
which = inkey();
@@ -5060,9 +4809,8 @@ static int reset_recall_aux()
else if (which == '*' || which == '?' || which == ' ')
{
- mode = (mode) ? FALSE : TRUE;
- Term_load();
- character_icky = FALSE;
+ mode = (mode) ? false : true;
+ screen_load_no_flush();
}
else if (which == '+')
@@ -5073,8 +4821,7 @@ static int reset_recall_aux()
{
start -= 20;
}
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
}
else if (which == '-')
@@ -5084,8 +4831,7 @@ static int reset_recall_aux()
{
start += 20;
}
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
}
else if (which == '@')
@@ -5143,13 +4889,12 @@ static int reset_recall_aux()
}
}
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
return ret;
}
-bool_ reset_recall(bool_ no_trepas_max_depth)
+bool reset_recall(bool no_trepas_max_depth)
{
auto const &d_info = game->edit_data.d_info;
@@ -5158,7 +4903,7 @@ bool_ reset_recall(bool_ no_trepas_max_depth)
/* Choose dungeon */
dun = reset_recall_aux();
- if (dun < 1) return FALSE;
+ if (dun < 1) return false;
/* Choose depth */
if (!no_trepas_max_depth)
@@ -5171,7 +4916,7 @@ bool_ reset_recall(bool_ no_trepas_max_depth)
d_info[dun].mindepth, max),
max);
- if (depth < 1) return FALSE;
+ if (depth < 1) return false;
/* Enforce minimum level */
if (depth < d_info[dun].mindepth) depth = d_info[dun].mindepth;
@@ -5182,7 +4927,7 @@ bool_ reset_recall(bool_ no_trepas_max_depth)
p_ptr->recall_dungeon = dun;
max_dlv[p_ptr->recall_dungeon] = depth;
- return TRUE;
+ return true;
}
/*
@@ -5191,6 +4936,7 @@ bool_ reset_recall(bool_ no_trepas_max_depth)
void create_between_gate(int dist, int y, int x)
{
auto const &f_info = game->edit_data.f_info;
+ auto const &dungeon_flags = game->dungeon_flags;
int ii, ij, plev = get_skill(SKILL_CONVEYANCE);
@@ -5325,7 +5071,7 @@ void geomancy_random_wall(int y, int x)
#undef TABLE_SIZE
}
-void geomancy_random_floor(int y, int x, bool_ kill_wall)
+void geomancy_random_floor(int y, int x, bool kill_wall)
{
auto const &f_info = game->edit_data.f_info;
@@ -5364,7 +5110,7 @@ void geomancy_random_floor(int y, int x, bool_ kill_wall)
#undef TABLE_SIZE
}
-static bool_ geomancy_can_tunnel(int y, int x)
+static bool geomancy_can_tunnel(int y, int x)
{
switch (cave[y][x].feat)
{
@@ -5384,9 +5130,9 @@ static bool_ geomancy_can_tunnel(int y, int x)
case FEAT_SANDWALL_H:
case FEAT_SANDWALL_K:
case FEAT_ICE_WALL:
- return TRUE;
+ return true;
default:
- return FALSE;
+ return false;
}
}
@@ -5425,7 +5171,7 @@ void geomancy_dig(int oy, int ox, int dir, int length)
x = x - dx;
while ((y != oy) || (x != ox))
{
- geomancy_random_floor(y, x, TRUE);
+ geomancy_random_floor(y, x, true);
/* Should we branch ? */
if (magik(20))
diff --git a/src/spells2.hpp b/src/spells2.hpp
index 0eeb3f5b..87894bff 100644
--- a/src/spells2.hpp
+++ b/src/spells2.hpp
@@ -1,7 +1,6 @@
#pragma once
-#include "h-basic.h"
-#include "identify_mode.hpp"
+#include "h-basic.hpp"
#include "monster_race_flag_set.hpp"
#include "object_filter.hpp"
#include "object_type_fwd.hpp"
@@ -10,103 +9,98 @@ void curse_artifact(object_type * o_ptr);
void grow_things(s16b type, int rad);
void grow_grass(int rad);
void grow_trees(int rad);
-bool_ hp_player(int num);
-bool_ heal_insanity(int val);
+void hp_player(int num);
+void heal_insanity(int val);
void warding_glyph();
void explosive_rune();
-bool_ do_dec_stat(int stat, int mode);
-bool_ do_res_stat(int stat, bool_ full);
-bool_ do_inc_stat(int stat);
-void identify_hooks(int i, object_type *o_ptr, identify_mode type);
-bool_ identify_pack();
+void do_dec_stat(int stat, int mode);
+bool do_res_stat(int stat, bool full);
+bool do_inc_stat(int stat);
+void identify_hooks(object_type *o_ptr);
+bool identify_pack();
void identify_pack_fully();
-bool_ remove_curse();
-bool_ remove_all_curse();
-bool_ restore_level();
-bool_ lose_all_info();
-bool_ detect_traps(int rad);
-bool_ detect_doors(int rad);
-bool_ detect_stairs(int rad);
-bool_ detect_treasure(int rad);
+bool remove_curse();
+bool remove_all_curse();
+bool restore_level();
+bool lose_all_info();
+bool detect_doors(int rad);
+bool detect_stairs(int rad);
+bool detect_treasure(int rad);
bool detect_objects_gold(int rad);
bool detect_objects_normal(int rad);
-bool_ detect_monsters_normal(int rad);
-bool_ detect_monsters_invis(int rad);
+bool detect_monsters_normal(int rad);
+bool detect_monsters_invis(int rad);
void detect_monsters_orcs(int rad);
-bool_ detect_all(int rad);
+bool detect_all(int rad);
void stair_creation();
-bool_ wall_stone(int y, int x);
-bool_ enchant(object_type *o_ptr, int n, int eflag);
-bool_ enchant_spell(int num_hit, int num_dam, int num_ac, int num_pval);
-bool_ ident_spell();
-bool_ ident_all();
-bool_ identify_fully();
-bool_ recharge(int num);
+void wall_stone(int y, int x);
+bool enchant(object_type *o_ptr, int n, int eflag);
+bool enchant_spell(int num_hit, int num_dam, int num_ac, int num_pval);
+bool ident_spell();
+bool ident_all();
+bool recharge(int num);
void aggravate_monsters(int who);
-bool_ genocide_aux(bool_ player_cast, char typ);
-bool_ genocide(bool_ player_cast);
-bool_ mass_genocide(bool_ player_cast);
+void genocide();
+void mass_genocide();
void change_wild_mode();
-bool_ banish_evil(int dist);
-bool_ dispel_evil(int dam);
-bool_ dispel_good(int dam);
-bool_ dispel_undead(int dam);
-bool_ dispel_monsters(int dam);
+bool banish_evil(int dist);
+void dispel_evil(int dam);
+void dispel_good(int dam);
+void dispel_undead(int dam);
+void dispel_monsters(int dam);
void destroy_area(int y1, int x1, int r);
void earthquake(int cy, int cx, int r);
void lite_room(int y1, int x1);
void unlite_room(int y1, int x1);
-bool_ lite_area(int dam, int rad);
-bool_ unlite_area(int dam, int rad);
-bool_ fire_cloud(int typ, int dir, int dam, int rad, int time);
-bool_ fire_wave(int typ, int dir, int dam, int rad, int time, s32b eff);
-bool_ fire_wall(int typ, int dir, int dam, int time);
-bool_ fire_ball(int typ, int dir, int dam, int rad);
-bool_ fire_bolt(int typ, int dir, int dam);
-bool_ fire_beam(int typ, int dir, int dam);
+void lite_area(int dam, int rad);
+void unlite_area(int dam, int rad);
+void fire_cloud(int typ, int dir, int dam, int rad, int time);
+void fire_wave(int typ, int dir, int dam, int rad, int time, s32b eff);
+void fire_wall(int typ, int dir, int dam, int time);
+bool fire_ball(int typ, int dir, int dam, int rad);
+void fire_bolt(int typ, int dir, int dam);
+void fire_beam(int typ, int dir, int dam);
void call_chaos();
-bool_ fire_bolt_or_beam(int prob, int typ, int dir, int dam);
-bool_ lite_line(int dir);
-bool_ drain_life(int dir, int dam);
-bool_ wall_to_mud(int dir);
-bool_ wizard_lock(int dir);
-bool_ slow_monster(int dir);
-bool_ sleep_monster(int dir);
-bool_ confuse_monster(int dir, int plev);
-bool_ fear_monster(int dir, int plev);
-bool_ poly_monster(int dir);
-bool_ teleport_monster(int dir);
-bool_ trap_creation();
-bool_ destroy_doors_touch();
-bool_ destroy_traps_touch();
-bool_ sleep_monsters_touch();
-bool_ alchemy();
+void fire_bolt_or_beam(int prob, int typ, int dir, int dam);
+void lite_line(int dir);
+bool drain_life(int dir, int dam);
+void wall_to_mud(int dir);
+void wizard_lock(int dir);
+void slow_monster(int dir);
+void sleep_monster(int dir);
+void confuse_monster(int dir, int plev);
+void fear_monster(int dir, int plev);
+void poly_monster(int dir);
+void teleport_monster(int dir);
+void destroy_doors_touch();
+void sleep_monsters_touch();
+void alchemy();
void activate_ty_curse();
void activate_dg_curse();
void summon_cyber();
-bool_ confuse_monsters(int dam);
-bool_ charm_monsters(int dam);
-bool_ charm_animals(int dam);
-bool_ stun_monsters(int dam);
-bool_ banish_monsters(int dist);
-bool_ turn_monsters(int dam);
-bool_ charm_monster(int dir, int plev);
-bool_ control_one_undead(int dir, int plev);
-bool_ charm_animal(int dir, int plev);
-bool_ mindblast_monsters(int dam);
+void confuse_monsters(int dam);
+void charm_monsters(int dam);
+void charm_animals(int dam);
+void stun_monsters(int dam);
+void banish_monsters(int dist);
+void turn_monsters(int dam);
+void charm_monster(int dir, int plev);
+void control_one_undead(int dir, int plev);
+void charm_animal(int dir, int plev);
+void mindblast_monsters(int dam);
void alter_reality();
void report_magics();
void teleport_swap(int dir);
void swap_position(int lty, int ltx);
object_filter_t const &item_tester_hook_recharge();
-bool_ project_hack(int typ, int dam);
+bool project_hack(int typ, int dam);
void project_meteor(int radius, int typ, int dam, u32b flg);
object_filter_t const &item_tester_hook_artifactable();
-bool_ passwall(int dir, bool_ safe);
-bool_ project_hook(int typ, int dir, int dam, int flg);
-bool_ reset_recall(bool_ no_trepas_max_depth);
+bool passwall(int dir, bool safe);
+bool project_hook(int typ, int dir, int dam, int flg);
+bool reset_recall(bool no_trepas_max_depth);
void geomancy_random_wall(int y, int x);
-void geomancy_random_floor(int y, int x, bool_ kill_wall);
+void geomancy_random_floor(int y, int x, bool kill_wall);
void geomancy_dig(int oy, int ox, int dir, int length);
void channel_the_elements(int y, int x, int level);
void random_resistance(object_type *o_ptr, int specific);
diff --git a/src/spells3.cc b/src/spells3.cc
index 58d42cab..7fbc9d6b 100644
--- a/src/spells3.cc
+++ b/src/spells3.cc
@@ -34,6 +34,7 @@
#include <algorithm>
#include <cassert>
+#include <fmt/format.h>
#include <vector>
s32b NOXIOUSCLOUD = -1; /* Identifier */
@@ -59,8 +60,6 @@ s32b DEMON_SUMMON;
s32b DISCHARGE_MINION;
s32b CONTROL_DEMON;
-s32b STARIDENTIFY;
-s32b IDENTIFY;
s32b VISION;
s32b SENSEHIDDEN;
s32b REVEALWAYS;
@@ -74,7 +73,6 @@ s32b SHAKE;
s32b ERU_SEE;
s32b ERU_LISTEN;
-s32b ERU_UNDERSTAND;
s32b ERU_PROT;
s32b GLOBELIGHT;
@@ -205,29 +203,6 @@ static void find_position(int y, int x, int *yy, int *xx)
while (!(in_bounds(*yy, *xx) && cave_floor_bold(*yy, *xx)) && --attempts);
}
-static casting_result cast(bool_ effect)
-{
- return effect ? CAST_OBVIOUS : CAST_HIDDEN;
-}
-
-static casting_result cplus(casting_result old, bool_ effect)
-{
- if (old == NO_CAST)
- {
- return cast(effect);
- }
- else
- {
- if ((old == CAST_OBVIOUS) || (effect == TRUE)) {
- return CAST_OBVIOUS;
- }
- else
- {
- return CAST_HIDDEN;
- }
- }
-}
-
GENERATE_MONSTER_LOOKUP_FN(get_fire_golem, "Fire golem")
// -------------------------------------------------------------
@@ -251,17 +226,15 @@ casting_result air_noxious_cloud()
}
fire_cloud(type, dir, 7 + get_level_s(NOXIOUSCLOUD, 150), 3, 5 + get_level_s(NOXIOUSCLOUD, 40));
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *air_noxious_cloud_info()
+std::string air_noxious_cloud_info()
{
- static char buf[128];
- sprintf(buf,
- "dam " FMTs32b " rad 3 dur " FMTs32b,
- (7 + get_level_s(NOXIOUSCLOUD, 150)),
- (5 + get_level_s(NOXIOUSCLOUD, 40)));
- return buf;
+ return fmt::format(
+ "dam {} rad 3 dur {}",
+ 7 + get_level_s(NOXIOUSCLOUD, 150),
+ 5 + get_level_s(NOXIOUSCLOUD, 40));
}
casting_result air_wings_of_winds()
@@ -270,44 +243,41 @@ casting_result air_wings_of_winds()
{
if (p_ptr->tim_fly == 0)
{
- return cast(set_tim_fly(randint(10) + 5 + get_level_s(AIRWINGS, 25)));
+ set_tim_fly(randint(10) + 5 + get_level_s(AIRWINGS, 25));
}
}
else
{
if (p_ptr->tim_ffall == 0)
{
- return cast(set_tim_ffall(randint(10) + 5 + get_level_s(AIRWINGS, 25)));
+ set_tim_ffall(randint(10) + 5 + get_level_s(AIRWINGS, 25));
}
}
- return CAST_HIDDEN;
+ return CAST;
}
-const char *air_wings_of_winds_info()
+std::string air_wings_of_winds_info()
{
- static char buf[128];
- sprintf(buf, "dur " FMTs32b "+d10", (5 + get_level_s(AIRWINGS, 25)));
- return buf;
+ return fmt::format("dur {}+d10", 5 + get_level_s(AIRWINGS, 25));
}
casting_result air_invisibility()
{
if (p_ptr->tim_invisible == 0)
{
- return cast(set_invis(randint(20) + 15 + get_level_s(INVISIBILITY, 50), 20 + get_level_s(INVISIBILITY, 50)));
+ set_invis(randint(20) + 15 + get_level_s(INVISIBILITY, 50), 20 + get_level_s(INVISIBILITY, 50));
}
- return CAST_HIDDEN;
+ return CAST;
}
-const char *air_invisibility_info()
+std::string air_invisibility_info()
{
- static char buf[128];
- sprintf(buf, "dur " FMTs32b "+d20 power " FMTs32b,
- (15 + get_level_s(INVISIBILITY, 50)),
- (20 + get_level_s(INVISIBILITY, 50)));
- return buf;
+ return fmt::format(
+ "dur {}+d20 power {}",
+ 15 + get_level_s(INVISIBILITY, 50),
+ 20 + get_level_s(INVISIBILITY, 50));
}
casting_result air_poison_blood()
@@ -316,61 +286,57 @@ casting_result air_poison_blood()
if (p_ptr->oppose_pois == 0)
{
- result = cplus(result, set_oppose_pois(randint(30) + 25 + get_level_s(POISONBLOOD, 25)));
+ set_oppose_pois(randint(30) + 25 + get_level_s(POISONBLOOD, 25));
+ result = CAST;
}
if ((p_ptr->tim_poison == 0) &&
(get_level_s(POISONBLOOD, 50) >= 15))
{
- result = cplus(result, set_poison(randint(30) + 25 + get_level_s(POISONBLOOD, 25)));
+ set_poison(randint(30) + 25 + get_level_s(POISONBLOOD, 25));
+ result = CAST;
}
return result;
}
-const char *air_poison_blood_info()
+std::string air_poison_blood_info()
{
- static char buf[128];
- sprintf(buf,
- "dur " FMTs32b "+d30",
- (25 + get_level_s(POISONBLOOD, 25)));
- return buf;
+ return fmt::format(
+ "dur {}+d30",
+ 25 + get_level_s(POISONBLOOD, 25));
}
casting_result air_thunderstorm()
{
if (p_ptr->tim_thunder == 0)
{
- return cast(set_tim_thunder(randint(10) + 10 + get_level_s(THUNDERSTORM, 25), 5 + get_level_s(THUNDERSTORM, 10), 10 + get_level_s(THUNDERSTORM, 25)));
+ set_tim_thunder(randint(10) + 10 + get_level_s(THUNDERSTORM, 25), 5 + get_level_s(THUNDERSTORM, 10), 10 + get_level_s(THUNDERSTORM, 25));
}
- return CAST_HIDDEN;
+ return CAST;
}
-const char *air_thunderstorm_info()
+std::string air_thunderstorm_info()
{
- static char buf[128];
- sprintf(buf,
- "dam " FMTs32b "d" FMTs32b " dur " FMTs32b "+d10",
- (5 + get_level_s(THUNDERSTORM, 10)),
- (10 + get_level_s(THUNDERSTORM, 25)),
- (10 + get_level_s(THUNDERSTORM, 25)));
- return buf;
+ return fmt::format(
+ "dam {}d{} dur {}+d10",
+ 5 + get_level_s(THUNDERSTORM, 10),
+ 10 + get_level_s(THUNDERSTORM, 25),
+ 10 + get_level_s(THUNDERSTORM, 25));
}
casting_result air_sterilize()
{
set_no_breeders((30) + 20 + get_level_s(STERILIZE, 70));
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *air_sterilize_info()
+std::string air_sterilize_info()
{
- static char buf[128];
- sprintf(buf,
- "dur " FMTs32b "+d30",
- (20 + get_level_s(STERILIZE, 70)));
- return buf;
+ return fmt::format(
+ "dur {}+d30",
+ 20 + get_level_s(STERILIZE, 70));
}
casting_result convey_blink()
@@ -382,45 +348,41 @@ casting_result convey_blink()
teleport_player(10 + get_level_s(BLINK, 8));
create_between_gate(0, oy, ox);
- return CAST_OBVIOUS;
}
else
{
teleport_player(10 + get_level_s(BLINK, 8));
- return CAST_OBVIOUS;
}
+
+ return CAST;
}
-const char *convey_blink_info()
+std::string convey_blink_info()
{
- static char buf[128];
- sprintf(buf,
- "distance " FMTs32b,
- (10 + get_level_s(BLINK, 8)));
- return buf;
+ return fmt::format(
+ "distance {}",
+ 10 + get_level_s(BLINK, 8));
}
casting_result convey_teleport()
{
p_ptr->energy -= (25 - get_level_s(TELEPORT, 50));
teleport_player(100 + get_level_s(TELEPORT, 100));
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *convey_teleport_info()
+std::string convey_teleport_info()
{
- static char buf[128];
- sprintf(buf,
- "distance " FMTs32b,
- (100 + get_level_s(TELEPORT, 100)));
- return buf;
+ return fmt::format(
+ "distance {}",
+ 100 + get_level_s(TELEPORT, 100));
}
casting_result convey_teleport_away()
{
if (get_level_s(TELEAWAY, 50) >= 20)
{
- return cast(project_hack(GF_AWAY_ALL, 100));
+ project_hack(GF_AWAY_ALL, 100);
}
else if (get_level_s(TELEAWAY, 50) >= 10)
{
@@ -430,7 +392,7 @@ casting_result convey_teleport_away()
return NO_CAST;
}
- return cast(fire_ball(GF_AWAY_ALL, dir, 100, 3 + get_level_s(TELEAWAY, 4)));
+ fire_ball(GF_AWAY_ALL, dir, 100, 3 + get_level_s(TELEAWAY, 4));
}
else
{
@@ -439,8 +401,10 @@ casting_result convey_teleport_away()
{
return NO_CAST;
}
- return cast(teleport_monster(dir));
+ teleport_monster(dir);
}
+
+ return CAST;
}
static int recall_get_d()
@@ -481,12 +445,12 @@ casting_result convey_recall()
int d = recall_get_d();
int f = recall_get_f();
recall_player(d, f);
- return CAST_OBVIOUS;
+ return CAST;
}
else if (c_ptr->m_idx > 0)
{
swap_position(y, x);
- return CAST_OBVIOUS;
+ return CAST;
}
else if (!c_ptr->o_idxs.empty())
{
@@ -497,13 +461,13 @@ casting_result convey_recall()
// Fetch item
if (get_level_s(RECALL, 50) >= 15)
{
- fetch(5, 10 + get_level_s(RECALL, 150), FALSE);
+ fetch(5, 10 + get_level_s(RECALL, 150), false);
}
else
{
- fetch(5, 10 + get_level_s(RECALL, 150), TRUE);
+ fetch(5, 10 + get_level_s(RECALL, 150), true);
}
- return CAST_OBVIOUS;
+ return CAST;
}
else
{
@@ -511,30 +475,27 @@ casting_result convey_recall()
}
}
-const char *convey_recall_info()
+std::string convey_recall_info()
{
- static char buf[128];
int d = recall_get_d();
int f = recall_get_f();
- sprintf(buf,
- "dur %d+d%d weight " FMTs32b "lb",
- f, d, (1 + get_level_s(RECALL, 15)));
- return buf;
+ return fmt::format(
+ "dur {}+d{} weight {}lb",
+ f, d, 1 + get_level_s(RECALL, 15));
}
casting_result convey_probability_travel()
{
- return cast(set_prob_travel(randint(20) + get_level_s(PROBABILITY_TRAVEL, 60)));
+ set_prob_travel(randint(20) + get_level_s(PROBABILITY_TRAVEL, 60));
+ return CAST;
}
-const char *convey_probability_travel_info()
+std::string convey_probability_travel_info()
{
- static char buf[128];
- sprintf(buf,
- "dur " FMTs32b "+d20",
+ return fmt::format(
+ "dur {}+d20",
get_level_s(PROBABILITY_TRAVEL, 60));
- return buf;
}
casting_result demonology_demon_blade()
@@ -553,26 +514,25 @@ casting_result demonology_demon_blade()
rad = 1;
}
- return cast(set_project(randint(20) + get_level_s(DEMON_BLADE, 80),
- type,
- 4 + get_level_s(DEMON_BLADE, 40),
- rad,
- PROJECT_STOP | PROJECT_KILL));
+ set_project(
+ randint(20) + get_level_s(DEMON_BLADE, 80),
+ type,
+ 4 + get_level_s(DEMON_BLADE, 40),
+ rad,
+ PROJECT_STOP | PROJECT_KILL);
+ return CAST;
}
-const char *demonology_demon_blade_info()
+std::string demonology_demon_blade_info()
{
- static char buf[128];
- sprintf(buf,
- "dur " FMTs32b "+d20 dam " FMTs32b "/blow",
- (get_level_s(DEMON_BLADE, 80)),
- (4 + get_level_s(DEMON_BLADE, 40)));
- return buf;
+ return fmt::format(
+ "dur {}+d20 dam {}/blow",
+ get_level_s(DEMON_BLADE, 80),
+ 4 + get_level_s(DEMON_BLADE, 40));
}
casting_result demonology_demon_madness()
{
- casting_result result = NO_CAST;
int dir, type, y1, x1, y2, x2;
if (!get_aim_dir(&dir))
@@ -611,30 +571,28 @@ casting_result demonology_demon_madness()
y2 = p_ptr->py - (y1 - p_ptr->py);
x2 = p_ptr->px - (x1 - p_ptr->px);
- result = cplus(result,
- project(0, 1 + get_level(DEMON_MADNESS, 4),
- y1, x1,
- 20 + get_level_s(DEMON_MADNESS, 200),
- type,
- PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL));
- result = cplus(result,
- project(0, 1 + get_level(DEMON_MADNESS, 4),
- y2, x2,
- 20 + get_level_s(DEMON_MADNESS, 200),
- type,
- PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL));
+ project(
+ 0, 1 + get_level(DEMON_MADNESS, 4),
+ y1, x1,
+ 20 + get_level_s(DEMON_MADNESS, 200),
+ type,
+ PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL);
+ project(
+ 0, 1 + get_level(DEMON_MADNESS, 4),
+ y2, x2,
+ 20 + get_level_s(DEMON_MADNESS, 200),
+ type,
+ PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL);
- return result;
+ return CAST;
}
-const char *demonology_demon_madness_info()
+std::string demonology_demon_madness_info()
{
- static char buf[128];
- sprintf(buf,
- "dam " FMTs32b " rad " FMTs32b,
- (20 + get_level_s(DEMON_MADNESS, 200)),
- (1 + get_level(DEMON_MADNESS, 4)));
- return buf;
+ return fmt::format(
+ "dam {} rad {}",
+ 20 + get_level_s(DEMON_MADNESS, 200),
+ 1 + get_level(DEMON_MADNESS, 4));
}
casting_result demonology_demon_field()
@@ -646,41 +604,41 @@ casting_result demonology_demon_field()
return NO_CAST;
}
- return cast(fire_cloud(GF_NEXUS,
- dir,
- 20 + get_level_s(DEMON_FIELD, 70),
- 7,
- 30 + get_level_s(DEMON_FIELD, 100)));
+ fire_cloud(
+ GF_NEXUS,
+ dir,
+ 20 + get_level_s(DEMON_FIELD, 70),
+ 7,
+ 30 + get_level_s(DEMON_FIELD, 100));
+ return CAST;
}
-const char *demonology_demon_field_info()
+std::string demonology_demon_field_info()
{
- static char buf[128];
- sprintf(buf,
- "dam " FMTs32b " dur " FMTs32b,
- (20 + get_level_s(DEMON_FIELD, 70)),
- (30 + get_level_s(DEMON_FIELD, 100)));
- return buf;
+ return fmt::format(
+ "dam {} dur {}",
+ 20 + get_level_s(DEMON_FIELD, 70),
+ 30 + get_level_s(DEMON_FIELD, 100));
}
casting_result demonology_doom_shield()
{
- return cast(set_shield(randint(10) + 20 + get_level_s(DOOM_SHIELD, 100),
- -300 + get_level_s(DOOM_SHIELD, 100),
- SHIELD_COUNTER,
- 1 + get_level_s(DOOM_SHIELD, 14),
- 10 + get_level_s(DOOM_SHIELD, 15)));
+ set_shield(
+ randint(10) + 20 + get_level_s(DOOM_SHIELD, 100),
+ -300 + get_level_s(DOOM_SHIELD, 100),
+ SHIELD_COUNTER,
+ 1 + get_level_s(DOOM_SHIELD, 14),
+ 10 + get_level_s(DOOM_SHIELD, 15));
+ return CAST;
}
-const char *demonology_doom_shield_info()
+std::string demonology_doom_shield_info()
{
- static char buf[128];
- sprintf(buf,
- "dur " FMTs32b "+d10 dam " FMTs32b "d" FMTs32b,
- (20 + get_level_s(DOOM_SHIELD, 100)),
- (1 + get_level_s(DOOM_SHIELD, 14)),
- (10 + get_level_s(DOOM_SHIELD, 15)));
- return buf;
+ return fmt::format(
+ "dur {}+d10 dam {}d{}",
+ 20 + get_level_s(DOOM_SHIELD, 100),
+ 1 + get_level_s(DOOM_SHIELD, 14),
+ 10 + get_level_s(DOOM_SHIELD, 15));
}
casting_result demonology_unholy_word()
@@ -732,7 +690,7 @@ casting_result demonology_unholy_word()
delete_monster_idx(c_ptr->m_idx);
}
- return CAST_OBVIOUS;
+ return CAST;
}
else
{
@@ -740,27 +698,24 @@ casting_result demonology_unholy_word()
}
}
-const char *demonology_unholy_word_info()
+std::string demonology_unholy_word_info()
{
- static char buf[128];
- sprintf(buf,
- "heal mhp%% of " FMTs32b "%%",
- (30 + get_level(UNHOLY_WORD, 50)));
- return buf;
+ return fmt::format(
+ "heal mhp% of {}%",
+ 30 + get_level(UNHOLY_WORD, 50));
}
casting_result demonology_demon_cloak()
{
- return cast(set_tim_reflect(randint(5) + 5 + get_level(DEMON_CLOAK, 15)));
+ set_tim_reflect(randint(5) + 5 + get_level(DEMON_CLOAK, 15));
+ return CAST;
}
-const char *demonology_demon_cloak_info()
+std::string demonology_demon_cloak_info()
{
- static char buf[128];
- sprintf(buf,
- "dur " FMTs32b "+d5",
- (5 + get_level(DEMON_CLOAK, 15)));
- return buf;
+ return fmt::format(
+ "dur {}+d5",
+ 5 + get_level(DEMON_CLOAK, 15));
}
casting_result demonology_summon_demon()
@@ -783,24 +738,19 @@ casting_result demonology_summon_demon()
type = SUMMON_HI_DEMON;
}
- if (summon_specific_friendly(p_ptr->py, p_ptr->px, level, type, TRUE))
- {
- return CAST_OBVIOUS;
- }
- else
+ if (!summon_specific_friendly(p_ptr->py, p_ptr->px, level, type, true))
{
msg_print("Something blocks your summoning!");
- return CAST_HIDDEN;
}
+
+ return CAST;
}
-const char *demonology_summon_demon_info()
+std::string demonology_summon_demon_info()
{
- static char buf[128];
- sprintf(buf,
- "level " FMTs32b,
- (5 + get_level_s(DEMON_SUMMON, 100)));
- return buf;
+ return fmt::format(
+ "level {}",
+ 5 + get_level_s(DEMON_SUMMON, 100));
}
casting_result demonology_discharge_minion()
@@ -835,9 +785,10 @@ casting_result demonology_discharge_minion()
}
/* We use project instead of fire_ball because we must tell it exactly where to land */
- return cast(project(0, 2, y, x, dam,
- GF_GRAVITY,
- PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL));
+ project(0, 2, y, x, dam,
+ GF_GRAVITY,
+ PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL);
+ return CAST;
}
else
{
@@ -845,14 +796,12 @@ casting_result demonology_discharge_minion()
}
}
-const char *demonology_discharge_minion_info()
+std::string demonology_discharge_minion_info()
{
- static char buf[128];
- sprintf(buf,
- "dam " FMTs32b "%% max " FMTs32b,
- (20 + get_level(DISCHARGE_MINION, 60)),
- (100 + get_level(DISCHARGE_MINION, 500)));
- return buf;
+ return fmt::format(
+ "dam {}% max {}",
+ 20 + get_level(DISCHARGE_MINION, 60),
+ 100 + get_level(DISCHARGE_MINION, 500));
}
casting_result demonology_control_demon()
@@ -863,55 +812,15 @@ casting_result demonology_control_demon()
return NO_CAST;
}
- return cast(fire_ball(GF_CONTROL_DEMON, dir, 50 + get_level_s(CONTROL_DEMON, 250), 0));
-}
-
-const char *demonology_control_demon_info()
-{
- static char buf[128];
- sprintf(buf,
- "power " FMTs32b,
- (50 + get_level_s(CONTROL_DEMON, 250)));
- return buf;
-}
-
-casting_result divination_greater_identify()
-{
- identify_fully();
- return CAST_OBVIOUS;
-}
-
-casting_result divination_identify()
-{
- if (get_level_s(IDENTIFY, 50) >= 17)
- {
- casting_result result = NO_CAST;
- result = cplus(result, identify_pack());
- return result;
- }
- else if (ident_spell())
- {
- return CAST_OBVIOUS;
- }
- else
- {
- return NO_CAST;
- }
+ fire_ball(GF_CONTROL_DEMON, dir, 50 + get_level_s(CONTROL_DEMON, 250), 0);
+ return CAST;
}
-const char *divination_identify_info()
+std::string demonology_control_demon_info()
{
- static char buf[128];
-
- if (get_level_s(IDENTIFY, 50) >= 27)
- {
- sprintf(buf, "rad " FMTs32b, get_level_s(IDENTIFY, 3));
- return buf;
- }
- else
- {
- return "";
- }
+ return fmt::format(
+ "power {}",
+ 50 + get_level_s(CONTROL_DEMON, 250));
}
casting_result divination_vision()
@@ -924,128 +833,109 @@ casting_result divination_vision()
{
map_area();
}
- return CAST_OBVIOUS;
+ return CAST;
}
casting_result divination_sense_hidden()
{
- casting_result result = NO_CAST;
- result = cplus(result, set_tim_invis(10 + randint(20) + get_level_s(SENSEHIDDEN, 40)));
-
- return result;
+ set_tim_invis(10 + randint(20) + get_level_s(SENSEHIDDEN, 40));
+ return CAST;
}
-const char *divination_sense_hidden_info()
+std::string divination_sense_hidden_info()
{
- static char buf[128];
-
if (get_level_s(SENSEHIDDEN, 50) >= 15)
{
- sprintf(buf,
- "rad " FMTs32b " dur " FMTs32b "+d20",
- (15 + get_level_s(SENSEHIDDEN, 40)),
- (10 + get_level_s(SENSEHIDDEN, 40)));
+ return fmt::format(
+ "rad {} dur {}+d20",
+ 15 + get_level_s(SENSEHIDDEN, 40),
+ 10 + get_level_s(SENSEHIDDEN, 40));
}
else
{
- sprintf(buf,
- "rad " FMTs32b,
- (15 + get_level_s(SENSEHIDDEN, 40)));
+ return fmt::format(
+ "rad {}",
+ 15 + get_level_s(SENSEHIDDEN, 40));
}
-
- return buf;
}
casting_result divination_reveal_ways()
{
- casting_result result = NO_CAST;
- result = cplus(result, detect_doors(10 + get_level(REVEALWAYS, 40)));
- result = cplus(result, detect_stairs(10 + get_level(REVEALWAYS, 40)));
- return result;
+ detect_doors(10 + get_level(REVEALWAYS, 40));
+ detect_stairs(10 + get_level(REVEALWAYS, 40));
+ return CAST;
}
-const char *divination_reveal_ways_info()
+std::string divination_reveal_ways_info()
{
- static char buf[128];
- sprintf(buf,
- "rad " FMTs32b,
- (10 + get_level_s(REVEALWAYS, 40)));
- return buf;
+ return fmt::format(
+ "rad {}",
+ 10 + get_level_s(REVEALWAYS, 40));
}
casting_result divination_sense_monsters()
{
- casting_result result = NO_CAST;
-
- result = cplus(result, detect_monsters_normal(10 + get_level(SENSEMONSTERS, 40)));
+ detect_monsters_normal(10 + get_level(SENSEMONSTERS, 40));
if (get_level_s(SENSEMONSTERS, 50) >= 30)
{
- result = cplus(result, set_tim_esp(10 + randint(10) + get_level_s(SENSEMONSTERS, 20)));
+ set_tim_esp(10 + randint(10) + get_level_s(SENSEMONSTERS, 20));
}
- return result;
+ return CAST;
}
-const char *divination_sense_monsters_info()
+std::string divination_sense_monsters_info()
{
- static char buf[128];
-
if (get_level_s(SENSEMONSTERS, 50) >= 30)
{
- sprintf(buf,
- "rad " FMTs32b " dur " FMTs32b "+d10",
- (10 + get_level_s(SENSEMONSTERS, 40)),
- (10 + get_level_s(SENSEMONSTERS, 20)));
+ return fmt::format(
+ "rad {} dur {}+d10",
+ 10 + get_level_s(SENSEMONSTERS, 40),
+ 10 + get_level_s(SENSEMONSTERS, 20));
}
else
{
- sprintf(buf,
- "rad " FMTs32b,
- (10 + get_level_s(SENSEMONSTERS, 40)));
+ return fmt::format(
+ "rad {}",
+ 10 + get_level_s(SENSEMONSTERS, 40));
}
-
- return buf;
}
casting_result earth_stone_skin()
{
- int type;
-
- type = 0;
+ int type = 0;
if (get_level_s(STONESKIN, 50) >= 25)
{
type = SHIELD_COUNTER;
}
- return cast(set_shield(randint(10) + 10 + get_level_s(STONESKIN, 100),
- 10 + get_level_s(STONESKIN, 50),
- type,
- 2 + get_level_s(STONESKIN, 5),
- 3 + get_level_s(STONESKIN, 5)));
+ set_shield(
+ randint(10) + 10 + get_level_s(STONESKIN, 100),
+ 10 + get_level_s(STONESKIN, 50),
+ type,
+ 2 + get_level_s(STONESKIN, 5),
+ 3 + get_level_s(STONESKIN, 5));
+ return CAST;
}
-const char *earth_stone_skin_info()
+std::string earth_stone_skin_info()
{
- static char buf[128];
-
if (get_level_s(STONESKIN, 50) >= 25)
{
- sprintf(buf,
- "dam " FMTs32b "d" FMTs32b " dur " FMTs32b "+d10 AC " FMTs32b,
- (2 + get_level_s(STONESKIN, 5)),
- (3 + get_level_s(STONESKIN, 5)),
- (10 + get_level_s(STONESKIN, 100)),
- (10 + get_level_s(STONESKIN, 50)));
+ return fmt::format(
+ "dam {}d{} dur {}+d10 AC {}",
+ 2 + get_level_s(STONESKIN, 5),
+ 3 + get_level_s(STONESKIN, 5),
+ 10 + get_level_s(STONESKIN, 100),
+ 10 + get_level_s(STONESKIN, 50));
}
else
{
- sprintf(buf,
- "dur " FMTs32b "+d10 AC " FMTs32b,
- (10 + get_level_s(STONESKIN, 100)),
- (10 + get_level_s(STONESKIN, 50)));
+ return fmt::format(
+ "dur {}+d10 AC {}",
+ 10 + get_level_s(STONESKIN, 100),
+ 10 + get_level_s(STONESKIN, 50));
}
-
- return buf;
}
casting_result earth_dig()
@@ -1056,7 +946,8 @@ casting_result earth_dig()
return NO_CAST;
}
- return cast(wall_to_mud(dir));
+ wall_to_mud(dir);
+ return CAST;
}
casting_result earth_stone_prison()
@@ -1077,44 +968,41 @@ casting_result earth_stone_prison()
}
wall_stone(y, x);
- return CAST_OBVIOUS;
+ return CAST;
}
casting_result earth_strike()
{
- int dir, dmg;
-
+ int dir;
if (!get_aim_dir(&dir))
{
return NO_CAST;
}
- dmg = 50 + get_level_s(STRIKE, 50);
+ int dmg = 50 + get_level_s(STRIKE, 50);
if (get_level_s(STRIKE, 50) >= 12)
{
- return cast(fire_ball(GF_FORCE, dir, dmg, 1));
+ fire_ball(GF_FORCE, dir, dmg, 1);
}
else
{
- return cast(fire_ball(GF_FORCE, dir, dmg, 0));
+ fire_ball(GF_FORCE, dir, dmg, 0);
}
+ return CAST;
}
-const char *earth_strike_info()
+std::string earth_strike_info()
{
- static char buf[128];
int dmg = 50 + get_level_s(STRIKE, 50);
if (get_level_s(STRIKE, 50) >= 12)
{
- sprintf(buf, "dam %d rad 1", dmg);
+ return fmt::format("dam {} rad 1", dmg);
}
else
{
- sprintf(buf, "dam %d", dmg);
+ return fmt::format("dam {}", dmg);
}
-
- return buf;
}
casting_result earth_shake()
@@ -1133,142 +1021,113 @@ casting_result earth_shake()
x = p_ptr->px;
y = p_ptr->py;
}
+
earthquake(y, x, 4 + get_level_s(SHAKE, 10));
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *earth_shake_info()
+std::string earth_shake_info()
{
- static char buf[128];
- sprintf(buf, "rad " FMTs32b, (4 + get_level_s(SHAKE, 10)));
- return buf;
+ return fmt::format("rad {}", 4 + get_level_s(SHAKE, 10));
}
casting_result eru_see_the_music()
{
- casting_result result = NO_CAST;
-
- result = cplus(result, set_tim_invis(randint(20) + 10 + get_level_s(ERU_SEE, 100)));
+ set_tim_invis(randint(20) + 10 + get_level_s(ERU_SEE, 100));
if (get_level_s(ERU_SEE, 50) >= 30)
{
wiz_lite_extra();
- result = CAST_OBVIOUS;
}
else if (get_level_s(ERU_SEE, 50) >= 10)
{
map_area();
- result = CAST_OBVIOUS;
}
if (get_level_s(ERU_SEE, 50) >= 20)
{
- result = cplus(result, set_blind(0));
+ set_blind(0);
}
- return result;
+ return CAST;
}
-const char *eru_see_the_music_info()
+std::string eru_see_the_music_info()
{
- static char buf[128];
- sprintf(buf,
- "dur " FMTs32b "+d20",
- (10 + get_level_s(ERU_SEE, 100)));
- return buf;
+ return fmt::format(
+ "dur {}+d20",
+ 10 + get_level_s(ERU_SEE, 100));
}
casting_result eru_listen_to_the_music()
{
- casting_result result = NO_CAST;
-
if (get_level_s(ERU_LISTEN, 50) >= 30)
{
- result = cplus(result, ident_all());
- result = cplus(result, identify_pack());
+ ident_all();
+ identify_pack();
}
else if (get_level_s(ERU_LISTEN, 50) >= 14)
{
- result = cplus(result, identify_pack());
+ identify_pack();
}
else
{
- result = cplus(result, ident_spell());
+ ident_spell();
}
- return result;
-}
-
-casting_result eru_know_the_music()
-{
- if (get_level_s(ERU_UNDERSTAND, 50) >= 10)
- {
- identify_pack_fully();
- return CAST_OBVIOUS;
- }
- else
- {
- return cast(identify_fully());
- }
+ return CAST;
}
casting_result eru_lay_of_protection()
{
- return cast(fire_ball(GF_MAKE_GLYPH, 0, 1, 1 + get_level(ERU_PROT, 2)));
+ fire_ball(GF_MAKE_GLYPH, 0, 1, 1 + get_level(ERU_PROT, 2));
+ return CAST;
}
-const char *eru_lay_of_protection_info()
+std::string eru_lay_of_protection_info()
{
- static char buf[128];
- sprintf(buf,
- "rad " FMTs32b,
- (1 + get_level(ERU_PROT, 2)));
- return buf;
+ return fmt::format(
+ "rad {}",
+ 1 + get_level(ERU_PROT, 2));
}
casting_result fire_globe_of_light()
{
- casting_result result = NO_CAST;
-
if (get_level_s(GLOBELIGHT, 50) >= 3)
{
- result = cplus(result, lite_area(10, 4));
+ lite_area(10, 4);
}
else
{
lite_room(p_ptr->py, p_ptr->px);
- result = CAST_OBVIOUS;
}
if (get_level_s(GLOBELIGHT, 50) >= 15)
{
- result = cplus(result,
- fire_ball(GF_LITE,
- 0,
- 10 + get_level_s(GLOBELIGHT, 100),
- 5 + get_level_s(GLOBELIGHT, 6)));
+ fire_ball(
+ GF_LITE,
+ 0,
+ 10 + get_level_s(GLOBELIGHT, 100),
+ 5 + get_level_s(GLOBELIGHT, 6));
p_ptr->update |= PU_VIEW;
}
- return result;
+ return CAST;
}
-const char *fire_globe_of_light_info()
+std::string fire_globe_of_light_info()
{
- static char buf[128];
-
if (get_level_s(GLOBELIGHT, 50) >= 15)
{
- sprintf(buf, "dam " FMTs32b " rad " FMTs32b,
+ return fmt::format(
+ "dam {} rad {}",
(10 + get_level_s(GLOBELIGHT, 100)),
(5 + get_level_s(GLOBELIGHT, 6)));
}
else
{
- buf[0] = '\0';
+ return "";
}
-
- return buf;
}
casting_result fire_fireflash()
@@ -1286,19 +1145,20 @@ casting_result fire_fireflash()
return NO_CAST;
}
- return cast(fire_ball(type, dir,
- 20 + get_level_s(FIREFLASH, 500),
- 2 + get_level_s(FIREFLASH, 5)));
+ fire_ball(
+ type,
+ dir,
+ 20 + get_level_s(FIREFLASH, 500),
+ 2 + get_level_s(FIREFLASH, 5));
+ return CAST;
}
-const char *fire_fireflash_info()
+std::string fire_fireflash_info()
{
- static char buf[128];
- sprintf(buf,
- "dam " FMTs32b " rad " FMTs32b,
- (20 + get_level_s(FIREFLASH, 500)),
- (2 + get_level_s(FIREFLASH, 5)));
- return buf;
+ return fmt::format(
+ "dam {} rad {}",
+ 20 + get_level_s(FIREFLASH, 500),
+ 2 + get_level_s(FIREFLASH, 5));
}
casting_result fire_fiery_shield()
@@ -1309,22 +1169,22 @@ casting_result fire_fiery_shield()
type = SHIELD_GREAT_FIRE;
}
- return cast(set_shield(randint(20) + 10 + get_level_s(FIERYAURA, 70),
- 10,
- type,
- 5 + get_level_s(FIERYAURA, 10),
- 5 + get_level_s(FIERYAURA, 7)));
+ set_shield(
+ randint(20) + 10 + get_level_s(FIERYAURA, 70),
+ 10,
+ type,
+ 5 + get_level_s(FIERYAURA, 10),
+ 5 + get_level_s(FIERYAURA, 7));
+ return CAST;
}
-const char *fire_fiery_shield_info()
+std::string fire_fiery_shield_info()
{
- static char buf[128];
- sprintf(buf,
- "dam " FMTs32b "d" FMTs32b " dur " FMTs32b "+d20",
- (5 + get_level_s(FIERYAURA, 15)),
- (5 + get_level_s(FIERYAURA, 7)),
- (10 + get_level_s(FIERYAURA, 70)));
- return buf;
+ return fmt::format(
+ "dam {}d{} dur {}+d20",
+ 5 + get_level_s(FIERYAURA, 15),
+ 5 + get_level_s(FIERYAURA, 7),
+ 10 + get_level_s(FIERYAURA, 70));
}
casting_result fire_firewall()
@@ -1344,17 +1204,15 @@ casting_result fire_firewall()
fire_wall(type, dir,
40 + get_level_s(FIREWALL, 150),
10 + get_level_s(FIREWALL, 14));
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *fire_firewall_info()
+std::string fire_firewall_info()
{
- static char buf[128];
- sprintf(buf,
- "dam " FMTs32b " dur " FMTs32b,
- (40 + get_level_s(FIREWALL, 150)),
- (10 + get_level_s(FIREWALL, 14)));
- return buf;
+ return fmt::format(
+ "dam {} dur {}",
+ 40 + get_level_s(FIREWALL, 150),
+ 10 + get_level_s(FIREWALL, 14));
}
object_filter_t const &item_tester_hook_fire_golem()
@@ -1396,9 +1254,9 @@ casting_result fire_golem()
/* Summon it */
int r_idx = get_fire_golem();
- m_allow_special[r_idx] = TRUE;
- int m_idx = place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_FRIEND);
- m_allow_special[r_idx] = FALSE;
+ m_allow_special[r_idx] = true;
+ int m_idx = place_monster_one(y, x, r_idx, 0, false, MSTATUS_FRIEND);
+ m_allow_special[r_idx] = false;
/* level it */
if (m_idx != 0)
@@ -1408,16 +1266,14 @@ casting_result fire_golem()
m_list[m_idx].mflag |= MFLAG_CONTROL;
}
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *fire_golem_info()
+std::string fire_golem_info()
{
- static char buf[128];
- sprintf(buf,
- "golem level " FMTs32b,
- (7 + get_level_s(FIREGOLEM, 70)));
- return buf;
+ return fmt::format(
+ "golem level {}",
+ 7 + get_level_s(FIREGOLEM, 70));
}
casting_result geomancy_call_the_elements()
@@ -1437,22 +1293,20 @@ casting_result geomancy_call_the_elements()
1,
1 + get_level(CALL_THE_ELEMENTS, 5));
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *geomancy_call_the_elements_info()
+std::string geomancy_call_the_elements_info()
{
- static char buf[128];
- sprintf(buf,
- "rad " FMTs32b,
- (1 + get_level(CALL_THE_ELEMENTS, 5)));
- return buf;
+ return fmt::format(
+ "rad {}",
+ 1 + get_level(CALL_THE_ELEMENTS, 5));
}
casting_result geomancy_channel_elements()
{
channel_the_elements(p_ptr->py, p_ptr->px, get_level_s(CHANNEL_ELEMENTS, 50));
- return CAST_OBVIOUS;
+ return CAST;
}
typedef struct eff_type eff_type;
@@ -1494,7 +1348,7 @@ static u32b dir_to_eff_flags(int dir)
case 8: return EFF_DIR8;
case 9: return EFF_DIR9;
default:
- assert(FALSE);
+ assert(false);
}
/* Default */
return 0;
@@ -1556,7 +1410,7 @@ casting_result geomancy_elemental_wave()
6 + get_level_s(ELEMENTAL_WAVE, 20),
EFF_WAVE + EFF_LAST + dir_flag);
- return CAST_OBVIOUS;
+ return CAST;
}
}
@@ -1602,21 +1456,19 @@ casting_result geomancy_vaporize()
1 + get_level_s(VAPORIZE, 4),
10 + get_level_s(VAPORIZE, 20));
- return CAST_OBVIOUS;
+ return CAST;
}
}
-const char *geomancy_vaporize_info()
+std::string geomancy_vaporize_info()
{
- static char buf[128];
- sprintf(buf,
- "rad " FMTs32b " dur " FMTs32b,
- (1 + get_level_s(VAPORIZE, 4)),
- (10 + get_level_s(VAPORIZE, 20)));
- return buf;
+ return fmt::format(
+ "rad {} dur {}",
+ 1 + get_level_s(VAPORIZE, 4),
+ 10 + get_level_s(VAPORIZE, 20));
}
-bool_ geomancy_vaporize_depends()
+bool geomancy_vaporize_depends()
{
return get_skill(SKILL_AIR) >= 4;
}
@@ -1633,19 +1485,17 @@ casting_result geomancy_geolysis()
msg_print("Elements recombine before you, laying down an open path.");
geomancy_dig(p_ptr->py, p_ptr->px, dir, 5 + get_level_s(GEOLYSIS, 12));
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *geomancy_geolysis_info()
+std::string geomancy_geolysis_info()
{
- static char buf[128];
- sprintf(buf,
- "length " FMTs32b,
- (5 + get_level_s(GEOLYSIS, 12)));
- return buf;
+ return fmt::format(
+ "length {}",
+ 5 + get_level_s(GEOLYSIS, 12));
}
-bool_ geomancy_geolysis_depends()
+bool geomancy_geolysis_depends()
{
return get_skill(SKILL_EARTH) >= 7;
}
@@ -1663,19 +1513,17 @@ casting_result geomancy_dripping_tread()
msg_print("You stop dripping raw elemental energies.");
}
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *geomancy_dripping_tread_info()
+std::string geomancy_dripping_tread_info()
{
- static char buf[128];
- sprintf(buf,
- "dur " FMTs32b "+d15 movs",
- (10 + get_level_s(DRIPPING_TREAD, 50)));
- return buf;
+ return fmt::format(
+ "dur {}+d15 movs",
+ 10 + get_level_s(DRIPPING_TREAD, 50));
}
-bool_ geomancy_dripping_tread_depends()
+bool geomancy_dripping_tread_depends()
{
return get_skill(SKILL_WATER) >= 10;
}
@@ -1693,10 +1541,10 @@ casting_result geomancy_grow_barrier()
}
fire_ball(GF_ELEMENTAL_WALL, dir, 1, 1);
- return CAST_OBVIOUS;
+ return CAST;
}
-bool_ geomancy_grow_barrier_depends()
+bool geomancy_grow_barrier_depends()
{
return get_skill(SKILL_EARTH) >= 12;
}
@@ -1705,7 +1553,7 @@ typedef struct geo_summon geo_summon;
struct geo_summon {
s16b feat;
s16b skill_idx;
- cptr *summon_names;
+ const char **summon_names;
};
geo_summon *geomancy_find_summon(geo_summon summons[], int feat)
@@ -1722,7 +1570,7 @@ geo_summon *geomancy_find_summon(geo_summon summons[], int feat)
return NULL;
}
-int geomancy_count_elements(cptr *elements)
+int geomancy_count_elements(const char **elements)
{
int i;
for (i = 0; elements[i] != NULL; i++)
@@ -1736,25 +1584,25 @@ casting_result geomancy_elemental_minion()
int dir = 0;
int x = 0, y = 0;
geo_summon *summon_ptr = NULL;
- cptr earth_summons[] = {
+ const char *earth_summons[] = {
"Earth elemental",
"Xorn",
"Xaren",
NULL
};
- cptr air_summons[] = {
+ const char *air_summons[] = {
"Air elemental",
"Ancient blue dragon",
"Great Storm Wyrm",
"Sky Drake",
NULL
};
- cptr fire_summons[] = {
+ const char *fire_summons[] = {
"Fire elemental",
"Ancient red dragon",
NULL
};
- cptr water_summons[] = {
+ const char *water_summons[] = {
"Water elemental",
"Water troll",
"Water demon",
@@ -1804,7 +1652,7 @@ casting_result geomancy_elemental_minion()
}
else
{
- cptr *names = summon_ptr->summon_names;
+ const char **names = summon_ptr->summon_names;
int max = get_skill_scale(summon_ptr->skill_idx,
geomancy_count_elements(names));
int r_idx = test_monster_name(names[rand_int(max)]);
@@ -1812,7 +1660,7 @@ casting_result geomancy_elemental_minion()
/* Summon it */
find_position(y, x, &my, &mx);
- m_idx = place_monster_one(my, mx, r_idx, 0, FALSE, MSTATUS_FRIEND);
+ m_idx = place_monster_one(my, mx, r_idx, 0, false, MSTATUS_FRIEND);
/* Level it */
if (m_idx)
@@ -1822,17 +1670,15 @@ casting_result geomancy_elemental_minion()
cave_set_feat(y, x, FEAT_FLOOR);
- return CAST_OBVIOUS;
+ return CAST;
}
}
-const char *geomancy_elemental_minion_info()
+std::string geomancy_elemental_minion_info()
{
- static char buf[128];
- sprintf(buf,
- "min level " FMTs32b,
- (10 + get_level_s(ELEMENTAL_MINION, 120)));
- return buf;
+ return fmt::format(
+ "min level {}",
+ 10 + get_level_s(ELEMENTAL_MINION, 120));
}
static void get_manathrust_dam(s16b *num, s16b *sides)
@@ -1853,42 +1699,31 @@ casting_result mana_manathrust()
}
get_manathrust_dam(&num, &sides);
- return cast(fire_bolt(GF_MANA, dir, damroll(num, sides)));
+ fire_bolt(GF_MANA, dir, damroll(num, sides));
+ return CAST;
}
-const char *mana_manathrust_info()
+std::string mana_manathrust_info()
{
s16b num = 0;
s16b sides = 0;
- static char buf[128];
get_manathrust_dam(&num, &sides);
- sprintf(buf,
- "dam " FMTs16b "d" FMTs16b,
- num,
- sides);
- return buf;
+ return fmt::format("dam {}d{}", num, sides);
}
casting_result mana_remove_curses()
{
- casting_result result = NO_CAST;
+ auto fn = (get_level_s(DELCURSES, 50) >= 20)
+ ? remove_all_curse
+ : remove_curse;
- if (get_level_s(DELCURSES, 50) >= 20)
- {
- result = cplus(result, remove_all_curse());
- }
- else
- {
- result = cplus(result, remove_curse());
- }
-
- if (result == CAST_OBVIOUS)
+ if (fn())
{
msg_print("The curse is broken!");
}
- return result;
+ return CAST;
}
casting_result mana_elemental_shield()
@@ -1897,34 +1732,36 @@ casting_result mana_elemental_shield()
if (p_ptr->oppose_fire == 0)
{
- res = cplus(res, set_oppose_fire(randint(10) + 15 + get_level_s(RESISTS, 50)));
+ set_oppose_fire(randint(10) + 15 + get_level_s(RESISTS, 50));
+ res = CAST;
}
if (p_ptr->oppose_cold == 0)
{
- res = cplus(res, set_oppose_cold(randint(10) + 15 + get_level_s(RESISTS, 50)));
+ set_oppose_cold(randint(10) + 15 + get_level_s(RESISTS, 50));
+ res = CAST;
}
if (p_ptr->oppose_elec == 0)
{
- res = cplus(res, set_oppose_elec(randint(10) + 15 + get_level_s(RESISTS, 50)));
+ set_oppose_elec(randint(10) + 15 + get_level_s(RESISTS, 50));
+ res = CAST;
}
if (p_ptr->oppose_acid == 0)
{
- res = cplus(res, set_oppose_acid(randint(10) + 15 + get_level_s(RESISTS, 50)));
+ set_oppose_acid(randint(10) + 15 + get_level_s(RESISTS, 50));
+ res = CAST;
}
return res;
}
-const char *mana_elemental_shield_info()
+std::string mana_elemental_shield_info()
{
- static char buf[128];
- sprintf(buf,
- "dur " FMTs32b "+d10",
- (15 + get_level_s(RESISTS, 50)));
- return buf;
+ return fmt::format(
+ "dur {}+d10",
+ 15 + get_level_s(RESISTS, 50));
}
casting_result mana_disruption_shield()
@@ -1933,32 +1770,31 @@ casting_result mana_disruption_shield()
{
if (p_ptr->invuln == 0)
{
- return cast(set_invuln(randint(5) + 3 + get_level_s(MANASHIELD, 10)));
+ set_invuln(randint(5) + 3 + get_level_s(MANASHIELD, 10));
+ return CAST;
}
}
else if (p_ptr->disrupt_shield == 0)
{
- return cast(set_disrupt_shield(randint(5) + 3 + get_level_s(MANASHIELD, 10)));
+ set_disrupt_shield(randint(5) + 3 + get_level_s(MANASHIELD, 10));
+ return CAST;
}
return NO_CAST;
}
-const char *mana_disruption_shield_info()
+std::string mana_disruption_shield_info()
{
- static char buf[128];
- sprintf(buf,
- "dur " FMTs32b "+d5",
- (3 + get_level_s(MANASHIELD, 10)));
- return buf;
+ return fmt::format(
+ "dur {}+d5",
+ 3 + get_level_s(MANASHIELD, 10));
}
casting_result manwe_wind_shield()
{
- casting_result res = NO_CAST;
s32b dur = get_level_s(MANWE_SHIELD, 50) + 10 + randint(20);
- res = cplus(res, set_protevil(dur));
+ set_protevil(dur);
if (get_level_s(MANWE_SHIELD, 50) >= 10)
{
@@ -1968,39 +1804,35 @@ casting_result manwe_wind_shield()
type = SHIELD_COUNTER;
}
- res = cplus(res,
- set_shield(dur,
- get_level_s(MANWE_SHIELD, 30),
- type,
- 1 + get_level_s(MANWE_SHIELD, 2),
- 1 + get_level_s(MANWE_SHIELD, 6)));
+ set_shield(
+ dur,
+ get_level_s(MANWE_SHIELD, 30),
+ type,
+ 1 + get_level_s(MANWE_SHIELD, 2),
+ 1 + get_level_s(MANWE_SHIELD, 6));
}
- return res;
+ return CAST;
}
-const char *manwe_wind_shield_info()
+std::string manwe_wind_shield_info()
{
- static char buf[128];
-
- sprintf(buf,
- "dur " FMTs32b "+d20",
- (get_level_s(MANWE_SHIELD, 50) + 10));
+ auto buf = fmt::format(
+ "dur {}+d20",
+ get_level_s(MANWE_SHIELD, 50) + 10);
if (get_level_s(MANWE_SHIELD, 50) >= 10)
{
- char tmp[128];
- sprintf(tmp, " AC " FMTs32b, get_level_s(MANWE_SHIELD, 30));
- strcat(buf, tmp);
+ buf += fmt::format(
+ " AC {}", get_level_s(MANWE_SHIELD, 30));
}
if (get_level_s(MANWE_SHIELD, 50) >= 20)
{
- char tmp[128];
- sprintf(tmp, " dam " FMTs32b "d" FMTs32b,
- (1 + get_level_s(MANWE_SHIELD, 2)),
- (1 + get_level_s(MANWE_SHIELD, 6)));
- strcat(buf, tmp);
+ buf += fmt::format(
+ " dam {}d{}",
+ 1 + get_level_s(MANWE_SHIELD, 2),
+ 1 + get_level_s(MANWE_SHIELD, 6));
}
return buf;
@@ -2011,52 +1843,49 @@ casting_result manwe_avatar()
s16b mimic_idx = resolve_mimic_name("Maia");
assert(mimic_idx >= 0);
- return cast(set_mimic(get_level_s(MANWE_AVATAR, 20) + randint(10),
- mimic_idx,
- p_ptr->lev));
+ set_mimic(
+ get_level_s(MANWE_AVATAR, 20) + randint(10),
+ mimic_idx,
+ p_ptr->lev);
+ return CAST;
}
-const char *manwe_avatar_info()
+std::string manwe_avatar_info()
{
- static char buf[128];
- sprintf(buf,
- "dur " FMTs32b "+d10",
+ return fmt::format(
+ "dur {}+d10",
get_level_s(MANWE_AVATAR, 20));
- return buf;
}
casting_result manwe_blessing()
{
- casting_result res = NO_CAST;
s32b dur = get_level_s(MANWE_BLESS, 70) + 30 + randint(40);
- res = cplus(res, set_blessed(dur));
- res = cplus(res, set_afraid(0));
- res = cplus(res, set_lite(0));
+ set_blessed(dur);
+ set_afraid(0);
+ set_lite(0);
if (get_level_s(MANWE_BLESS, 50) >= 10)
{
- res = cplus(res, set_hero(dur));
+ set_hero(dur);
}
if (get_level_s(MANWE_BLESS, 50) >= 20)
{
- res = cplus(res, set_shero(dur));
+ set_shero(dur);
}
if (get_level_s(MANWE_BLESS, 50) >= 30)
{
- res = cplus(res, set_holy(dur));
+ set_holy(dur);
}
- return res;
+ return CAST;
}
-const char *manwe_blessing_info()
+std::string manwe_blessing_info()
{
- static char buf[128];
- sprintf(buf,
- "dur " FMTs32b "+d40",
+ return fmt::format(
+ "dur {}+d40",
get_level_s(MANWE_BLESS, 70) + 30);
- return buf;
}
casting_result manwe_call()
@@ -2068,24 +1897,24 @@ casting_result manwe_call()
r_idx = test_monster_name("Great eagle");
assert(r_idx >= 1);
- m_idx = place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_FRIEND);
+ m_idx = place_monster_one(y, x, r_idx, 0, false, MSTATUS_FRIEND);
if (m_idx > 0)
{
monster_set_level(m_idx, 20 + get_level(MANWE_CALL, 70));
- return CAST_OBVIOUS;
+ return CAST;
+ }
+ else
+ {
+ return NO_CAST;
}
-
- return NO_CAST;
}
-const char *manwe_call_info()
+std::string manwe_call_info()
{
- static char buf[128];
- sprintf(buf,
- "level " FMTs32b,
+ return fmt::format(
+ "level {}",
get_level_s(MANWE_CALL, 70) + 20);
- return buf;
}
void do_melkor_curse(int m_idx)
@@ -2194,25 +2023,25 @@ casting_result melkor_curse()
else
{
do_melkor_curse(target_who);
- return CAST_OBVIOUS;
+ return CAST;
}
}
casting_result melkor_corpse_explosion()
{
- return cast(fire_ball(GF_CORPSE_EXPL,
- 0,
- 20 + get_level_s(MELKOR_CORPSE_EXPLOSION, 70),
- 2 + get_level_s(MELKOR_CORPSE_EXPLOSION, 5)));
+ fire_ball(
+ GF_CORPSE_EXPL,
+ 0,
+ 20 + get_level_s(MELKOR_CORPSE_EXPLOSION, 70),
+ 2 + get_level_s(MELKOR_CORPSE_EXPLOSION, 5));
+ return CAST;
}
-const char *melkor_corpse_explosion_info()
+std::string melkor_corpse_explosion_info()
{
- static char buf[128];
- sprintf(buf,
- "dam " FMTs32b "%%",
+ return fmt::format(
+ "dam {}%",
20 + get_level_s(MELKOR_CORPSE_EXPLOSION, 70));
- return buf;
}
casting_result melkor_mind_steal()
@@ -2252,31 +2081,28 @@ casting_result melkor_mind_steal()
}
msg_print(buf);
- return CAST_OBVIOUS;
+ return CAST;
}
}
-const char *melkor_mind_steal_info()
+std::string melkor_mind_steal_info()
{
- static char buf[128];
- sprintf(buf,
- "chance 1d(mlvl)<" FMTs32b,
+ return fmt::format(
+ "chance 1d(mlvl)<{}",
get_level_s(MELKOR_MIND_STEAL, 50));
- return buf;
}
casting_result meta_recharge()
{
- return cast(recharge(60 + get_level_s(RECHARGE, 140)));
+ recharge(60 + get_level_s(RECHARGE, 140));
+ return CAST;
}
-const char *meta_recharge_info()
+std::string meta_recharge_info()
{
- static char buf[128];
- sprintf(buf,
- "power " FMTs32b,
+ return fmt::format(
+ "power {}",
60 + get_level_s(RECHARGE, 140));
- return buf;
}
static int get_spellbinder_max()
@@ -2297,7 +2123,7 @@ casting_result meta_spellbinder()
{
struct trigger {
int idx;
- cptr desc;
+ const char *desc;
};
struct trigger triggers[] = {
{ SPELLBINDER_HP75, "75% HP", },
@@ -2362,14 +2188,16 @@ casting_result meta_spellbinder()
{
spellbinder->trigger = 0;
spellbinder->spell_idxs.clear();
- return CAST_OBVIOUS;
+ return CAST;
}
else
{
if (spell_type_skill_level(spell_at(s)) > 7 + get_level_s(SPELLBINDER, 35))
{
- msg_format("You are only allowed spells with a base level of " FMTs32b ".", (7 + get_level_s(SPELLBINDER, 35)));
- return CAST_OBVIOUS;
+ msg_print(fmt::format(
+ "You are only allowed spells with a base level of {}.",
+ 7 + get_level_s(SPELLBINDER, 35)));
+ return CAST;
}
}
@@ -2379,53 +2207,49 @@ casting_result meta_spellbinder()
p_ptr->energy = p_ptr->energy - 3100;
msg_print("Spellbinder ready.");
- return CAST_OBVIOUS;
+ return CAST;
}
}
-const char *meta_spellbinder_info()
+std::string meta_spellbinder_info()
{
- static char buf[128];
- sprintf(buf,
- "number %d max level " FMTs32b,
+ return fmt::format(
+ "number {} max level {}",
get_spellbinder_max(),
- (7 + get_level_s(SPELLBINDER, 35)));
- return buf;
+ 7 + get_level_s(SPELLBINDER, 35));
}
casting_result meta_disperse_magic()
{
- casting_result res = NO_CAST;
-
- res = cplus(res, set_blind(0));
- res = cplus(res, set_lite(0));
+ set_blind(0);
+ set_lite(0);
if (get_level_s(DISPERSEMAGIC, 50) >= 5)
{
- res = cplus(res, set_confused(0));
- res = cplus(res, set_image(0));
+ set_confused(0);
+ set_image(0);
}
if (get_level_s(DISPERSEMAGIC, 50) >= 10)
{
- res = cplus(res, set_slow(0));
- res = cplus(res, set_fast(0, 0));
- res = cplus(res, set_light_speed(0));
+ set_slow(0);
+ set_fast(0, 0);
+ set_light_speed(0);
}
if (get_level_s(DISPERSEMAGIC, 50) >= 15)
{
- res = cplus(res, set_stun(0));
- res = cplus(res, set_cut(0));
+ set_stun(0);
+ set_cut(0);
}
if (get_level_s(DISPERSEMAGIC, 50) >= 20)
{
- res = cplus(res, set_hero(0));
- res = cplus(res, set_shero(0));
- res = cplus(res, set_blessed(0));
- res = cplus(res, set_shield(0, 0, 0, 0, 0));
- res = cplus(res, set_afraid(0));
- res = cplus(res, set_parasite(0, 0));
- res = cplus(res, set_mimic(0, 0, 0));
+ set_hero(0);
+ set_shero(0);
+ set_blessed(0);
+ set_shield(0, 0, 0, 0, 0);
+ set_afraid(0);
+ set_parasite(0, 0);
+ set_mimic(0, 0, 0);
}
- return res;
+ return CAST;
}
casting_result meta_tracker()
@@ -2439,7 +2263,7 @@ casting_result meta_tracker()
{
teleport_player_to(last_teleportation_y, last_teleportation_x);
}
- return CAST_OBVIOUS;
+ return CAST;
}
static void stop_inertia_controlled_spell()
@@ -2486,7 +2310,9 @@ casting_result meta_inertia_control()
if (difficulty > get_level_s(INERTIA_CONTROL, 10))
{
- msg_format("This spell inertia flow(" FMTs32b ") is too strong to be controlled by your current spell.", difficulty);
+ msg_print(fmt::format(
+ "This spell inertia flow({}) is too strong to be controlled by your current spell.",
+ difficulty));
stop_inertia_controlled_spell();
return NO_CAST;
}
@@ -2496,16 +2322,14 @@ casting_result meta_inertia_control()
TIMER_INERTIA_CONTROL->enable();
p_ptr->update |= PU_MANA;
msg_format("Inertia flow controlling spell %s.", spell_type_name(spell_at(s)));
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *meta_inertia_control_info()
+std::string meta_inertia_control_info()
{
- static char buf[128];
- sprintf(buf,
- "level " FMTs32b,
+ return fmt::format(
+ "level {}",
get_level_s(INERTIA_CONTROL, 10));
- return buf;
}
void meta_inertia_control_timer_callback()
@@ -2522,7 +2346,7 @@ void meta_inertia_control_timer_callback()
else if ((p_ptr->inertia_controlled_spell != -1) &&
(!p_ptr->wild_mode))
{
- lua_cast_school_spell(p_ptr->inertia_controlled_spell, TRUE);
+ lua_cast_school_spell(p_ptr->inertia_controlled_spell, true);
}
}
@@ -2550,7 +2374,7 @@ casting_result mind_charm()
if (level >= 35)
{
- return cast(project_hack(GF_CHARM, pwr));
+ project_hack(GF_CHARM, pwr);
}
else
{
@@ -2562,22 +2386,23 @@ casting_result mind_charm()
if (level >= 15)
{
- return cast(fire_ball(GF_CHARM, dir, pwr, 3));
+ fire_ball(GF_CHARM, dir, pwr, 3);
}
else
{
- return cast(fire_bolt(GF_CHARM, dir, pwr));
+ fire_bolt(GF_CHARM, dir, pwr);
}
+
}
+
+ return CAST;
}
-const char *mind_charm_info()
+std::string mind_charm_info()
{
- static char buf[128];
- sprintf(buf,
- "power %d",
+ return fmt::format(
+ "power {}",
mind_charm_power());
- return buf;
}
static int mind_confuse_power()
@@ -2592,7 +2417,7 @@ casting_result mind_confuse()
if (level >= 35)
{
- return cast(project_hack(GF_OLD_CONF, pwr));
+ project_hack(GF_OLD_CONF, pwr);
}
else
{
@@ -2604,22 +2429,22 @@ casting_result mind_confuse()
if (level >= 15)
{
- return cast(fire_ball(GF_OLD_CONF, dir, pwr, 3));
+ fire_ball(GF_OLD_CONF, dir, pwr, 3);
}
else
{
- return cast(fire_bolt(GF_OLD_CONF, dir, pwr));
+ fire_bolt(GF_OLD_CONF, dir, pwr);
}
}
+
+ return CAST;
}
-const char *mind_confuse_info()
+std::string mind_confuse_info()
{
- static char buf[128];
- sprintf(buf,
- "power %d",
+ return fmt::format(
+ "power {}",
mind_confuse_power());
- return buf;
}
static int mind_armor_of_fear_base_duration()
@@ -2639,22 +2464,22 @@ static int mind_armor_of_fear_power_dice()
casting_result mind_armor_of_fear()
{
- return cast(set_shield(randint(10) + mind_armor_of_fear_base_duration(),
- 10,
- SHIELD_FEAR,
- mind_armor_of_fear_power_sides(),
- mind_armor_of_fear_power_dice()));
+ set_shield(
+ randint(10) + mind_armor_of_fear_base_duration(),
+ 10,
+ SHIELD_FEAR,
+ mind_armor_of_fear_power_sides(),
+ mind_armor_of_fear_power_dice());
+ return CAST;
}
-const char *mind_armor_of_fear_info()
+std::string mind_armor_of_fear_info()
{
- static char buf[128];
- sprintf(buf,
- "dur %d+d10 power %dd%d",
+ return fmt::format(
+ "dur {}+d10 power {}d{}",
mind_armor_of_fear_base_duration(),
mind_armor_of_fear_power_sides(),
mind_armor_of_fear_power_dice());
- return buf;
}
static int mind_stun_power()
@@ -2673,21 +2498,20 @@ casting_result mind_stun()
if (get_level_s(STUN, 50) >= 20)
{
- return cast(fire_ball(GF_STUN, dir, mind_stun_power(), 3));
+ fire_ball(GF_STUN, dir, mind_stun_power(), 3);
}
else
{
- return cast(fire_bolt(GF_STUN, dir, mind_stun_power()));
+ fire_bolt(GF_STUN, dir, mind_stun_power());
}
+ return CAST;
}
-const char *mind_stun_info()
+std::string mind_stun_info()
{
- static char buf[128];
- sprintf(buf,
- "power %d",
+ return fmt::format(
+ "power {}",
mind_stun_power());
- return buf;
}
casting_result tempo_magelock()
@@ -2721,15 +2545,15 @@ casting_result tempo_magelock()
x = p_ptr->px;
}
cave_set_feat(y, x, 3);
- return CAST_OBVIOUS;
} else {
int dir;
if (!get_aim_dir(&dir))
{
return NO_CAST;
}
- return cast(wizard_lock(dir));
+ wizard_lock(dir);
}
+ return CAST;
}
static s32b tempo_slow_monster_power()
@@ -2750,28 +2574,27 @@ casting_result tempo_slow_monster()
pwr = tempo_slow_monster_power();
if (get_level_s(SLOWMONSTER, 50) >= 20)
{
- return cast(fire_ball(GF_OLD_SLOW, dir, pwr, 1));
+ fire_ball(GF_OLD_SLOW, dir, pwr, 1);
}
else
{
- return cast(fire_bolt(GF_OLD_SLOW, dir, pwr));
+ fire_bolt(GF_OLD_SLOW, dir, pwr);
}
+ return CAST;
}
-const char *tempo_slow_monster_info()
+std::string tempo_slow_monster_info()
{
- static char buf[128];
s32b pwr = tempo_slow_monster_power();
if (get_level_s(SLOWMONSTER, 50) >= 20)
{
- sprintf(buf, "power " FMTs32b " rad 1", pwr);
+ return fmt::format("power {} rad 1", pwr);
}
else
{
- sprintf(buf, "power " FMTs32b, pwr);
+ return fmt::format("power {}", pwr);
}
- return buf;
}
static s32b tempo_essence_of_speed_base_duration()
@@ -2788,20 +2611,20 @@ casting_result tempo_essence_of_speed()
{
if (p_ptr->fast == 0)
{
- return cast(set_fast(randint(10) + tempo_essence_of_speed_base_duration(),
- tempo_essence_of_speed_bonus()));
+ set_fast(
+ randint(10) + tempo_essence_of_speed_base_duration(),
+ tempo_essence_of_speed_bonus());
+ return CAST;
}
return NO_CAST;
}
-const char *tempo_essence_of_speed_info()
+std::string tempo_essence_of_speed_info()
{
- static char buf[128];
- sprintf(buf,
- "dur " FMTs32b "+d10 speed " FMTs32b,
+ return fmt::format(
+ "dur {}+d10 speed {}",
tempo_essence_of_speed_base_duration(),
tempo_essence_of_speed_bonus());
- return buf;
}
static s32b tempo_banishment_power()
@@ -2811,50 +2634,43 @@ static s32b tempo_banishment_power()
casting_result tempo_banishment()
{
- casting_result result = NO_CAST;
s32b pwr = tempo_banishment_power();
- result = cplus(result, project_hack(GF_AWAY_ALL, pwr));
+ project_hack(GF_AWAY_ALL, pwr);
if (get_level_s(BANISHMENT, 50) >= 15)
{
- result = cplus(result,
- project_hack(GF_STASIS, 20 + get_level_s(BANISHMENT, 120)));
+ project_hack(GF_STASIS, 20 + get_level_s(BANISHMENT, 120));
}
- return result;
+ return CAST;
}
-const char *tempo_banishment_info()
+std::string tempo_banishment_info()
{
- static char buf[128];
- sprintf(buf,
- "power " FMTs32b,
+ return fmt::format(
+ "power {}",
tempo_banishment_power());
- return buf;
}
casting_result tulkas_divine_aim()
{
- casting_result result = NO_CAST;
s32b dur = get_level_s(TULKAS_AIM, 50) + randint(10);
- result = cplus(result, set_strike(dur));
+ set_strike(dur);
if (get_level_s(TULKAS_AIM, 50) >= 20)
{
- result = cplus(result, set_tim_deadly(dur));
+ set_tim_deadly(dur);
}
- return result;
+ return CAST;
}
-const char *tulkas_divine_aim_info()
+std::string tulkas_divine_aim_info()
{
- static char buf[128];
- sprintf(buf,
- "dur " FMTs32b "+d10",
+ return fmt::format(
+ "dur {}+d10",
get_level_s(TULKAS_AIM, 50));
- return buf;
}
casting_result tulkas_wave_of_power()
@@ -2866,21 +2682,21 @@ casting_result tulkas_wave_of_power()
return NO_CAST;
}
- return cast(fire_bolt(GF_ATTACK, dir, get_level_s(TULKAS_WAVE, p_ptr->num_blow)));
+ fire_bolt(GF_ATTACK, dir, get_level_s(TULKAS_WAVE, p_ptr->num_blow));
+ return CAST;
}
-const char *tulkas_wave_of_power_info()
+std::string tulkas_wave_of_power_info()
{
- static char buf[128];
- sprintf(buf,
- "blows " FMTs32b,
+ return fmt::format(
+ "blows {}",
get_level_s(TULKAS_WAVE, p_ptr->num_blow));
- return buf;
}
casting_result tulkas_whirlwind()
{
- return cast(fire_ball(GF_ATTACK, 0, 1, 1));
+ fire_ball(GF_ATTACK, 0, 1, 1);
+ return CAST;
}
/* Return the number of Udun/Melkor spells in a given book */
@@ -2940,8 +2756,6 @@ static object_filter_t const &udun_object_is_drainable()
casting_result udun_drain()
{
- auto const &k_info = game->edit_data.k_info;
-
/* Ask for an item */
int item;
if (!get_item(&item,
@@ -2961,10 +2775,8 @@ casting_result udun_drain()
case TV_STAFF:
case TV_WAND:
{
- auto k_ptr = &k_info[o_ptr->k_idx];
-
/* Generate mana */
- increase_mana(o_ptr->pval * k_ptr->level * o_ptr->number);
+ increase_mana(o_ptr->pval * o_ptr->k_ptr->level * o_ptr->number);
/* Destroy it */
inc_stack_size(item, -99);
@@ -2987,31 +2799,31 @@ casting_result udun_drain()
}
default:
- assert(FALSE);
+ assert(false);
}
- return CAST_OBVIOUS;
+ return CAST;
}
casting_result udun_genocide()
{
if (get_level_s(GENOCIDE, 50) < 10)
{
- genocide(TRUE);
+ genocide();
}
else
{
if (get_check("Genocide all monsters near you? "))
{
- mass_genocide(TRUE);
+ mass_genocide();
}
else
{
- genocide(TRUE);
+ genocide();
}
}
- return CAST_OBVIOUS;
+ return CAST;
}
static int udun_wraithform_base_duration()
@@ -3021,16 +2833,15 @@ static int udun_wraithform_base_duration()
casting_result udun_wraithform()
{
- return cast(set_shadow(randint(30) + udun_wraithform_base_duration()));
+ set_shadow(randint(30) + udun_wraithform_base_duration());
+ return CAST;
}
-const char *udun_wraithform_info()
+std::string udun_wraithform_info()
{
- static char buf[128];
- sprintf(buf,
- "dur %d+d30",
+ return fmt::format(
+ "dur {}+d30",
udun_wraithform_base_duration());
- return buf;
}
static int udun_flame_of_udun_base_duration()
@@ -3040,18 +2851,18 @@ static int udun_flame_of_udun_base_duration()
casting_result udun_flame_of_udun()
{
- return cast(set_mimic(randint(15) + udun_flame_of_udun_base_duration(),
- resolve_mimic_name("Balrog"),
- get_level_s(FLAMEOFUDUN, 50)));
+ set_mimic(
+ randint(15) + udun_flame_of_udun_base_duration(),
+ resolve_mimic_name("Balrog"),
+ get_level_s(FLAMEOFUDUN, 50));
+ return CAST;
}
-const char *udun_flame_of_udun_info()
+std::string udun_flame_of_udun_info()
{
- static char buf[128];
- sprintf(buf,
- "dur %d+d15",
+ return fmt::format(
+ "dur {}+d15",
udun_flame_of_udun_base_duration());
- return buf;
}
static int tidal_wave_damage()
@@ -3072,17 +2883,15 @@ casting_result water_tidal_wave()
0,
tidal_wave_duration(),
EFF_WAVE);
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *water_tidal_wave_info()
+std::string water_tidal_wave_info()
{
- static char buf[128];
- sprintf(buf,
- "dam %d dur %d",
+ return fmt::format(
+ "dam {} dur {}",
tidal_wave_damage(),
tidal_wave_duration());
- return buf;
}
static int water_ice_storm_damage()
@@ -3116,18 +2925,16 @@ casting_result water_ice_storm()
water_ice_storm_duration(),
EFF_STORM);
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *water_ice_storm_info()
+std::string water_ice_storm_info()
{
- static char buf[128];
- sprintf(buf,
- "dam %d rad %d dur %d",
+ return fmt::format(
+ "dam {} rad {} dur {}",
water_ice_storm_damage(),
water_ice_storm_radius(),
water_ice_storm_duration());
- return buf;
}
static int water_ent_potion_base_duration()
@@ -3149,18 +2956,16 @@ casting_result water_ent_potion()
set_hero(p_ptr->hero + randint(25) + water_ent_potion_base_duration());
}
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *water_ent_potion_info()
+std::string water_ent_potion_info()
{
if (get_level_s(ENTPOTION, 50) >= 12)
{
- static char buf[128];
- sprintf(buf,
- "dur %d+d25",
+ return fmt::format(
+ "dur {}+d25",
water_ent_potion_base_duration());
- return buf;
}
else
{
@@ -3190,18 +2995,16 @@ casting_result water_vapor()
water_vapor_damage(),
water_vapor_radius(),
water_vapor_duration());
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *water_vapor_info()
+std::string water_vapor_info()
{
- static char buf[128];
- sprintf(buf,
- "dam %d rad %d dur %d",
+ return fmt::format(
+ "dam {} rad {} dur {}",
water_vapor_damage(),
water_vapor_radius(),
water_vapor_duration());
- return buf;
}
static void get_geyser_damage(int *dice, int *sides)
@@ -3223,24 +3026,23 @@ casting_result water_geyser()
}
get_geyser_damage(&dice, &sides);
- return cast(fire_bolt_or_beam(2 * get_level_s(GEYSER, 85),
- GF_WATER,
- dir,
- damroll(dice, sides)));
+ fire_bolt_or_beam(
+ 2 * get_level_s(GEYSER, 85),
+ GF_WATER,
+ dir,
+ damroll(dice, sides));
+ return CAST;
}
-const char *water_geyser_info()
+std::string water_geyser_info()
{
- static char buf[128];
int dice, sides;
-
get_geyser_damage(&dice, &sides);
- sprintf(buf,
- "dam %dd%d",
+ return fmt::format(
+ "dam {}d{}",
dice,
sides);
- return buf;
}
static int charm_animal_power()
@@ -3262,20 +3064,20 @@ casting_result yavanna_charm_animal()
return NO_CAST;
}
- return cast(fire_ball(GF_CONTROL_ANIMAL,
- dir,
- charm_animal_power(),
- charm_animal_radius()));
+ fire_ball(
+ GF_CONTROL_ANIMAL,
+ dir,
+ charm_animal_power(),
+ charm_animal_radius());
+ return CAST;
}
-const char *yavanna_charm_animal_info()
+std::string yavanna_charm_animal_info()
{
- static char buf[128];
- sprintf(buf,
- "power %d rad %d",
+ return fmt::format(
+ "power {} rad {}",
charm_animal_power(),
charm_animal_radius());
- return buf;
}
static int yavanna_grow_grass_radius()
@@ -3286,16 +3088,14 @@ static int yavanna_grow_grass_radius()
casting_result yavanna_grow_grass()
{
grow_grass(yavanna_grow_grass_radius());
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *yavanna_grow_grass_info()
+std::string yavanna_grow_grass_info()
{
- static char buf[128];
- sprintf(buf,
- "rad %d",
+ return fmt::format(
+ "rad {}",
yavanna_grow_grass_radius());
- return buf;
}
static int tree_roots_duration()
@@ -3315,20 +3115,20 @@ static int tree_roots_damage()
casting_result yavanna_tree_roots()
{
- return cast(set_roots(tree_roots_duration(),
- tree_roots_ac(),
- tree_roots_damage()));
+ set_roots(
+ tree_roots_duration(),
+ tree_roots_ac(),
+ tree_roots_damage());
+ return CAST;
}
-const char *yavanna_tree_roots_info()
+std::string yavanna_tree_roots_info()
{
- static char buf[128];
- sprintf(buf,
- "dur %d AC %d dam %d",
+ return fmt::format(
+ "dur {} AC {} dam {}",
tree_roots_duration(),
tree_roots_ac(),
tree_roots_damage());
- return buf;
}
static int water_bite_base_duration()
@@ -3350,21 +3150,21 @@ casting_result yavanna_water_bite()
rad = 1;
}
- return cast(set_project(randint(30) + water_bite_base_duration(),
- GF_WATER,
- water_bite_damage(),
- rad,
- PROJECT_STOP | PROJECT_KILL));
+ set_project(
+ randint(30) + water_bite_base_duration(),
+ GF_WATER,
+ water_bite_damage(),
+ rad,
+ PROJECT_STOP | PROJECT_KILL);
+ return CAST;
}
-const char *yavanna_water_bite_info()
+std::string yavanna_water_bite_info()
{
- static char buf[128];
- sprintf(buf,
- "dur %d+d30 dam %d/blow",
+ return fmt::format(
+ "dur {}+d30 dam {}/blow",
water_bite_base_duration(),
water_bite_damage());
- return buf;
}
static int uproot_mlevel()
@@ -3398,7 +3198,7 @@ casting_result yavanna_uproot()
/* Summon it */
find_position(y, x, &y, &x);
- m_idx = place_monster_one(y, x, test_monster_name("Ent"), 0, FALSE, MSTATUS_FRIEND);
+ m_idx = place_monster_one(y, x, test_monster_name("Ent"), 0, false, MSTATUS_FRIEND);
/* level it */
if (m_idx != 0)
@@ -3407,7 +3207,7 @@ casting_result yavanna_uproot()
}
msg_print("The tree awakes!");
- return CAST_OBVIOUS;
+ return CAST;
}
else
{
@@ -3416,13 +3216,11 @@ casting_result yavanna_uproot()
}
}
-const char *yavanna_uproot_info()
+std::string yavanna_uproot_info()
{
- static char buf[128];
- sprintf(buf,
- "lev %d",
+ return fmt::format(
+ "lev {}",
uproot_mlevel());
- return buf;
}
static int nature_grow_trees_radius()
@@ -3433,16 +3231,14 @@ static int nature_grow_trees_radius()
casting_result nature_grow_trees()
{
grow_trees(nature_grow_trees_radius());
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *nature_grow_trees_info()
+std::string nature_grow_trees_info()
{
- static char buf[128];
- sprintf(buf,
- "rad %d",
+ return fmt::format(
+ "rad {}",
nature_grow_trees_radius());
- return buf;
}
static int nature_healing_percentage()
@@ -3457,44 +3253,44 @@ static int nature_healing_hp()
casting_result nature_healing()
{
- return cast(hp_player(nature_healing_hp()));
+ hp_player(nature_healing_hp());
+ return CAST;
}
-const char *nature_healing_info()
+std::string nature_healing_info()
{
- static char buf[128];
- sprintf(buf,
- "heal %d%% = %dhp",
+ return fmt::format(
+ "heal {}% = {}hp",
nature_healing_percentage(),
nature_healing_hp());
- return buf;
}
casting_result nature_recovery()
{
- casting_result result = NO_CAST;
+ set_poisoned(p_ptr->poisoned / 2);
- result = cplus(result, set_poisoned(p_ptr->poisoned / 2));
if (get_level_s(RECOVERY, 50) >= 5)
{
- result = cplus(result, set_poisoned(0));
- result = cplus(result, set_cut(0));
+ set_poisoned(0);
+ set_cut(0);
}
+
if (get_level_s(RECOVERY, 50) >= 10)
{
- result = cplus(result, do_res_stat(A_STR, TRUE));
- result = cplus(result, do_res_stat(A_CON, TRUE));
- result = cplus(result, do_res_stat(A_DEX, TRUE));
- result = cplus(result, do_res_stat(A_WIS, TRUE));
- result = cplus(result, do_res_stat(A_INT, TRUE));
- result = cplus(result, do_res_stat(A_CHR, TRUE));
+ do_res_stat(A_STR, true);
+ do_res_stat(A_CON, true);
+ do_res_stat(A_DEX, true);
+ do_res_stat(A_WIS, true);
+ do_res_stat(A_INT, true);
+ do_res_stat(A_CHR, true);
}
+
if (get_level_s(RECOVERY, 50) >= 15)
{
- result = cplus(result, restore_level());
+ restore_level();
}
- return result;
+ return CAST;
}
static int regeneration_base_duration()
@@ -3511,20 +3307,20 @@ casting_result nature_regeneration()
{
if (p_ptr->tim_regen == 0)
{
- return cast(set_tim_regen(randint(10) + regeneration_base_duration(),
- regeneration_power()));
+ set_tim_regen(
+ randint(10) + regeneration_base_duration(),
+ regeneration_power());
+ return CAST;
}
return NO_CAST;
}
-const char *nature_regeneration_info()
+std::string nature_regeneration_info()
{
- static char buf[128];
- sprintf(buf,
- "dur %d+d10 power %d",
+ return fmt::format(
+ "dur {}+d10 power {}",
regeneration_base_duration(),
regeneration_power());
- return buf;
}
static int summon_animal_level()
@@ -3535,20 +3331,20 @@ static int summon_animal_level()
casting_result nature_summon_animal()
{
summon_specific_level = summon_animal_level();
- return cast(summon_specific_friendly(p_ptr->py,
- p_ptr->px,
- dun_level,
- SUMMON_ANIMAL,
- TRUE));
+ summon_specific_friendly(
+ p_ptr->py,
+ p_ptr->px,
+ dun_level,
+ SUMMON_ANIMAL,
+ true);
+ return CAST;
}
-const char *nature_summon_animal_info()
+std::string nature_summon_animal_info()
{
- static char buf[128];
- sprintf(buf,
- "level %d",
+ return fmt::format(
+ "level {}",
summon_animal_level());
- return buf;
}
casting_result nature_grow_athelas()
@@ -3556,11 +3352,10 @@ casting_result nature_grow_athelas()
if (p_ptr->black_breath)
{
msg_print("The hold of the Black Breath on you is broken!");
- p_ptr->black_breath = FALSE;
- return CAST_OBVIOUS;
+ p_ptr->black_breath = false;
}
- return CAST_HIDDEN;
+ return CAST;
}
static int device_heal_monster_hp()
@@ -3577,16 +3372,15 @@ casting_result device_heal_monster()
return NO_CAST;
}
- return cast(fire_ball(GF_OLD_HEAL, dir, device_heal_monster_hp(), 0));
+ fire_ball(GF_OLD_HEAL, dir, device_heal_monster_hp(), 0);
+ return CAST;
}
-const char *device_heal_monster_info()
+std::string device_heal_monster_info()
{
- static char buf[128];
- sprintf(buf,
- "heal %d",
+ return fmt::format(
+ "heal {}",
device_heal_monster_hp());
- return buf;
}
casting_result device_haste_monster()
@@ -3598,31 +3392,31 @@ casting_result device_haste_monster()
return NO_CAST;
}
- return cast(fire_ball(GF_OLD_SPEED, dir, 1, 0));
+ fire_ball(GF_OLD_SPEED, dir, 1, 0);
+ return CAST;
}
-const char *device_haste_monster_info()
+std::string device_haste_monster_info()
{
return "speed +10";
}
casting_result device_wish()
{
- make_wish();
- return CAST_OBVIOUS;
+ if (make_wish()) {
+ return CAST;
+ }
+ return NO_CAST;
}
casting_result device_summon_monster()
{
- casting_result result = NO_CAST;
- int i;
-
- for (i = 0; i < 4 + get_level_s(DEVICE_SUMMON, 30); i++)
+ for (int i = 0; i < 4 + get_level_s(DEVICE_SUMMON, 30); i++)
{
- result = cplus(result, summon_specific(p_ptr->py, p_ptr->px, dun_level, 0));
+ summon_specific(p_ptr->py, p_ptr->px, dun_level, 0);
}
- return result;
+ return CAST;
}
static int device_mana_pct()
@@ -3633,21 +3427,19 @@ static int device_mana_pct()
casting_result device_mana()
{
increase_mana((p_ptr->msp * device_mana_pct()) / 100);
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *device_mana_info()
+std::string device_mana_info()
{
- static char buf[128];
- sprintf(buf,
- "restore %d%%",
+ return fmt::format(
+ "restore {}%",
device_mana_pct());
- return buf;
}
casting_result device_nothing()
{
- return CAST_HIDDEN;
+ return CAST;
}
static int holy_fire_damage()
@@ -3657,16 +3449,15 @@ static int holy_fire_damage()
casting_result device_holy_fire()
{
- return cast(project_hack(GF_HOLY_FIRE, holy_fire_damage()));
+ project_hack(GF_HOLY_FIRE, holy_fire_damage());
+ return CAST;
}
-const char *device_holy_fire_info()
+std::string device_holy_fire_info()
{
- static char buf[128];
- sprintf(buf,
- "dam %d",
+ return fmt::format(
+ "dam {}",
holy_fire_damage());
- return buf;
}
casting_result device_thunderlords()
@@ -3684,7 +3475,7 @@ casting_result device_thunderlords()
{
msg_print("You cannot use it there.");
}
- return CAST_OBVIOUS;
+ return CAST;
}
case MODULE_THEME:
@@ -3698,11 +3489,11 @@ casting_result device_thunderlords()
{
msg_print("You cannot use it there.");
}
- return CAST_OBVIOUS;
+ return CAST;
}
default:
- assert(FALSE);
+ assert(false);
return NO_CAST;
}
}
@@ -3715,7 +3506,7 @@ void static start_lasting_spell(int spl)
casting_result music_stop_singing_spell()
{
start_lasting_spell(0);
- return CAST_OBVIOUS;
+ return CAST;
}
static int holding_pattern_power()
@@ -3732,16 +3523,14 @@ int music_holding_pattern_lasting()
casting_result music_holding_pattern_spell()
{
start_lasting_spell(MUSIC_HOLD);
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *music_holding_pattern_info()
+std::string music_holding_pattern_info()
{
- static char buf[128];
- sprintf(buf,
- "power %d",
+ return fmt::format(
+ "power {}",
holding_pattern_power());
- return buf;
}
static int illusion_pattern_power()
@@ -3758,16 +3547,14 @@ int music_illusion_pattern_lasting()
casting_result music_illusion_pattern_spell()
{
start_lasting_spell(MUSIC_CONF);
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *music_illusion_pattern_info()
+std::string music_illusion_pattern_info()
{
- static char buf[128];
- sprintf(buf,
- "power %d",
+ return fmt::format(
+ "power {}",
illusion_pattern_power());
- return buf;
}
static int stun_pattern_power()
@@ -3784,16 +3571,14 @@ int music_stun_pattern_lasting()
casting_result music_stun_pattern_spell()
{
start_lasting_spell(MUSIC_STUN);
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *music_stun_pattern_info()
+std::string music_stun_pattern_info()
{
- static char buf[128];
- sprintf(buf,
- "power %d",
+ return fmt::format(
+ "power {}",
stun_pattern_power());
- return buf;
}
int music_song_of_the_sun_lasting()
@@ -3805,7 +3590,7 @@ int music_song_of_the_sun_lasting()
casting_result music_song_of_the_sun_spell()
{
start_lasting_spell(MUSIC_LITE);
- return CAST_OBVIOUS;
+ return CAST;
}
int flow_of_life_hp()
@@ -3822,16 +3607,14 @@ int music_flow_of_life_lasting()
casting_result music_flow_of_life_spell()
{
start_lasting_spell(MUSIC_HEAL);
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *music_flow_of_life_info()
+std::string music_flow_of_life_info()
{
- static char buf[128];
- sprintf(buf,
- "heal %d/turn",
+ return fmt::format(
+ "heal {}/turn",
flow_of_life_hp());
- return buf;
}
int music_heroic_ballad_lasting()
@@ -3855,7 +3638,7 @@ int music_heroic_ballad_lasting()
casting_result music_heroic_ballad_spell()
{
start_lasting_spell(MUSIC_HERO);
- return CAST_OBVIOUS;
+ return CAST;
}
int music_hobbit_melodies_lasting()
@@ -3871,24 +3654,24 @@ int music_hobbit_melodies_lasting()
casting_result music_hobbit_melodies_spell()
{
start_lasting_spell(MUSIC_TIME);
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *music_hobbit_melodies_info()
+std::string music_hobbit_melodies_info()
{
- static char buf[128];
if (get_level_s(MUSIC_TIME, 50) >= 15)
{
- sprintf(buf, "AC " FMTs32b " speed " FMTs32b,
+ return fmt::format(
+ "AC {} speed {}",
10 + get_level_s(MUSIC_TIME, 50),
7 + get_level_s(MUSIC_TIME, 10));
}
else
{
- sprintf(buf, "AC " FMTs32b,
+ return fmt::format(
+ "AC {}",
10 + get_level_s(MUSIC_TIME, 50));
}
- return buf;
}
int music_clairaudience_lasting()
@@ -3900,18 +3683,16 @@ int music_clairaudience_lasting()
casting_result music_clairaudience_spell()
{
start_lasting_spell(MUSIC_MIND);
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *music_clairaudience_info()
+std::string music_clairaudience_info()
{
- static char buf[128];
-
if (get_level_s(MUSIC_MIND, 50) >= 10)
{
- sprintf(buf, "rad " FMTs32b,
+ return fmt::format(
+ "rad {}",
1 + get_level(MUSIC_MIND, 3));
- return buf;
}
else
{
@@ -3925,18 +3706,16 @@ casting_result music_blow_spell()
0,
damroll(2 + get_level(MUSIC_BLOW, 10), 4 + get_level(MUSIC_BLOW, 40)),
1 + get_level(MUSIC_BLOW, 12));
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *music_blow_info()
+std::string music_blow_info()
{
- static char buf[128];
- sprintf(buf,
- "dam " FMTs32b "d" FMTs32b " rad " FMTs32b,
+ return fmt::format(
+ "dam {}d{} rad {}",
2 + get_level(MUSIC_BLOW, 10),
4 + get_level(MUSIC_BLOW, 40),
1 + get_level(MUSIC_BLOW, 12));
- return buf;
}
casting_result music_gush_of_wind_spell()
@@ -3945,38 +3724,34 @@ casting_result music_gush_of_wind_spell()
0,
10 + get_level(MUSIC_BLOW, 40),
1 + get_level(MUSIC_BLOW, 12));
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *music_gush_of_wind_info()
+std::string music_gush_of_wind_info()
{
- static char buf[128];
- sprintf(buf,
- "dist " FMTs32b " rad " FMTs32b,
+ return fmt::format(
+ "dist {} rad {}",
10 + get_level(MUSIC_BLOW, 40),
1 + get_level(MUSIC_BLOW, 12));
- return buf;
}
casting_result music_horns_of_ylmir_spell()
{
earthquake(p_ptr->py, p_ptr->px, 2 + get_level_s(MUSIC_YLMIR, 10));
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *music_horns_of_ylmir_info()
+std::string music_horns_of_ylmir_info()
{
- static char buf[128];
- sprintf(buf,
- "rad " FMTs32b,
+ return fmt::format(
+ "rad {}",
2 + get_level_s(MUSIC_YLMIR, 10));
- return buf;
}
casting_result music_ambarkanta_spell()
{
alter_reality();
- return CAST_OBVIOUS;
+ return CAST;
}
casting_result aule_firebrand_spell()
@@ -3995,23 +3770,22 @@ casting_result aule_firebrand_spell()
rad = 1;
}
- return cast(set_project(level + randint(20),
- type,
- 4 + level,
- rad,
- PROJECT_STOP | PROJECT_KILL));
+ set_project(
+ level + randint(20),
+ type,
+ 4 + level,
+ rad,
+ PROJECT_STOP | PROJECT_KILL);
+ return CAST;
}
-const char *aule_firebrand_info()
+std::string aule_firebrand_info()
{
s32b level = get_level_s(AULE_FIREBRAND, 50);
- static char buf[128];
- sprintf(buf,
- "dur " FMTs32b "+d20 dam " FMTs32b "/blow",
+ return fmt::format("dur {}+d20 dam {}/blow",
level,
4 + level);
- return buf;
}
static object_filter_t const &aule_enchant_weapon_item_tester()
@@ -4065,16 +3839,14 @@ casting_result aule_enchant_weapon_spell()
o_ptr->to_d = o_ptr->to_d + num_d;
o_ptr->pval = o_ptr->pval + num_p;
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *aule_enchant_weapon_info()
+std::string aule_enchant_weapon_info()
{
- static char buf[128];
- sprintf(buf,
- "tries " FMTs32b,
+ return fmt::format(
+ "tries {}",
1 + get_level_s(AULE_ENCHANT_WEAPON, 50)/12);
- return buf;
}
static object_filter_t const &aule_enchant_armor_item_tester()
@@ -4134,16 +3906,14 @@ casting_result aule_enchant_armour_spell()
o_ptr->pval = o_ptr->pval + num_p;
o_ptr->to_a = o_ptr->to_a + num_a;
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *aule_enchant_armour_info()
+std::string aule_enchant_armour_info()
{
- static char buf[128];
- sprintf(buf,
- "tries " FMTs32b,
+ return fmt::format(
+ "tries {}",
1 + get_level_s(AULE_ENCHANT_ARMOUR, 50)/10);
- return buf;
}
casting_result aule_child_spell()
@@ -4153,12 +3923,12 @@ casting_result aule_child_spell()
find_position(p_ptr->py, p_ptr->px, &y, &x);
m_idx = place_monster_one(y, x, test_monster_name("Dwarven warrior"),
- 0, FALSE, MSTATUS_FRIEND);
+ 0, false, MSTATUS_FRIEND);
if (m_idx)
{
monster_set_level(m_idx, 20 + get_level(AULE_CHILD, 70));
- return CAST_OBVIOUS;
+ return CAST;
}
else
{
@@ -4166,13 +3936,11 @@ casting_result aule_child_spell()
}
}
-const char *aule_child_info()
+std::string aule_child_info()
{
- static char buf[128];
- sprintf(buf,
- "level " FMTs32b,
+ return fmt::format(
+ "level {}",
20 + get_level_s(AULE_CHILD, 70));
- return buf;
}
static int tears_of_luthien_hp()
@@ -4182,56 +3950,49 @@ static int tears_of_luthien_hp()
casting_result mandos_tears_of_luthien_spell()
{
- casting_result result = NO_CAST;
+ hp_player(tears_of_luthien_hp());
+ set_stun(0);
+ set_cut(0);
+ set_afraid(0);
- result = cplus(result, hp_player(tears_of_luthien_hp()));
- result = cplus(result, set_stun(0));
- result = cplus(result, set_cut(0));
- result = cplus(result, set_afraid(0));
-
- return result;
+ return CAST;
}
-const char *mandos_tears_of_luthien_info()
+std::string mandos_tears_of_luthien_info()
{
- static char buf[128];
- sprintf(buf,
- "heals %d",
+ return fmt::format(
+ "heals {}",
tears_of_luthien_hp());
- return buf;
}
casting_result mandos_spirit_of_the_feanturi_spell()
{
- casting_result result = NO_CAST;
s32b level = get_level_s(MANDOS_SPIRIT_FEANTURI, 50);
- result = cplus(result, set_afraid(0));
- result = cplus(result, set_confused(0));
+ set_afraid(0);
+ set_confused(0);
if (level >= 20)
{
- result = cplus(result, do_res_stat(A_WIS, TRUE));
- result = cplus(result, do_res_stat(A_INT, TRUE));
+ do_res_stat(A_WIS, true);
+ do_res_stat(A_INT, true);
}
if (level >= 30)
{
- result = cplus(result, set_image(0));
- result = cplus(result, heal_insanity(p_ptr->msane * level / 100));
+ set_image(0);
+ heal_insanity(p_ptr->msane * level / 100);
}
- return result;
+ return CAST;
}
-const char *mandos_spirit_of_the_feanturi_info()
+std::string mandos_spirit_of_the_feanturi_info()
{
- static char buf[128];
s32b level = get_level_s(MANDOS_SPIRIT_FEANTURI, 50) ;
if (level >= 20)
{
- sprintf(buf, "heals " FMTs32b "%%", level);
- return buf;
+ return fmt::format("heals {}%", level);
}
else
{
@@ -4246,16 +4007,15 @@ static int tale_of_doom_duration()
casting_result mandos_tale_of_doom_spell()
{
- return cast(set_tim_precognition(tale_of_doom_duration()));
+ set_tim_precognition(tale_of_doom_duration());
+ return CAST;
}
-const char *mandos_tale_of_doom_info()
+std::string mandos_tale_of_doom_info()
{
- static char buf[128];
- sprintf(buf,
- "dur %d",
+ return fmt::format(
+ "dur {}",
tale_of_doom_duration());
- return buf;
}
int call_to_the_halls_mlev()
@@ -4276,22 +4036,20 @@ casting_result mandos_call_to_the_halls_spell()
assert(r_idx >= 0);
find_position(p_ptr->py, p_ptr->px, &y, &x);
- m_idx = place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_FRIEND);
+ m_idx = place_monster_one(y, x, r_idx, 0, false, MSTATUS_FRIEND);
if (m_idx)
{
monster_set_level(m_idx, call_to_the_halls_mlev());
- return CAST_OBVIOUS;
+ return CAST;
}
return NO_CAST;
}
-const char *mandos_call_to_the_halls_info()
+std::string mandos_call_to_the_halls_info()
{
- static char buf[128];
- sprintf(buf,
- "level %d",
+ return fmt::format(
+ "level {}",
call_to_the_halls_mlev());
- return buf;
}
static void get_belegaer_damage(int *dice, int *sides)
@@ -4310,23 +4068,23 @@ casting_result ulmo_song_of_belegaer_spell()
}
get_belegaer_damage(&dice, &sides);
- return cast(fire_bolt_or_beam(2 * get_level_s(ULMO_BELEGAER, 85),
- GF_WATER,
- dir,
- damroll(dice, sides)));
+ fire_bolt_or_beam(
+ 2 * get_level_s(ULMO_BELEGAER, 85),
+ GF_WATER,
+ dir,
+ damroll(dice, sides));
+ return CAST;
}
-const char *ulmo_song_of_belegaer_info()
+std::string ulmo_song_of_belegaer_info()
{
- static char buf[128];
int dice, sides;
-
get_belegaer_damage(&dice, &sides);
- sprintf(buf,
- "dam %dd%d",
+
+ return fmt::format(
+ "dam {}d{}",
dice,
sides);
- return buf;
}
int draught_of_ulmonan_hp()
@@ -4336,39 +4094,36 @@ int draught_of_ulmonan_hp()
casting_result ulmo_draught_of_ulmonan_spell()
{
- casting_result result = NO_CAST;
s32b level = get_level_s(ULMO_DRAUGHT_ULMONAN, 50);
-
- result = cplus(result, hp_player(draught_of_ulmonan_hp()));
- result = cplus(result, set_poisoned(0));
- result = cplus(result, set_cut(0));
- result = cplus(result, set_stun(0));
- result = cplus(result, set_blind(0));
+ hp_player(draught_of_ulmonan_hp());
+
+ set_poisoned(0);
+ set_cut(0);
+ set_stun(0);
+ set_blind(0);
if (level >= 10)
{
- result = cplus(result, do_res_stat(A_STR, TRUE));
- result = cplus(result, do_res_stat(A_CON, TRUE));
- result = cplus(result, do_res_stat(A_DEX, TRUE));
+ do_res_stat(A_STR, true);
+ do_res_stat(A_CON, true);
+ do_res_stat(A_DEX, true);
}
if (level >= 20)
{
- result = cplus(result, set_parasite(0, 0));
- result = cplus(result, set_mimic(0, 0, 0));
+ set_parasite(0, 0);
+ set_mimic(0, 0, 0);
}
- return result;
+ return CAST;
}
-const char *ulmo_draught_of_ulmonan_info()
+std::string ulmo_draught_of_ulmonan_info()
{
- static char buf[128];
- sprintf(buf,
- "cure %d",
+ return fmt::format(
+ "cure {}",
draught_of_ulmonan_hp());
- return buf;
}
static int call_of_the_ulumuri_mlev()
@@ -4390,23 +4145,23 @@ casting_result ulmo_call_of_the_ulumuri_spell()
find_position(p_ptr->py, p_ptr->px, &y, &x);
- m_idx = place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_FRIEND);
+ m_idx = place_monster_one(y, x, r_idx, 0, false, MSTATUS_FRIEND);
if (m_idx)
{
monster_set_level(m_idx, call_of_the_ulumuri_mlev());
- return CAST_OBVIOUS;
+ return CAST;
+ }
+ else
+ {
+ return NO_CAST;
}
-
- return NO_CAST;
}
-const char *ulmo_call_of_the_ulumuri_info()
+std::string ulmo_call_of_the_ulumuri_info()
{
- static char buf[128];
- sprintf(buf,
- "level %d",
+ return fmt::format(
+ "level {}",
call_of_the_ulumuri_mlev());
- return buf;
}
static int wrath_of_ulmo_damage()
@@ -4437,17 +4192,15 @@ casting_result ulmo_wrath_of_ulmo_spell()
dir,
wrath_of_ulmo_damage(),
wrath_of_ulmo_duration());
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *ulmo_wrath_of_ulmo_info()
+std::string ulmo_wrath_of_ulmo_info()
{
- static char buf[128];
- sprintf(buf,
- "dam %d dur %d",
+ return fmt::format(
+ "dam {} dur {}",
wrath_of_ulmo_damage(),
wrath_of_ulmo_duration());
- return buf;
}
static int light_of_valinor_damage()
@@ -4462,40 +4215,35 @@ static int light_of_valinor_radius()
casting_result varda_light_of_valinor_spell()
{
- casting_result result = NO_CAST;
-
if (get_level_s(VARDA_LIGHT_VALINOR, 50) >= 3)
{
- result = cplus(result, lite_area(10, 4));
+ lite_area(10, 4);
}
else
{
lite_room(p_ptr->py, p_ptr->px);
- result = CAST_OBVIOUS;
}
if (get_level_s(VARDA_LIGHT_VALINOR, 50) >= 15)
{
- result = cplus(result,
- fire_ball(GF_LITE,
- 0,
- light_of_valinor_damage(),
- light_of_valinor_radius()));
+ fire_ball(
+ GF_LITE,
+ 0,
+ light_of_valinor_damage(),
+ light_of_valinor_radius());
}
- return result;
+ return CAST;
}
-const char *varda_light_of_valinor_info()
+std::string varda_light_of_valinor_info()
{
- static char buf[128];
if (get_level_s(VARDA_LIGHT_VALINOR, 50) >= 15)
{
- sprintf(buf,
- "dam %d rad %d",
+ return fmt::format(
+ "dam {} rad {}",
light_of_valinor_damage(),
light_of_valinor_radius());
- return buf;
}
else
{
@@ -4514,7 +4262,7 @@ casting_result varda_call_of_almaren_spell()
{
banish_evil(power);
}
- return CAST_OBVIOUS;
+ return CAST;
}
casting_result varda_evenstar_spell()
@@ -4525,7 +4273,7 @@ casting_result varda_evenstar_spell()
identify_pack();
}
- return CAST_OBVIOUS;
+ return CAST;
}
static int star_kindler_bursts()
@@ -4555,16 +4303,13 @@ casting_result varda_star_kindler_spell()
10);
}
- return CAST_OBVIOUS;
+ return CAST;
}
-const char *varda_star_kindler_info()
+std::string varda_star_kindler_info()
{
- static char buf[128];
- sprintf(buf,
- "dam %d bursts %d rad 10",
+ return fmt::format(
+ "dam {} bursts {} rad 10",
star_kindler_damage(),
star_kindler_bursts());
- return buf;
}
-
diff --git a/src/spells3.hpp b/src/spells3.hpp
index 12e6a78f..721ee115 100644
--- a/src/spells3.hpp
+++ b/src/spells3.hpp
@@ -1,9 +1,11 @@
#pragma once
#include "spell_type_fwd.hpp"
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "timer_type_fwd.hpp"
+#include <string>
+
extern s32b NOXIOUSCLOUD;
extern s32b AIRWINGS;
extern s32b INVISIBILITY;
@@ -12,17 +14,17 @@ extern s32b THUNDERSTORM;
extern s32b STERILIZE;
casting_result air_noxious_cloud();
-const char *air_noxious_cloud_info();
+std::string air_noxious_cloud_info();
casting_result air_wings_of_winds();
-const char *air_wings_of_winds_info();
+std::string air_wings_of_winds_info();
casting_result air_invisibility();
-const char *air_invisibility_info();
+std::string air_invisibility_info();
casting_result air_poison_blood();
-const char *air_poison_blood_info();
+std::string air_poison_blood_info();
casting_result air_thunderstorm();
-const char *air_thunderstorm_info();
+std::string air_thunderstorm_info();
casting_result air_sterilize();
-const char *air_sterilize_info();
+std::string air_sterilize_info();
extern s32b BLINK;
extern s32b DISARM;
@@ -32,14 +34,14 @@ extern s32b RECALL;
extern s32b PROBABILITY_TRAVEL;
casting_result convey_blink();
-const char *convey_blink_info();
+std::string convey_blink_info();
casting_result convey_teleport();
-const char *convey_teleport_info();
+std::string convey_teleport_info();
casting_result convey_teleport_away();
casting_result convey_recall();
-const char *convey_recall_info();
+std::string convey_recall_info();
casting_result convey_probability_travel();
-const char *convey_probability_travel_info();
+std::string convey_probability_travel_info();
extern s32b DEMON_BLADE;
extern s32b DEMON_MADNESS;
@@ -52,41 +54,36 @@ extern s32b DISCHARGE_MINION;
extern s32b CONTROL_DEMON;
casting_result demonology_demon_blade();
-const char *demonology_demon_blade_info();
+std::string demonology_demon_blade_info();
casting_result demonology_demon_madness();
-const char *demonology_demon_madness_info();
+std::string demonology_demon_madness_info();
casting_result demonology_demon_field();
-const char *demonology_demon_field_info();
+std::string demonology_demon_field_info();
casting_result demonology_doom_shield();
-const char *demonology_doom_shield_info();
+std::string demonology_doom_shield_info();
casting_result demonology_unholy_word();
-const char *demonology_unholy_word_info();
+std::string demonology_unholy_word_info();
casting_result demonology_demon_cloak();
-const char *demonology_demon_cloak_info();
+std::string demonology_demon_cloak_info();
casting_result demonology_summon_demon();
-const char *demonology_summon_demon_info();
+std::string demonology_summon_demon_info();
casting_result demonology_discharge_minion();
-const char *demonology_discharge_minion_info();
+std::string demonology_discharge_minion_info();
casting_result demonology_control_demon();
-const char *demonology_control_demon_info();
+std::string demonology_control_demon_info();
-extern s32b STARIDENTIFY;
-extern s32b IDENTIFY;
extern s32b VISION;
extern s32b SENSEHIDDEN;
extern s32b REVEALWAYS;
extern s32b SENSEMONSTERS;
-casting_result divination_greater_identify();
-casting_result divination_identify();
-const char *divination_identify_info();
casting_result divination_vision();
casting_result divination_sense_hidden();
-const char *divination_sense_hidden_info();
+std::string divination_sense_hidden_info();
casting_result divination_reveal_ways();
-const char *divination_reveal_ways_info();
+std::string divination_reveal_ways_info();
casting_result divination_sense_monsters();
-const char *divination_sense_monsters_info();
+std::string divination_sense_monsters_info();
extern s32b STONESKIN;
extern s32b DIG;
@@ -95,25 +92,23 @@ extern s32b STRIKE;
extern s32b SHAKE;
casting_result earth_stone_skin();
-const char *earth_stone_skin_info();
+std::string earth_stone_skin_info();
casting_result earth_dig();
casting_result earth_stone_prison();
casting_result earth_strike();
-const char *earth_strike_info();
+std::string earth_strike_info();
casting_result earth_shake();
-const char *earth_shake_info();
+std::string earth_shake_info();
extern s32b ERU_SEE;
extern s32b ERU_LISTEN;
-extern s32b ERU_UNDERSTAND;
extern s32b ERU_PROT;
casting_result eru_see_the_music();
-const char *eru_see_the_music_info();
+std::string eru_see_the_music_info();
casting_result eru_listen_to_the_music();
-casting_result eru_know_the_music();
casting_result eru_lay_of_protection();
-const char *eru_lay_of_protection_info();
+std::string eru_lay_of_protection_info();
extern s32b GLOBELIGHT;
extern s32b FIREFLASH;
@@ -122,15 +117,15 @@ extern s32b FIREWALL;
extern s32b FIREGOLEM;
casting_result fire_globe_of_light();
-const char *fire_globe_of_light_info();
+std::string fire_globe_of_light_info();
casting_result fire_fireflash();
-const char *fire_fireflash_info();
+std::string fire_fireflash_info();
casting_result fire_fiery_shield();
-const char *fire_fiery_shield_info();
+std::string fire_fiery_shield_info();
casting_result fire_firewall();
-const char *fire_firewall_info();
+std::string fire_firewall_info();
casting_result fire_golem();
-const char *fire_golem_info();
+std::string fire_golem_info();
extern s32b CALL_THE_ELEMENTS;
extern s32b CHANNEL_ELEMENTS;
@@ -142,22 +137,22 @@ extern s32b GROW_BARRIER;
extern s32b ELEMENTAL_MINION;
casting_result geomancy_call_the_elements();
-const char *geomancy_call_the_elements_info();
+std::string geomancy_call_the_elements_info();
casting_result geomancy_channel_elements();
casting_result geomancy_elemental_wave();
casting_result geomancy_vaporize();
-const char *geomancy_vaporize_info();
-bool_ geomancy_vaporize_depends();
+std::string geomancy_vaporize_info();
+bool geomancy_vaporize_depends();
casting_result geomancy_geolysis();
-const char *geomancy_geolysis_info();
-bool_ geomancy_geolysis_depends();
+std::string geomancy_geolysis_info();
+bool geomancy_geolysis_depends();
casting_result geomancy_dripping_tread();
-const char *geomancy_dripping_tread_info();
-bool_ geomancy_dripping_tread_depends();
+std::string geomancy_dripping_tread_info();
+bool geomancy_dripping_tread_depends();
casting_result geomancy_grow_barrier();
-bool_ geomancy_grow_barrier_depends();
+bool geomancy_grow_barrier_depends();
casting_result geomancy_elemental_minion();
-const char *geomancy_elemental_minion_info();
+std::string geomancy_elemental_minion_info();
extern s32b MANATHRUST;
extern s32b DELCURSES;
@@ -165,12 +160,12 @@ extern s32b RESISTS;
extern s32b MANASHIELD;
casting_result mana_manathrust();
-const char *mana_manathrust_info();
+std::string mana_manathrust_info();
casting_result mana_remove_curses();
casting_result mana_elemental_shield();
-const char *mana_elemental_shield_info();
+std::string mana_elemental_shield_info();
casting_result mana_disruption_shield();
-const char *mana_disruption_shield_info();
+std::string mana_disruption_shield_info();
extern s32b MANWE_SHIELD;
extern s32b MANWE_AVATAR;
@@ -178,13 +173,13 @@ extern s32b MANWE_BLESS;
extern s32b MANWE_CALL;
casting_result manwe_wind_shield();
-const char *manwe_wind_shield_info();
+std::string manwe_wind_shield_info();
casting_result manwe_avatar();
-const char *manwe_avatar_info();
+std::string manwe_avatar_info();
casting_result manwe_blessing();
-const char *manwe_blessing_info();
+std::string manwe_blessing_info();
casting_result manwe_call();
-const char *manwe_call_info();
+std::string manwe_call_info();
extern s32b MELKOR_CURSE;
extern s32b MELKOR_CORPSE_EXPLOSION;
@@ -194,9 +189,9 @@ void do_melkor_curse(int m_idx);
casting_result melkor_curse();
casting_result melkor_corpse_explosion();
-const char *melkor_corpse_explosion_info();
+std::string melkor_corpse_explosion_info();
casting_result melkor_mind_steal();
-const char *melkor_mind_steal_info();
+std::string melkor_mind_steal_info();
extern s32b RECHARGE;
extern s32b SPELLBINDER;
@@ -206,13 +201,13 @@ extern s32b INERTIA_CONTROL;
extern timer_type *TIMER_INERTIA_CONTROL;
casting_result meta_recharge();
-const char *meta_recharge_info();
+std::string meta_recharge_info();
casting_result meta_spellbinder();
-const char *meta_spellbinder_info();
+std::string meta_spellbinder_info();
casting_result meta_disperse_magic();
casting_result meta_tracker();
casting_result meta_inertia_control();
-const char *meta_inertia_control_info();
+std::string meta_inertia_control_info();
void meta_inertia_control_timer_callback();
void meta_inertia_control_calc_mana(int *msp);
@@ -224,13 +219,13 @@ extern s32b ARMOROFFEAR;
extern s32b STUN;
casting_result mind_charm();
-const char *mind_charm_info();
+std::string mind_charm_info();
casting_result mind_confuse();
-const char *mind_confuse_info();
+std::string mind_confuse_info();
casting_result mind_armor_of_fear();
-const char *mind_armor_of_fear_info();
+std::string mind_armor_of_fear_info();
casting_result mind_stun();
-const char *mind_stun_info();
+std::string mind_stun_info();
extern s32b MAGELOCK;
extern s32b SLOWMONSTER;
@@ -239,20 +234,20 @@ extern s32b BANISHMENT;
casting_result tempo_magelock();
casting_result tempo_slow_monster();
-const char *tempo_slow_monster_info();
+std::string tempo_slow_monster_info();
casting_result tempo_essence_of_speed();
-const char *tempo_essence_of_speed_info();
+std::string tempo_essence_of_speed_info();
casting_result tempo_banishment();
-const char *tempo_banishment_info();
+std::string tempo_banishment_info();
extern s32b TULKAS_AIM;
extern s32b TULKAS_WAVE;
extern s32b TULKAS_SPIN;
casting_result tulkas_divine_aim();
-const char *tulkas_divine_aim_info();
+std::string tulkas_divine_aim_info();
casting_result tulkas_wave_of_power();
-const char *tulkas_wave_of_power_info();
+std::string tulkas_wave_of_power_info();
casting_result tulkas_whirlwind();
extern s32b DRAIN;
@@ -266,9 +261,9 @@ int levels_in_book(s32b sval, s32b pval);
casting_result udun_drain();
casting_result udun_genocide();
casting_result udun_wraithform();
-const char *udun_wraithform_info();
+std::string udun_wraithform_info();
casting_result udun_flame_of_udun();
-const char *udun_flame_of_udun_info();
+std::string udun_flame_of_udun_info();
extern s32b TIDALWAVE;
extern s32b ICESTORM;
@@ -277,15 +272,15 @@ extern s32b VAPOR;
extern s32b GEYSER;
casting_result water_tidal_wave();
-const char *water_tidal_wave_info();
+std::string water_tidal_wave_info();
casting_result water_ice_storm();
-const char *water_ice_storm_info();
+std::string water_ice_storm_info();
casting_result water_ent_potion();
-const char *water_ent_potion_info();
+std::string water_ent_potion_info();
casting_result water_vapor();
-const char *water_vapor_info();
+std::string water_vapor_info();
casting_result water_geyser();
-const char *water_geyser_info();
+std::string water_geyser_info();
extern s32b YAVANNA_CHARM_ANIMAL;
extern s32b YAVANNA_GROW_GRASS;
@@ -294,15 +289,15 @@ extern s32b YAVANNA_WATER_BITE;
extern s32b YAVANNA_UPROOT;
casting_result yavanna_charm_animal();
-const char *yavanna_charm_animal_info();
+std::string yavanna_charm_animal_info();
casting_result yavanna_grow_grass();
-const char *yavanna_grow_grass_info();
+std::string yavanna_grow_grass_info();
casting_result yavanna_tree_roots();
-const char *yavanna_tree_roots_info();
+std::string yavanna_tree_roots_info();
casting_result yavanna_water_bite();
-const char *yavanna_water_bite_info();
+std::string yavanna_water_bite_info();
casting_result yavanna_uproot();
-const char *yavanna_uproot_info();
+std::string yavanna_uproot_info();
extern s32b GROWTREE;
extern s32b HEALING;
@@ -312,14 +307,14 @@ extern s32b SUMMONANNIMAL;
extern s32b GROW_ATHELAS;
casting_result nature_grow_trees();
-const char *nature_grow_trees_info();
+std::string nature_grow_trees_info();
casting_result nature_healing();
-const char *nature_healing_info();
+std::string nature_healing_info();
casting_result nature_recovery();
casting_result nature_regeneration();
-const char *nature_regeneration_info();
+std::string nature_regeneration_info();
casting_result nature_summon_animal();
-const char *nature_summon_animal_info();
+std::string nature_summon_animal_info();
casting_result nature_grow_athelas();
extern s32b DEVICE_HEAL_MONSTER;
@@ -332,16 +327,16 @@ extern s32b DEVICE_HOLY_FIRE;
extern s32b DEVICE_THUNDERLORDS;
casting_result device_heal_monster();
-const char *device_heal_monster_info();
+std::string device_heal_monster_info();
casting_result device_haste_monster();
-const char *device_haste_monster_info();
+std::string device_haste_monster_info();
casting_result device_wish();
casting_result device_summon_monster();
casting_result device_mana();
-const char *device_mana_info();
+std::string device_mana_info();
casting_result device_nothing();
casting_result device_holy_fire();
-const char *device_holy_fire_info();
+std::string device_holy_fire_info();
casting_result device_thunderlords();
extern s32b MUSIC_STOP;
@@ -361,32 +356,32 @@ extern s32b MUSIC_AMBARKANTA;
casting_result music_stop_singing_spell();
int music_holding_pattern_lasting();
casting_result music_holding_pattern_spell();
-const char *music_holding_pattern_info();
+std::string music_holding_pattern_info();
int music_illusion_pattern_lasting();
casting_result music_illusion_pattern_spell();
-const char *music_illusion_pattern_info();
+std::string music_illusion_pattern_info();
int music_stun_pattern_lasting();
casting_result music_stun_pattern_spell();
-const char *music_stun_pattern_info();
+std::string music_stun_pattern_info();
int music_song_of_the_sun_lasting();
casting_result music_song_of_the_sun_spell();
int music_flow_of_life_lasting();
casting_result music_flow_of_life_spell();
-const char *music_flow_of_life_info();
+std::string music_flow_of_life_info();
int music_heroic_ballad_lasting();
casting_result music_heroic_ballad_spell();
int music_hobbit_melodies_lasting();
casting_result music_hobbit_melodies_spell();
-const char *music_hobbit_melodies_info();
+std::string music_hobbit_melodies_info();
int music_clairaudience_lasting();
casting_result music_clairaudience_spell();
-const char *music_clairaudience_info();
+std::string music_clairaudience_info();
casting_result music_blow_spell();
-const char *music_blow_info();
+std::string music_blow_info();
casting_result music_gush_of_wind_spell();
-const char *music_gush_of_wind_info();
+std::string music_gush_of_wind_info();
casting_result music_horns_of_ylmir_spell();
-const char *music_horns_of_ylmir_info();
+std::string music_horns_of_ylmir_info();
casting_result music_ambarkanta_spell();
extern s32b AULE_FIREBRAND;
@@ -395,13 +390,13 @@ extern s32b AULE_ENCHANT_ARMOUR;
extern s32b AULE_CHILD;
casting_result aule_firebrand_spell();
-const char *aule_firebrand_info();
+std::string aule_firebrand_info();
casting_result aule_enchant_weapon_spell();
-const char *aule_enchant_weapon_info();
+std::string aule_enchant_weapon_info();
casting_result aule_enchant_armour_spell();
-const char *aule_enchant_armour_info();
+std::string aule_enchant_armour_info();
casting_result aule_child_spell();
-const char *aule_child_info();
+std::string aule_child_info();
extern s32b MANDOS_TEARS_LUTHIEN;
extern s32b MANDOS_SPIRIT_FEANTURI;
@@ -409,13 +404,13 @@ extern s32b MANDOS_TALE_DOOM;
extern s32b MANDOS_CALL_HALLS;
casting_result mandos_tears_of_luthien_spell();
-const char *mandos_tears_of_luthien_info();
+std::string mandos_tears_of_luthien_info();
casting_result mandos_spirit_of_the_feanturi_spell();
-const char *mandos_spirit_of_the_feanturi_info();
+std::string mandos_spirit_of_the_feanturi_info();
casting_result mandos_tale_of_doom_spell();
-const char *mandos_tale_of_doom_info();
+std::string mandos_tale_of_doom_info();
casting_result mandos_call_to_the_halls_spell();
-const char *mandos_call_to_the_halls_info();
+std::string mandos_call_to_the_halls_info();
extern s32b ULMO_BELEGAER;
extern s32b ULMO_DRAUGHT_ULMONAN;
@@ -423,13 +418,13 @@ extern s32b ULMO_CALL_ULUMURI;
extern s32b ULMO_WRATH;
casting_result ulmo_song_of_belegaer_spell();
-const char *ulmo_song_of_belegaer_info();
+std::string ulmo_song_of_belegaer_info();
casting_result ulmo_draught_of_ulmonan_spell();
-const char *ulmo_draught_of_ulmonan_info();
+std::string ulmo_draught_of_ulmonan_info();
casting_result ulmo_call_of_the_ulumuri_spell();
-const char *ulmo_call_of_the_ulumuri_info();
+std::string ulmo_call_of_the_ulumuri_info();
casting_result ulmo_wrath_of_ulmo_spell();
-const char *ulmo_wrath_of_ulmo_info();
+std::string ulmo_wrath_of_ulmo_info();
extern s32b VARDA_LIGHT_VALINOR;
extern s32b VARDA_CALL_ALMAREN;
@@ -437,8 +432,8 @@ extern s32b VARDA_EVENSTAR;
extern s32b VARDA_STARKINDLER;
casting_result varda_light_of_valinor_spell();
-const char *varda_light_of_valinor_info();
+std::string varda_light_of_valinor_info();
casting_result varda_call_of_almaren_spell();
casting_result varda_evenstar_spell();
casting_result varda_star_kindler_spell();
-const char *varda_star_kindler_info();
+std::string varda_star_kindler_info();
diff --git a/src/spells4.cc b/src/spells4.cc
index 97c3d523..ab79788c 100644
--- a/src/spells4.cc
+++ b/src/spells4.cc
@@ -12,9 +12,9 @@
#include "spells5.hpp"
#include "spells6.hpp"
#include "util.hpp"
-#include "util.h"
#include "variable.hpp"
#include "z-rand.hpp"
+#include "z-term.hpp"
#include <algorithm>
#include <array>
@@ -53,13 +53,13 @@ s32b SCHOOL_VARDA;
s32b SCHOOL_WATER;
s32b SCHOOL_YAVANNA;
-static bool_ uses_piety_to_cast(int s)
+static bool uses_piety_to_cast(int s)
{
return spell_type_uses_piety_to_cast(spell_at(s));
}
/** Describe what type of energy the spell uses for casting */
-cptr get_power_name(s32b s)
+const char *get_power_name(s32b s)
{
return uses_piety_to_cast(s) ? "piety" : "mana";
}
@@ -147,7 +147,7 @@ int spell_x(int sval, int spell_idx, int i)
}
}
-bool_ school_book_contains_spell(int sval, s32b spell_idx)
+bool school_book_contains_spell(int sval, s32b spell_idx)
{
random_book_setup(sval, spell_idx);
school_book *school_book = school_books_at(sval);
@@ -224,9 +224,7 @@ void init_school_books()
push_spell(TOME_NATURE, GROWTREE);
/* Create the book of Knowledge */
- push_spell(TOME_KNOWLEDGE, STARIDENTIFY);
push_spell(TOME_KNOWLEDGE, VISION);
- push_spell(TOME_KNOWLEDGE, IDENTIFY);
push_spell(TOME_KNOWLEDGE, REVEALWAYS);
push_spell(TOME_KNOWLEDGE, SENSEHIDDEN);
push_spell(TOME_KNOWLEDGE, SENSEMONSTERS);
@@ -258,7 +256,6 @@ void init_school_books()
/* Create the book of eru */
push_spell(TOME_ERU, ERU_PROT);
- push_spell(TOME_ERU, ERU_UNDERSTAND);
push_spell(TOME_ERU, ERU_LISTEN);
push_spell(TOME_ERU, ERU_SEE);
@@ -416,13 +413,13 @@ static std::string spell_school_name(spell_type *spell)
return buf.str();
}
-int print_spell(cptr label_, byte color, int y, s32b s)
+int print_spell(const char *label_, byte color, int y, s32b s)
{
s32b level;
- bool_ na;
+ bool na;
spell_type *spell = spell_at(s);
- cptr spell_info = spell_type_info(spell);
- cptr label = (label_ == NULL) ? "" : label_;
+ auto spell_info = spell_type_info(spell);
+ const char *label = (label_ == NULL) ? "" : label_;
char level_str[8] = "n/a";
char buf[128];
@@ -442,15 +439,15 @@ int print_spell(cptr label_, byte color, int y, s32b s)
level_str,
get_mana(s),
(int) spell_chance_book(s),
- spell_info);
+ spell_info.c_str());
c_prt(color, buf, y, 0);
return y + 1;
}
-void lua_cast_school_spell(s32b s, bool_ no_cost)
+void lua_cast_school_spell(s32b s, bool no_cost)
{
- bool_ use = FALSE;
+ bool use = false;
spell_type *spell = spell_at(s);
/* No magic? */
@@ -507,7 +504,7 @@ void lua_cast_school_spell(s32b s, bool_ no_cost)
}
else
{
- use = TRUE;
+ use = true;
/* failures are dangerous; we'll flush the input buffer
so it isn't missed. */
@@ -522,7 +519,7 @@ void lua_cast_school_spell(s32b s, bool_ no_cost)
}
/* Use the mana/piety */
- if (use == TRUE)
+ if (use == true)
{
/* Reduce mana */
adjust_power(s, -get_mana(s));
diff --git a/src/spells4.hpp b/src/spells4.hpp
index 02cdc3ce..e16c358a 100644
--- a/src/spells4.hpp
+++ b/src/spells4.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_type_fwd.hpp"
#include "school_book_fwd.hpp"
@@ -35,8 +35,8 @@ void init_school_books();
school_book *school_books_at(int sval);
void school_book_add_spell(school_book *school_book, s32b spell_idx);
void random_book_setup(s16b sval, s32b spell_idx);
-int print_spell(cptr label, byte color, int y, s32b s);
+int print_spell(const char *label, byte color, int y, s32b s);
int school_book_length(int sval);
int spell_x(int sval, int spell_idx, int i);
-bool_ school_book_contains_spell(int sval, s32b spell_idx);
-void lua_cast_school_spell(s32b spell_idx, bool_ no_cost);
+bool school_book_contains_spell(int sval, s32b spell_idx);
+void lua_cast_school_spell(s32b spell_idx, bool no_cost);
diff --git a/src/spells5.cc b/src/spells5.cc
index ba2e6d05..a8c42a7d 100644
--- a/src/spells5.cc
+++ b/src/spells5.cc
@@ -7,12 +7,15 @@
#include "variable.hpp"
#include "z-rand.hpp"
+#include <boost/algorithm/string/predicate.hpp>
#include <cassert>
+using boost::algorithm::equals;
+
static s16b school_spells_count = 0;
static struct spell_type *school_spells[SCHOOL_SPELLS_MAX];
-static spell_type *spell_new(s32b *index, cptr name)
+static spell_type *spell_new(s32b *index, const char *name)
{
assert(school_spells_count < SCHOOL_SPELLS_MAX);
@@ -24,7 +27,7 @@ static spell_type *spell_new(s32b *index, cptr name)
return spell;
}
-static cptr no_info()
+static std::string no_info()
{
return "";
}
@@ -37,20 +40,19 @@ spell_type *spell_at(s32b index)
return school_spells[index];
}
-int find_spell(cptr name)
+boost::optional<int> find_spell(const char *name)
{
int i;
for (i = 0; i < school_spells_count; i++)
{
- if (streq(spell_type_name(spell_at(i)), name))
+ if (equals(spell_type_name(spell_at(i)), name))
{
- return i;
+ return boost::make_optional(i);
}
}
- /* Not found */
- return -1;
+ return boost::none;
}
s16b get_random_spell(s16b random_type, int level)
@@ -1102,44 +1104,6 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&STARIDENTIFY, "Greater Identify");
- spell_type_describe(spell, "Asks for an object and fully identify it, providing the full list of powers");
- spell_type_describe(spell, "Cast at yourself it will reveal your powers");
- spell_type_set_mana(spell, 30, 30);
- spell_type_set_difficulty(spell, 35, 80);
- spell_type_init_mage(spell,
- RANDOM,
- SCHOOL_DIVINATION,
- no_info,
- divination_greater_identify);
- }
-
- {
- spell_type *spell = spell_new(&IDENTIFY, "Identify");
- spell_type_describe(spell, "Asks for an object and identifies it");
- spell_type_describe(spell, "At level 17 it identifies all objects in the inventory");
- spell_type_describe(spell, "At level 27 it identifies all objects in the inventory and in a");
- spell_type_describe(spell, "radius on the floor");
- spell_type_set_mana(spell, 10, 50);
- spell_type_set_difficulty(spell, 8, 40);
- spell_type_init_mage(spell,
- RANDOM,
- SCHOOL_DIVINATION,
- divination_identify_info,
- divination_identify);
-
- spell_type_set_device_charges(spell, "7+d10");
-
- {
- device_allocation *device_allocation = device_allocation_new(TV_STAFF);
- device_allocation->rarity = 45;
- range_init(&device_allocation->base_level, 1, 15);
- range_init(&device_allocation->max_level, 15, 40);
- spell_type_add_device_allocation(spell, device_allocation);
- }
- }
-
- {
spell_type *spell = spell_new(&VISION, "Vision");
spell_type_describe(spell, "Detects the layout of the surrounding area");
spell_type_describe(spell, "At level 25 it maps and lights the whole level");
@@ -1370,8 +1334,8 @@ void school_spells_init()
spell_type_set_mana(spell, 30, 60);
spell_type_set_inertia(spell, 1, 5);
spell_type_set_difficulty(spell, 15, 40);
- spell_type_set_castable_while_blind(spell, TRUE);
- spell_type_set_castable_while_confused(spell, TRUE);
+ spell_type_set_castable_while_blind(spell, true);
+ spell_type_set_castable_while_confused(spell, true);
spell_type_init_mage(spell,
RANDOM,
SCHOOL_META,
@@ -1565,7 +1529,7 @@ void school_spells_init()
spell_type_describe(spell, "At level 17 it can be targeted");
spell_type_set_mana(spell, 2, 20);
spell_type_set_difficulty(spell, 1, 10);
- spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_set_castable_while_blind(spell, true);
spell_type_init_mage(spell,
NO_RANDOM,
SCHOOL_GEOMANCY,
@@ -1590,7 +1554,7 @@ void school_spells_init()
spell_type_describe(spell, "At Fire level 15, fire become hellfire.");
spell_type_set_mana(spell, 3, 30);
spell_type_set_difficulty(spell, 3, 20);
- spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_set_castable_while_blind(spell, true);
spell_type_init_mage(spell,
NO_RANDOM,
SCHOOL_GEOMANCY,
@@ -1605,7 +1569,7 @@ void school_spells_init()
spell_type_describe(spell, "Abyss squares cannot be channeled into a wave.");
spell_type_set_mana(spell, 15, 50);
spell_type_set_difficulty(spell, 15, 20);
- spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_set_castable_while_blind(spell, true);
spell_type_init_mage(spell,
NO_RANDOM,
SCHOOL_GEOMANCY,
@@ -1618,7 +1582,7 @@ void school_spells_init()
spell_type_describe(spell, "Draws upon your immediate environs to form a cloud of damaging vapors");
spell_type_set_mana(spell, 3, 30);
spell_type_set_difficulty(spell, 4, 15);
- spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_set_castable_while_blind(spell, true);
spell_type_init_geomancy(
spell,
geomancy_vaporize_info,
@@ -1632,7 +1596,7 @@ void school_spells_init()
spell_type_describe(spell, "leaving behind tailings of various different sorts of walls in the passage.");
spell_type_set_mana(spell, 15, 40);
spell_type_set_difficulty(spell, 7, 15);
- spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_set_castable_while_blind(spell, true);
spell_type_init_geomancy(
spell,
geomancy_geolysis_info,
@@ -1645,7 +1609,7 @@ void school_spells_init()
spell_type_describe(spell, "Causes you to leave random elemental forms behind as you walk");
spell_type_set_mana(spell, 15, 25);
spell_type_set_difficulty(spell, 10, 15);
- spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_set_castable_while_blind(spell, true);
spell_type_init_geomancy(
spell,
geomancy_dripping_tread_info,
@@ -1659,7 +1623,7 @@ void school_spells_init()
spell_type_describe(spell, "At level 20 it can be projected around another area.");
spell_type_set_mana(spell, 30, 40);
spell_type_set_difficulty(spell, 12, 15);
- spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_set_castable_while_blind(spell, true);
spell_type_init_geomancy(
spell,
no_info,
@@ -1697,7 +1661,7 @@ void school_spells_init()
SCHOOL_ERU,
eru_see_the_music_info,
eru_see_the_music);
- spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_set_castable_while_blind(spell, true);
}
{
@@ -1715,19 +1679,6 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&ERU_UNDERSTAND, "Know the Music");
- spell_type_describe(spell, "Allows you to understand the Great Music from which the world");
- spell_type_describe(spell, "originates, allowing you to know the full abilities of things");
- spell_type_describe(spell, "At level 10 it allows you to *identify* all your pack");
- spell_type_set_mana(spell, 200, 600);
- spell_type_set_difficulty(spell, 30, 50);
- spell_type_init_priest(spell,
- SCHOOL_ERU,
- no_info,
- eru_know_the_music);
- }
-
- {
spell_type *spell = spell_new(&ERU_PROT, "Lay of Protection");
spell_type_describe(spell, "Creates a circle of safety around you");
spell_type_set_mana(spell, 400, 400);
@@ -2181,7 +2132,7 @@ void school_spells_init()
spell_type_describe(spell, "Stops the current song, if any.");
spell_type_set_mana(spell, 0, 0);
spell_type_set_difficulty(spell, 1, -400);
- spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_set_castable_while_blind(spell, true);
spell_type_init_music(spell,
1,
no_info,
@@ -2194,7 +2145,7 @@ void school_spells_init()
spell_type_describe(spell, "Consumes the amount of mana each turn.");
spell_type_set_mana(spell, 1, 10);
spell_type_set_difficulty(spell, 1, 20);
- spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_set_castable_while_blind(spell, true);
spell_type_init_music_lasting(
spell,
1,
@@ -2209,7 +2160,7 @@ void school_spells_init()
spell_type_describe(spell, "Consumes the amount of mana each turn.");
spell_type_set_mana(spell, 2, 15);
spell_type_set_difficulty(spell, 5, 30);
- spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_set_castable_while_blind(spell, true);
spell_type_init_music_lasting(
spell,
2,
@@ -2224,7 +2175,7 @@ void school_spells_init()
spell_type_describe(spell, "Consumes the amount of mana each turn.");
spell_type_set_mana(spell, 3, 25);
spell_type_set_difficulty(spell, 10, 45);
- spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_set_castable_while_blind(spell, true);
spell_type_init_music_lasting(
spell,
4,
@@ -2239,7 +2190,7 @@ void school_spells_init()
spell_type_describe(spell, "Consumes the amount of mana each turn.");
spell_type_set_mana(spell, 1, 1);
spell_type_set_difficulty(spell, 1, 20);
- spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_set_castable_while_blind(spell, true);
spell_type_init_music_lasting(
spell,
1,
@@ -2364,7 +2315,7 @@ void school_spells_init()
spells_init_theme();
break;
default:
- assert(FALSE);
+ assert(false);
}
}
diff --git a/src/spells5.hpp b/src/spells5.hpp
index 7359fa16..ef4b71ad 100644
--- a/src/spells5.hpp
+++ b/src/spells5.hpp
@@ -1,9 +1,11 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
+
+#include <boost/optional.hpp>
void school_spells_init();
struct spell_type *spell_at(s32b index);
s16b get_random_spell(s16b random_type, int lev);
s16b get_random_stick(byte tval, int level);
-int find_spell(cptr name);
+boost::optional<int> find_spell(const char *name);
diff --git a/src/spells6.cc b/src/spells6.cc
index 555f252f..ea71fe83 100644
--- a/src/spells6.cc
+++ b/src/spells6.cc
@@ -50,7 +50,7 @@ school_type *school_at(int index)
return &schools[index];
}
-static void school_init(school_type *school, cptr name, s16b skill)
+static void school_init(school_type *school, const char *name, s16b skill)
{
assert(school != NULL);
@@ -64,7 +64,7 @@ static void school_init(school_type *school, cptr name, s16b skill)
school->deity_idx = -1;
}
-static school_type *school_new(s32b *school_idx, cptr name, s16b skill)
+static school_type *school_new(s32b *school_idx, const char *name, s16b skill)
{
assert(schools_count < SCHOOLS_MAX);
@@ -77,11 +77,11 @@ static school_type *school_new(s32b *school_idx, cptr name, s16b skill)
return school;
}
-static school_type *sorcery_school_new(s32b *school_idx, cptr name, s16b skill)
+static school_type *sorcery_school_new(s32b *school_idx, const char *name, s16b skill)
{
school_type *school = school_new(school_idx, name, skill);
- school->spell_power = TRUE;
- school->sorcery = TRUE;
+ school->spell_power = true;
+ school->sorcery = true;
return school;
}
@@ -98,7 +98,7 @@ static school_type *god_school_new(s32b *school_idx, byte god)
if (god_enabled(deity))
{
school = school_new(school_idx, deity->name, SKILL_PRAY);
- school->spell_power = TRUE;
+ school->spell_power = true;
school->deity_idx = god;
school->deity = deity;
return school;
@@ -128,25 +128,23 @@ static int udun_bonus_levels()
return (p_ptr->lev * 2) / 3;
}
-static bool_ geomancy_depends_satisfied()
+static bool geomancy_depends_satisfied()
{
- object_type *o_ptr = NULL;
-
/* Require at least one point in each school */
if ((get_skill(SKILL_FIRE) <= 0) ||
(get_skill(SKILL_AIR) <= 0) ||
(get_skill(SKILL_EARTH) <= 0) ||
(get_skill(SKILL_WATER) <= 0))
{
- return FALSE;
+ return false;
}
/* Require to wield a Mage Staff, as the spells requries the
* caster to stomp the floor with it. */
- o_ptr = get_object(INVEN_WIELD);
+ auto o_ptr = get_object(INVEN_WIELD);
return ((o_ptr != NULL) &&
- (o_ptr->k_idx > 0) &&
+ (o_ptr->k_ptr) &&
(o_ptr->tval == TV_MSTAFF));
}
@@ -166,7 +164,7 @@ long get_provided_levels(school_type *school)
}
struct get_level_school_callback_data {
- bool_ allow_spell_power;
+ bool allow_spell_power;
long bonus;
long lvl;
long num;
@@ -206,7 +204,7 @@ static bool get_level_school_callback(struct get_level_school_callback_data *dat
* allow use of Spell Power for it to apply. */
if (!school->spell_power)
{
- data->allow_spell_power = FALSE;
+ data->allow_spell_power = false;
}
/* Calculate effects of provided levels */
@@ -243,7 +241,7 @@ static bool get_level_school_callback(struct get_level_school_callback_data *dat
return true;
}
-void get_level_school(spell_type *spell, s32b max, s32b min, s32b *level, bool_ *na)
+void get_level_school(spell_type *spell, s32b max, s32b min, s32b *level, bool *na)
{
assert(level != NULL);
assert(na != NULL);
@@ -252,13 +250,13 @@ void get_level_school(spell_type *spell, s32b max, s32b min, s32b *level, bool_
if (!spell_type_dependencies_satisfied(spell))
{
*level = min;
- *na = TRUE;
+ *na = true;
return;
}
/* Set up initial state */
get_level_school_callback_data data;
- data.allow_spell_power = TRUE;
+ data.allow_spell_power = true;
data.bonus = 0;
data.lvl = 0;
data.num = 0;
@@ -270,7 +268,7 @@ void get_level_school(spell_type *spell, s32b max, s32b min, s32b *level, bool_
if (!get_level_school_callback(&data, school_idx))
{
*level = min;
- *na = TRUE;
+ *na = true;
return;
}
}
@@ -293,7 +291,7 @@ void get_level_school(spell_type *spell, s32b max, s32b min, s32b *level, bool_
/* Result */
*level = data.lvl;
- *na = FALSE;
+ *na = false;
}
void schools_init()
@@ -322,6 +320,7 @@ void schools_init()
{
school_type *school = sorcery_school_new(&SCHOOL_EARTH, "Earth", SKILL_EARTH);
+ school_god(school, GOD_AULE, 1, 3);
school_god(school, GOD_TULKAS, 4, 5);
school_god(school, GOD_YAVANNA, 1, 2);
}
@@ -333,7 +332,7 @@ void schools_init()
{
school_type *school = school_new(&SCHOOL_GEOMANCY, "Geomancy", SKILL_GEOMANCY);
- school->spell_power = TRUE;
+ school->spell_power = true;
school->depends_satisfied = geomancy_depends_satisfied;
}
diff --git a/src/squelch/automatizer.cc b/src/squelch/automatizer.cc
index b06367a8..349f5915 100644
--- a/src/squelch/automatizer.cc
+++ b/src/squelch/automatizer.cc
@@ -5,7 +5,7 @@
#include "tome/squelch/cursor.hpp"
#include "tome/squelch/tree_printer.hpp"
#include "util.hpp"
-#include "z-term.h"
+#include "z-term.hpp"
namespace squelch {
diff --git a/src/squelch/condition.cc b/src/squelch/condition.cc
index cd7f879c..f172df58 100644
--- a/src/squelch/condition.cc
+++ b/src/squelch/condition.cc
@@ -3,6 +3,7 @@
#include <boost/algorithm/string/predicate.hpp>
+#include "jsoncons_helpers.hpp"
#include "tome/squelch/cursor.hpp"
#include "tome/squelch/tree_printer.hpp"
#include "../ability_type.hpp"
@@ -19,6 +20,9 @@
#include "../skill_type.hpp"
#include "../util.hpp"
#include "../variable.hpp"
+#include "../z-term.hpp"
+
+#include <fmt/format.h>
namespace squelch {
@@ -34,7 +38,6 @@ EnumStringMap<match_type> &match_mapping()
{ match_type::INSCRIBED, "inscribed" },
{ match_type::DISCOUNT, "discount" },
{ match_type::SYMBOL, "symbol" },
- { match_type::STATE, "state" },
{ match_type::STATUS, "status" },
{ match_type::TVAL, "tval" },
{ match_type::SVAL, "sval" },
@@ -49,15 +52,6 @@ EnumStringMap<match_type> &match_mapping()
return *m;
};
-EnumStringMap<identification_state> &identification_state_mapping()
-{
- // TODO: This is quite ugly and leads to valgrind complaints
- static auto m = new EnumStringMap<identification_state> {
- { identification_state::IDENTIFIED, "identified" },
- { identification_state::NOT_IDENTIFIED, "not identified" } };
- return *m;
-}
-
jsoncons::json Condition::to_json() const
{
// Start with an object with only 'type' property
@@ -107,7 +101,6 @@ std::shared_ptr<Condition> Condition::parse_condition(jsoncons::json const &cond
{ match_type::TVAL, &TvalCondition::from_json },
{ match_type::SVAL, &SvalCondition::from_json },
{ match_type::STATUS, &StatusCondition::from_json },
- { match_type::STATE, &StateCondition::from_json },
{ match_type::RACE, &RaceCondition::from_json },
{ match_type::SUBRACE, &SubraceCondition::from_json },
{ match_type::CLASS, &ClassCondition::from_json },
@@ -120,17 +113,18 @@ std::shared_ptr<Condition> Condition::parse_condition(jsoncons::json const &cond
return nullptr;
}
- cptr type_s = condition_json.get("type").as<cptr>();
- if (!type_s)
+ auto maybe_type_s = get_optional<std::string>(condition_json, "type");
+ if (!maybe_type_s)
{
msg_print("Missing/invalid 'type' in condition");
return nullptr;
}
+ auto type_s = *maybe_type_s;
match_type match;
if (!match_mapping().parse(type_s, &match))
{
- msg_format("Invalid 'type' in condition: %s", type_s);
+ msg_format("Invalid 'type' in condition: %s", type_s.c_str());
return nullptr;
}
@@ -149,7 +143,7 @@ jsoncons::json Condition::optional_to_json(std::shared_ptr<Condition> condition)
{
return condition
? condition->to_json()
- : jsoncons::json::null_type();
+ : jsoncons::null_type();
}
bool TvalCondition::is_match(object_type *o_ptr) const
@@ -159,16 +153,15 @@ bool TvalCondition::is_match(object_type *o_ptr) const
std::shared_ptr<Condition> TvalCondition::from_json(jsoncons::json const &j)
{
- auto tval_j = j.get("tval");
- if (!tval_j.is_uinteger())
+ if (auto maybe_tval = get_optional<uint8_t>(j, "tval"))
+ {
+ return std::make_shared<TvalCondition>(*maybe_tval);
+ }
+ else
{
msg_print("Missing/invalid 'tval' property");
return nullptr;
}
-
- int tval = tval_j.as_uint();
-
- return std::make_shared<TvalCondition>(tval);
}
void TvalCondition::to_json(jsoncons::json &j) const
@@ -182,7 +175,7 @@ void TvalCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t b
p->write(bcol, "tval");
p->write(ecol, " is ");
p->write(ecol, "\"");
- p->write(TERM_WHITE, format("%d", (int) m_tval));
+ p->write(TERM_WHITE, fmt::format("{}", m_tval));
p->write(ecol, "\"");
p->write(TERM_WHITE, "\n");
}
@@ -197,15 +190,15 @@ bool NameCondition::is_match(object_type *o_ptr) const
std::shared_ptr<Condition> NameCondition::from_json(jsoncons::json const &j)
{
- cptr s = j.get("name").as<cptr>();
-
- if (!s)
+ if (auto maybe_s = get_optional<std::string>(j, "name"))
+ {
+ return std::make_shared<NameCondition>(*maybe_s);
+ }
+ else
{
msg_print("Missing/invalid 'name' property");
return nullptr;
}
-
- return std::make_shared<NameCondition>(s);
}
void NameCondition::write_tree(TreePrinter *p, Cursor *cursor, uint8_t ecol, uint8_t bcol) const
@@ -232,15 +225,15 @@ bool ContainCondition::is_match(object_type *o_ptr) const
std::shared_ptr<Condition> ContainCondition::from_json(jsoncons::json const &j)
{
- cptr s = j.get("contain").as<cptr>();
-
- if (!s)
+ if (auto maybe_s = get_optional<std::string>(j, "contain"))
+ {
+ return std::make_shared<ContainCondition>(*maybe_s);
+ }
+ else
{
msg_print("Missing/invalid 'contain' property");
return nullptr;
}
-
- return std::make_shared<ContainCondition>(s);
}
void ContainCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
@@ -267,23 +260,21 @@ bool SvalCondition::is_match(object_type *o_ptr) const
std::shared_ptr<Condition> SvalCondition::from_json(jsoncons::json const &j)
{
- auto min_j = j.get("min");
- if (!min_j.is_uinteger())
+ auto min_j = get_optional<uint8_t>(j, "min");
+ if (!min_j)
{
msg_print("Missing/invalid 'min' property");
return nullptr;
}
- auto max_j = j.get("max");
- if (!max_j.is_uinteger())
+ auto max_j = get_optional<uint8_t>(j, "max");
+ if (!max_j)
{
msg_print("Missing/invalid 'max' property");
return nullptr;
}
- return std::make_shared<SvalCondition>(
- min_j.as_uint(),
- max_j.as_uint());
+ return std::make_shared<SvalCondition>(*min_j, *max_j);
}
void SvalCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
@@ -291,9 +282,9 @@ void SvalCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t b
p->write(ecol, "Its ");
p->write(bcol, "sval");
p->write(ecol, " is from ");
- p->write(TERM_WHITE, format("%d", m_min));
+ p->write(TERM_WHITE, fmt::format("{}", m_min));
p->write(ecol, " to ");
- p->write(TERM_WHITE, format("%d", m_max));
+ p->write(TERM_WHITE, fmt::format("{}", m_max));
p->write(TERM_WHITE, "\n");
}
@@ -384,7 +375,7 @@ std::shared_ptr<Condition> GroupingCondition::next_child(Condition *current)
std::vector< std::shared_ptr<Condition> > GroupingCondition::parse_conditions(jsoncons::json const &j)
{
- auto conditions_j = j.get("conditions");
+ auto conditions_j = j.get_with_default<jsoncons::json>("conditions", jsoncons::null_type());
if (conditions_j.is_null())
{
@@ -500,22 +491,23 @@ bool StatusCondition::is_match(object_type *o_ptr) const
std::shared_ptr<Condition> StatusCondition::from_json(jsoncons::json const &j)
{
- cptr s = j.get("status").as<cptr>();
-
- if (!s)
+ if (auto maybe_s = get_optional<std::string>(j, "status"))
{
- msg_print("Missing/invalid 'status' property");
- return nullptr;
- }
+ std::string s = *maybe_s;
+ status_type status;
+ if (!status_mapping().parse(s, &status))
+ {
+ msg_format("Invalid 'status' property: %s", s.c_str());
+ return nullptr;
+ }
- status_type status;
- if (!status_mapping().parse(s, &status))
+ return std::make_shared<StatusCondition>(status);
+ }
+ else
{
- msg_format("Invalid 'status' property: %s", s);
+ msg_print("Missing/invalid 'status' property");
return nullptr;
}
-
- return std::make_shared<StatusCondition>(status);
}
void StatusCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
@@ -541,15 +533,15 @@ bool RaceCondition::is_match(object_type *o_ptr) const
std::shared_ptr<Condition> RaceCondition::from_json(jsoncons::json const &j)
{
- cptr s = j.get("race").as<cptr>();
-
- if (!s)
+ if (auto maybe_s = get_optional<std::string>(j, "race"))
+ {
+ return std::make_shared<RaceCondition>(*maybe_s);
+ }
+ else
{
msg_print("Missing/invalid 'race' property");
return nullptr;
}
-
- return std::make_shared<RaceCondition>(s);
}
void RaceCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
@@ -575,15 +567,15 @@ bool SubraceCondition::is_match(object_type *o_ptr) const
std::shared_ptr<Condition> SubraceCondition::from_json(jsoncons::json const &j)
{
- cptr s = j.get("subrace").as<cptr>();
-
- if (!s)
+ if (auto maybe_s = get_optional<std::string>(j, "subrace"))
+ {
+ return std::make_shared<SubraceCondition>(*maybe_s);
+ }
+ else
{
msg_print("Missing/invalid 'subrace' property");
return nullptr;
}
-
- return std::make_shared<SubraceCondition>(s);
}
void SubraceCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
@@ -609,15 +601,15 @@ bool ClassCondition::is_match(object_type *o_ptr) const
std::shared_ptr<Condition> ClassCondition::from_json(jsoncons::json const &j)
{
- cptr s = j.get("class").as<cptr>();
-
- if (!s)
+ if (auto maybe_s = get_optional<std::string>(j, "class"))
+ {
+ return std::make_shared<ClassCondition>(*maybe_s);
+ }
+ else
{
msg_print("Missing/invalid 'class' property");
return nullptr;
}
-
- return std::make_shared<ClassCondition>(s);
}
void ClassCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
@@ -645,15 +637,15 @@ bool InscriptionCondition::is_match(object_type *o_ptr) const
std::shared_ptr<Condition> InscriptionCondition::from_json(jsoncons::json const &j)
{
- cptr s = j.get("inscription").as<cptr>();
-
- if (!s)
+ if (auto maybe_s = get_optional<std::string>(j, "inscription"))
+ {
+ return std::make_shared<InscriptionCondition>(*maybe_s);
+ }
+ else
{
msg_print("Missing/invalid 'inscription' property");
return nullptr;
}
-
- return std::make_shared<InscriptionCondition>(s);
}
void InscriptionCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
@@ -681,21 +673,21 @@ bool DiscountCondition::is_match(object_type *o_ptr) const
std::shared_ptr<Condition> DiscountCondition::from_json(jsoncons::json const &j)
{
- auto min_j = j.get("min");
- if (!min_j.is_integer())
+ auto maybe_min = get_optional<int>(j, "min");
+ if (!maybe_min)
{
msg_print("Missing/invalid 'min' property");
return nullptr;
}
- int min = min_j.as_int();
+ auto min = *maybe_min;
- auto max_j = j.get("max");
- if (!max_j.is_integer())
+ auto maybe_max = get_optional<int>(j, "max");
+ if (!maybe_max)
{
msg_print("Missing/invalid 'max' property");
return nullptr;
}
- int max = max_j.as_int();
+ auto max = *maybe_max;
return std::make_shared<DiscountCondition>(min, max);
}
@@ -705,9 +697,9 @@ void DiscountCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8
p->write(ecol, "Its ");
p->write(bcol, "discount");
p->write(ecol, " is from ");
- p->write(TERM_WHITE, format("%d", m_min));
+ p->write(TERM_WHITE, fmt::format("{}", m_min));
p->write(ecol, " to ");
- p->write(TERM_WHITE, format("%d", m_max));
+ p->write(TERM_WHITE, fmt::format("{}", m_max));
p->write(TERM_WHITE, "\n");
}
@@ -725,21 +717,21 @@ bool LevelCondition::is_match(object_type *) const
std::shared_ptr<Condition> LevelCondition::from_json(jsoncons::json const &j)
{
- auto min_j = j.get("min");
- if (!min_j.is_integer())
+ auto maybe_min = get_optional<int>(j, "min");
+ if (!maybe_min)
{
msg_print("Missing/invalid 'min' property");
return nullptr;
}
- int min = min_j.as_int();
+ auto min = *maybe_min;
- auto max_j = j.get("max");
- if (!max_j.is_integer())
+ auto maybe_max = get_optional<int>(j, "max");
+ if (!maybe_max)
{
msg_print("Missing/invalid 'max' property");
return nullptr;
}
- int max = max_j.as_int();
+ int max = *maybe_max;
return std::make_shared<LevelCondition>(min, max);
}
@@ -750,9 +742,9 @@ void LevelCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t
p->write(bcol, "level");
p->write(ecol, " is from ");
- p->write(TERM_WHITE, format("%d", m_min));
+ p->write(TERM_WHITE, fmt::format("{}", m_min));
p->write(ecol, " to ");
- p->write(TERM_WHITE, format("%d", m_max));
+ p->write(TERM_WHITE, fmt::format("{}", m_max));
p->write(TERM_WHITE, "\n");
}
@@ -771,33 +763,34 @@ bool SkillCondition::is_match(object_type *) const
std::shared_ptr<Condition> SkillCondition::from_json(jsoncons::json const &j)
{
- auto min_j = j.get("min");
- if (!min_j.is_integer())
+ auto maybe_min = get_optional<int>(j, "min");
+ if (!maybe_min)
{
msg_print("Missing/invalid 'min' property");
return nullptr;
}
- int min = min_j.as_int();
+ auto min = *maybe_min;
- auto max_j = j.get("max");
- if (!max_j.is_integer())
+ auto maybe_max = get_optional<int>(j, "max");
+ if (!maybe_max)
{
msg_print("Missing/invalid 'max' property");
return nullptr;
}
- int max = max_j.as_int();
+ auto max = *maybe_max;
- auto s = j.get("name").as<cptr>();
- if (!s)
+ auto maybe_s = get_optional<std::string>(j, "name");
+ if (!maybe_s)
{
msg_print("Missing/invalid 'name' property");
return nullptr;
}
+ auto s = *maybe_s;
auto si = find_skill_i(s);
if (si < 0)
{
- msg_print("Invalid 'name' property");
+ msg_format("Invalid 'name' property: %s", s.c_str());
return nullptr;
}
@@ -811,9 +804,9 @@ void SkillCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t
p->write(ecol, "Your skill in ");
p->write(bcol, s_descriptors[m_skill_idx].name);
p->write(ecol, " is from ");
- p->write(TERM_WHITE, format("%d", (int) m_min));
+ p->write(TERM_WHITE, fmt::format("{}", m_min));
p->write(ecol, " to ");
- p->write(TERM_WHITE, format("%d", (int) m_max));
+ p->write(TERM_WHITE, fmt::format("{}", m_max));
p->write(TERM_WHITE, "\n");
}
@@ -826,66 +819,14 @@ void SkillCondition::to_json(jsoncons::json &j) const
j["max"] = m_max;
}
-bool StateCondition::is_match(object_type *o_ptr) const
-{
- switch (m_state)
- {
- case identification_state::IDENTIFIED:
- return object_known_p(o_ptr);
- case identification_state::NOT_IDENTIFIED:
- return !object_known_p(o_ptr);
- }
-
- assert(false);
- return false;
-}
-
-std::shared_ptr<Condition> StateCondition::from_json(jsoncons::json const &j)
-{
- cptr s = j.get("state").as<cptr>();
-
- if (!s)
- {
- msg_print("Missing/invalid 'state' property");
- return nullptr;
- }
-
- identification_state state;
- if (!identification_state_mapping().parse(s, &state))
- {
- msg_format("Invalid 'state' property: %s", s);
- return nullptr;
- }
-
- return std::make_shared<StateCondition>(state);
-}
-
-void StateCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
-{
- p->write(ecol, "Its ");
- p->write(bcol, "state");
- p->write(ecol, " is ");
- p->write(ecol, "\"");
- p->write(TERM_WHITE, identification_state_mapping().stringify(m_state));
- p->write(ecol, "\"");
- p->write(TERM_WHITE, "\n");
-}
-
-void StateCondition::to_json(jsoncons::json &j) const
-{
- j["state"] = identification_state_mapping().stringify(m_state);
-}
-
bool SymbolCondition::is_match(object_type *o_ptr) const
{
- auto const &k_info = game->edit_data.k_info;
-
- return k_info[o_ptr->k_idx].d_char == m_symbol;
+ return o_ptr->k_ptr->d_char == m_symbol;
}
std::shared_ptr<Condition> SymbolCondition::from_json(jsoncons::json const &j)
{
- auto s = j.get("symbol").as<std::string>();
+ auto s = get_optional<std::string>(j, "symbol").value_or("");
if (s.empty())
{
@@ -908,14 +849,14 @@ void SymbolCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t
p->write(bcol, "symbol");
p->write(ecol, " is ");
p->write(ecol, "\"");
- p->write(TERM_WHITE, format("%c", m_symbol));
+ p->write(TERM_WHITE, fmt::format("{}", m_symbol));
p->write(ecol, "\"");
p->write(TERM_WHITE, "\n");
}
void SymbolCondition::to_json(jsoncons::json &j) const
{
- j["symbol"] = format("%c", m_symbol);
+ j["symbol"] = fmt::format("{}", m_symbol);
}
bool AbilityCondition::is_match(object_type *) const
@@ -925,18 +866,18 @@ bool AbilityCondition::is_match(object_type *) const
std::shared_ptr<Condition> AbilityCondition::from_json(jsoncons::json const &j)
{
- cptr a = j.get("ability").as<cptr>();
-
- if (!a)
+ auto maybe_a = get_optional<std::string>(j, "ability");
+ if (!maybe_a)
{
msg_print("Missing/invalid 'ability' property");
return nullptr;
}
+ auto a = *maybe_a;
auto ai = find_ability(a);
if (ai < 0)
{
- msg_print("Invalid 'ability' property");
+ msg_format("Invalid 'ability' property: %s", a.c_str());
return nullptr;
}
@@ -989,7 +930,7 @@ void SingleSubconditionCondition::to_json(jsoncons::json &j) const
std::shared_ptr<Condition> SingleSubconditionCondition::parse_single_subcondition(jsoncons::json const &in_json)
{
- auto condition_j = in_json.get("condition");
+ auto condition_j = in_json.get_with_default<jsoncons::json>("condition", jsoncons::null_type());
if (condition_j.is_null())
{
diff --git a/src/squelch/condition_metadata.cc b/src/squelch/condition_metadata.cc
index f6d4370c..7510840f 100644
--- a/src/squelch/condition_metadata.cc
+++ b/src/squelch/condition_metadata.cc
@@ -7,8 +7,7 @@
#include "lua_bind.hpp"
#include "skills.hpp"
#include "util.hpp"
-#include "util.h"
-#include "z-term.h"
+#include "z-term.hpp"
namespace squelch {
@@ -101,21 +100,6 @@ static std::shared_ptr<Condition> create_condition_status()
return std::make_shared<StatusCondition>(status);
}
-static std::shared_ptr<Condition> create_condition_state()
-{
- char c = msg_box_auto("[i]dentified, [n]on identified?");
-
- identification_state s;
- switch (c)
- {
- case 'i': s = identification_state::IDENTIFIED; break;
- case 'n': s = identification_state::NOT_IDENTIFIED; break;
- default: return nullptr;
- }
-
- return std::make_shared<StateCondition>(s);
-}
-
static bool in_byte_range(int x)
{
return (x >= 0) && (x < 256);
@@ -316,16 +300,13 @@ static void display_desc(match_type match_type_)
line("Check is true if object symbol is ok");
break;
- case match_type::STATE:
- line("Check is true if object is identified/unidentified");
- break;
-
case match_type::STATUS:
line("Check is true if object status is ok");
break;
case match_type::TVAL:
line("Check is true if object tval(from k_info.txt) is ok");
+ break;
case match_type::SVAL:
line("Check is true if object sval(from k_info.txt) is between");
@@ -379,7 +360,6 @@ std::shared_ptr<Condition> new_condition_interactive()
match_type::INSCRIBED,
match_type::DISCOUNT,
match_type::SYMBOL,
- match_type::STATE,
match_type::STATUS,
match_type::TVAL,
match_type::SVAL,
@@ -406,7 +386,7 @@ std::shared_ptr<Condition> new_condition_interactive()
// Choose
int begin = 0, sel = 0;
- while (1)
+ while (true)
{
int wid, hgt;
Term_clear();
@@ -460,8 +440,6 @@ std::shared_ptr<Condition> new_condition_interactive()
return create_condition_discount();
case match_type::SYMBOL:
return create_condition_symbol();
- case match_type::STATE:
- return create_condition_state();
case match_type::STATUS:
return create_condition_status();
case match_type::TVAL:
diff --git a/src/squelch/jsoncons_helpers.hpp b/src/squelch/jsoncons_helpers.hpp
new file mode 100644
index 00000000..1ce6b094
--- /dev/null
+++ b/src/squelch/jsoncons_helpers.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <boost/optional.hpp>
+#include <jsoncons/json.hpp>
+#include <string>
+
+namespace squelch {
+
+template <class T>
+boost::optional<T> get_optional(jsoncons::json const &json, std::string const &key)
+{
+ if (!json.has_key(key))
+ {
+ return boost::none;
+ }
+
+ auto value = json.at(key);
+
+ if (!value.is<T>())
+ {
+ return boost::none;
+ }
+
+ return value.as<T>();
+}
+
+} // namespace squelch
diff --git a/src/squelch/object_status.cc b/src/squelch/object_status.cc
index 075c0529..e020614f 100644
--- a/src/squelch/object_status.cc
+++ b/src/squelch/object_status.cc
@@ -5,6 +5,7 @@
#include "../object1.hpp"
#include "../object2.hpp"
#include "../object_type.hpp"
+#include "../object_flag.hpp"
#include "../variable.hpp"
namespace squelch {
@@ -20,9 +21,8 @@ EnumStringMap<status_type> &status_mapping()
{ status_type::VERY_GOOD, "very good" },
{ status_type::SPECIAL, "special" },
{ status_type::TERRIBLE, "terrible" },
- { status_type::NONE, "none" },
- { status_type::CHEST_EMPTY, "(empty chest)" },
- { status_type::CHEST_DISARMED, "(disarmed chest)" } };
+ { status_type::NONE, "none" }
+ };
return *m;
}
@@ -30,26 +30,15 @@ status_type object_status(object_type *o_ptr)
{
if (!object_known_p(o_ptr))
{
- switch (o_ptr->sense)
- {
- case SENSE_CURSED: return status_type::BAD;
- case SENSE_WORTHLESS: return status_type::VERY_BAD;
- case SENSE_AVERAGE: return status_type::AVERAGE;
- case SENSE_GOOD_LIGHT: return status_type::GOOD;
- case SENSE_GOOD_HEAVY: return status_type::GOOD;
- case SENSE_EXCELLENT: return status_type::VERY_GOOD;
- case SENSE_SPECIAL: return status_type::SPECIAL;
- case SENSE_TERRIBLE: return status_type::TERRIBLE;
- default: return status_type::NONE;
- }
+ return status_type::NONE;
}
else
{
- s16b slot = wield_slot_ideal(o_ptr, TRUE);
+ s16b slot = wield_slot_ideal(o_ptr, true);
if (artifact_p(o_ptr))
{
- if (!(o_ptr->ident & IDENT_CURSED))
+ if (!(o_ptr->art_flags & TR_CURSED))
{
return status_type::SPECIAL;
}
@@ -61,7 +50,7 @@ status_type object_status(object_type *o_ptr)
else if ((o_ptr->name2 > 0) ||
(o_ptr->name2b > 0))
{
- if (!(o_ptr->ident & IDENT_CURSED))
+ if (!(o_ptr->art_flags & TR_CURSED))
{
return status_type::VERY_GOOD;
}
@@ -128,21 +117,6 @@ status_type object_status(object_type *o_ptr)
return status_type::AVERAGE;
}
}
- else if (o_ptr->tval == TV_CHEST)
- {
- if (o_ptr->pval == 0)
- {
- return status_type::CHEST_EMPTY;
- }
- else if (o_ptr->pval < 0)
- {
- return status_type::CHEST_DISARMED;
- }
- else
- {
- return status_type::AVERAGE;
- }
- }
else
{
return status_type::AVERAGE;
diff --git a/src/squelch/rule.cc b/src/squelch/rule.cc
index e35b3ce1..934e40a1 100644
--- a/src/squelch/rule.cc
+++ b/src/squelch/rule.cc
@@ -1,10 +1,10 @@
#include "tome/squelch/rule_fwd.hpp"
#include "tome/squelch/rule.hpp"
+#include "jsoncons_helpers.hpp"
#include "tome/squelch/cursor.hpp"
#include "tome/squelch/condition.hpp"
#include "tome/squelch/tree_printer.hpp"
-#include "../angband.h"
#include "../modules.hpp"
#include "../object1.hpp"
#include "../object2.hpp"
@@ -13,6 +13,7 @@
#include "../tables.hpp"
#include "../util.hpp"
#include "../variable.hpp"
+#include "../z-term.hpp"
namespace squelch {
@@ -140,41 +141,44 @@ std::shared_ptr<Rule> Rule::parse_rule(jsoncons::json const &rule_json)
}
// Retrieve the attributes
- char const *rule_name_s = rule_json.get("name").as<char const *>();
- char const *rule_action_s = rule_json.get("action").as<char const *>();
- char const *rule_module_s = rule_json.get("module").as<char const *>();
- if ((!rule_name_s) || (!rule_action_s) || (!rule_module_s))
+ auto maybe_rule_name_s = get_optional<std::string>(rule_json, "name");
+ auto maybe_rule_action_s = get_optional<std::string>(rule_json, "action");
+ auto maybe_rule_module_s = get_optional<std::string>(rule_json, "module");
+ if ((!maybe_rule_name_s) || (!maybe_rule_action_s) || (!maybe_rule_module_s))
{
msg_print("Rule missing required field(s)");
return nullptr;
}
+ auto rule_name_s = *maybe_rule_name_s;
+ auto rule_action_s = *maybe_rule_action_s;
+ auto rule_module_s = *maybe_rule_module_s;
// Convert attributes
action_type action;
- if (!action_mapping().parse((cptr) rule_action_s, &action))
+ if (!action_mapping().parse(rule_action_s, &action))
{
- msg_format("Invalid rule action '%s'", rule_action_s);
+ msg_format("Invalid rule action '%s'", rule_action_s.c_str());
return nullptr;
}
- int module_idx = find_module((cptr) rule_module_s);
+ int module_idx = find_module(rule_module_s.c_str());
if (module_idx < 0)
{
msg_format("Skipping rule for unrecognized module '%s'",
- (cptr) rule_module_s);
+ rule_module_s.c_str());
return nullptr;
}
// Parse condition
std::shared_ptr<Condition> condition =
- Condition::parse_condition(rule_json.get("condition"));
+ Condition::parse_condition(rule_json.get_with_default<jsoncons::json>("condition", jsoncons::null_type()));
// Parse rule
switch (action)
{
case action_type::AUTO_INSCRIBE:
{
- auto rule_inscription_j = rule_json.get("inscription");
+ auto rule_inscription_j = rule_json.get_with_default<jsoncons::json>("inscription", jsoncons::null_type());
if (rule_inscription_j.is_null())
{
@@ -221,7 +225,7 @@ void DestroyRule::do_write_tree(TreePrinter *p) const
bool DestroyRule::do_apply_rule(object_type *o_ptr, int item_idx) const
{
// Must be identified
- if (object_aware_p(o_ptr) == FALSE)
+ if (object_aware_p(o_ptr) == false)
{
return false;
}
diff --git a/src/squelch/tree_printer.cc b/src/squelch/tree_printer.cc
index 0dbceec9..c9b70223 100644
--- a/src/squelch/tree_printer.cc
+++ b/src/squelch/tree_printer.cc
@@ -1,7 +1,7 @@
#include "tome/squelch/tree_printer_fwd.hpp"
#include "tome/squelch/tree_printer.hpp"
-#include "../z-term.h"
+#include "../z-term.hpp"
namespace squelch {
@@ -53,9 +53,9 @@ void TreePrinter::scroll_right() {
m_write_off_x--;
}
-void TreePrinter::write(uint8_t color, cptr line)
+void TreePrinter::write(uint8_t color, const char *line)
{
- cptr p = line;
+ const char *p = line;
for (p = line; *p != '\0'; p++)
{
diff --git a/src/squeltch.cc b/src/squeltch.cc
index 1db8ff74..5a3e7d86 100644
--- a/src/squeltch.cc
+++ b/src/squeltch.cc
@@ -27,9 +27,8 @@
#include "tome/squelch/object_status.hpp"
#include "tome/squelch/automatizer.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
+#include "z-form.hpp"
#include <algorithm>
#include <deque>
@@ -58,10 +57,10 @@ using squelch::StatusCondition;
static squelch::Automatizer *automatizer = nullptr;
+bool automatizer_create = false;
+
void squeltch_grid()
{
- auto const &k_info = game->edit_data.k_info;
-
if (!automatizer_enabled)
{
return;
@@ -77,7 +76,7 @@ void squeltch_grid()
object_type * o_ptr = &o_list[this_o_idx];
// We've now seen one of these
- if (!k_info[o_ptr->k_idx].flavor)
+ if (!o_ptr->k_ptr->flavor)
{
object_aware(o_ptr);
}
@@ -103,7 +102,7 @@ void squeltch_inventory()
for (int i = 0; i < INVEN_PACK; i++)
{
object_type *o_ptr = &p_ptr->inventory[i];
- if ((o_ptr->k_idx > 0) && automatizer->apply_rules(o_ptr, i))
+ if (o_ptr->k_ptr && automatizer->apply_rules(o_ptr, i))
{
// We have changes
changed = true;
@@ -207,10 +206,6 @@ static void automatizer_save_rules()
}
}
- // Pretty-printing options
- jsoncons::output_format format;
- format.indent(2);
-
// Convert to a JSON document
auto rules_document = automatizer->to_json();
@@ -223,7 +218,9 @@ static void automatizer_save_rules()
}
// Write JSON to output
- of << jsoncons::pretty_print(rules_document, format);
+ jsoncons::serialization_options serialization_options;
+ serialization_options.indent(2);
+ of << jsoncons::pretty_print(rules_document, serialization_options);
if (of.fail())
{
error();
@@ -251,16 +248,16 @@ static void rename_rule(Rule *rule)
void do_cmd_automatizer()
{
int active = ACTIVE_LIST;
- cptr keys;
- cptr keys2;
- cptr keys3;
- std::vector<cptr> rule_names;
+ const char *keys;
+ const char *keys2;
+ const char *keys3;
+ std::vector<const char *> rule_names;
if (!automatizer_enabled)
{
if (msg_box_auto("Automatizer is currently disabled, enable it? (y/n)") == 'y')
{
- automatizer_enabled = TRUE;
+ automatizer_enabled = true;
}
else
return;
@@ -270,7 +267,7 @@ void do_cmd_automatizer()
automatizer->reset_view();
- while (1)
+ while (true)
{
Term_clear();
@@ -367,7 +364,7 @@ void do_cmd_automatizer()
}
else if (c == 'k')
{
- automatizer_enabled = FALSE;
+ automatizer_enabled = false;
break;
}
else if (c == '\t')
@@ -419,6 +416,8 @@ void do_cmd_automatizer()
}
else if (c == 'a')
{
+ if (!automatizer->selected_rule())
+ continue;
automatizer->add_new_condition(
squelch::new_condition_interactive);
}
@@ -432,7 +431,7 @@ void do_cmd_automatizer()
int new_sel =
automatizer->remove_current_selection();
- if (new_sel == -1)
+ if (!new_sel)
{
active = ACTIVE_LIST;
}
@@ -585,7 +584,12 @@ bool automatizer_load(boost::filesystem::path const &path)
jsoncons::json rules_json;
try
{
- rules_json = jsoncons::json::parse_file(path.string());
+ // Open
+ std::ifstream ifs(
+ path.string(),
+ std::ifstream::in | std::ifstream::binary);
+ // Parse
+ ifs >> rules_json;
}
catch (jsoncons::json_exception const &exc)
{
@@ -593,6 +597,12 @@ bool automatizer_load(boost::filesystem::path const &path)
msg_print(exc.what());
return false;
}
+ catch (const std::ifstream::failure &exc)
+ {
+ msg_format("I/O error reading automatizer rules from '%s'.", path.c_str());
+ msg_print(exc.what());
+ return false;
+ }
// We didn't return directly via an exception, so let's extract
// the rules.
diff --git a/src/squeltch.hpp b/src/squeltch.hpp
index c4525e7d..11f4dec9 100644
--- a/src/squeltch.hpp
+++ b/src/squeltch.hpp
@@ -1,6 +1,5 @@
#pragma once
-#include "h-basic.h"
#include "object_type_fwd.hpp"
#include <boost/filesystem.hpp>
@@ -8,6 +7,6 @@ void squeltch_inventory();
void squeltch_grid();
void do_cmd_automatizer();
void automatizer_add_rule(object_type *o_ptr);
-extern bool_ automatizer_create;
+extern bool automatizer_create;
void automatizer_init();
bool automatizer_load(boost::filesystem::path const &path);
diff --git a/src/store.cc b/src/store.cc
index a11a3ea8..ba2f0c2b 100644
--- a/src/store.cc
+++ b/src/store.cc
@@ -36,10 +36,9 @@
#include "tables.hpp"
#include "town_type.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "xtra1.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
#include <cassert>
@@ -62,7 +61,7 @@
#define MAX_COMMENT_1 6
-static cptr comment_1[MAX_COMMENT_1] =
+static const char *comment_1[MAX_COMMENT_1] =
{
"Okay.",
"Fine.",
@@ -74,7 +73,7 @@ static cptr comment_1[MAX_COMMENT_1] =
#define MAX_COMMENT_4A 4
-static cptr comment_4a[MAX_COMMENT_4A] =
+static const char *comment_4a[MAX_COMMENT_4A] =
{
"Enough! You have abused me once too often!",
"Arghhh! I have had enough abuse for one day!",
@@ -84,7 +83,7 @@ static cptr comment_4a[MAX_COMMENT_4A] =
#define MAX_COMMENT_4B 4
-static cptr comment_4b[MAX_COMMENT_4B] =
+static const char *comment_4b[MAX_COMMENT_4B] =
{
"Leave my store!",
"Get out of my sight!",
@@ -128,7 +127,7 @@ static void say_comment_4()
#define MAX_COMMENT_7A 4
-static cptr comment_7a[MAX_COMMENT_7A] =
+static const char *comment_7a[MAX_COMMENT_7A] =
{
"Arrgghh!",
"You moron!",
@@ -138,7 +137,7 @@ static cptr comment_7a[MAX_COMMENT_7A] =
#define MAX_COMMENT_7B 4
-static cptr comment_7b[MAX_COMMENT_7B] =
+static const char *comment_7b[MAX_COMMENT_7B] =
{
"Darn!",
"You fiend!",
@@ -148,7 +147,7 @@ static cptr comment_7b[MAX_COMMENT_7B] =
#define MAX_COMMENT_7C 4
-static cptr comment_7c[MAX_COMMENT_7C] =
+static const char *comment_7c[MAX_COMMENT_7C] =
{
"Cool!",
"You've made my day!",
@@ -158,7 +157,7 @@ static cptr comment_7c[MAX_COMMENT_7C] =
#define MAX_COMMENT_7D 4
-static cptr comment_7d[MAX_COMMENT_7D] =
+static const char *comment_7d[MAX_COMMENT_7D] =
{
"Yippee!",
"I think I'll retire!",
@@ -247,7 +246,7 @@ static owner_type const *ot_ptr = NULL;
* to adjust (by 200) to extract a usable multiplier. Note that the
* "greed" value is always something (?).
*/
-static s32b price_item(object_type *o_ptr, int greed, bool_ flip)
+static s32b price_item(object_type *o_ptr, int greed, bool flip)
{
auto const &st_info = game->edit_data.st_info;
@@ -482,70 +481,67 @@ static void mass_produce(object_type *o_ptr)
*
* See "object_similar()" for the same function for the "player"
*/
-static bool_ store_object_similar(object_type const *o_ptr, object_type *j_ptr)
+static bool store_object_similar(object_type const *o_ptr, object_type *j_ptr)
{
/* Hack -- Identical items cannot be stacked */
- if (o_ptr == j_ptr) return (0);
+ if (o_ptr == j_ptr) return (false);
/* Different objects cannot be stacked */
- if (o_ptr->k_idx != j_ptr->k_idx) return (0);
+ if (o_ptr->k_ptr != j_ptr->k_ptr) return (false);
/* Different charges (etc) cannot be stacked, unless wands or rods. */
- if ((o_ptr->pval != j_ptr->pval) && (o_ptr->tval != TV_WAND)) return (0);
+ if ((o_ptr->pval != j_ptr->pval) && (o_ptr->tval != TV_WAND)) return (false);
/* Require many identical values */
- if (o_ptr->pval2 != j_ptr->pval2) return (0);
- if (o_ptr->pval3 != j_ptr->pval3) return (0);
+ if (o_ptr->pval2 != j_ptr->pval2) return (false);
+ if (o_ptr->pval3 != j_ptr->pval3) return (false);
/* Require many identical values */
- if (o_ptr->to_h != j_ptr->to_h) return (0);
- if (o_ptr->to_d != j_ptr->to_d) return (0);
- if (o_ptr->to_a != j_ptr->to_a) return (0);
+ if (o_ptr->to_h != j_ptr->to_h) return (false);
+ if (o_ptr->to_d != j_ptr->to_d) return (false);
+ if (o_ptr->to_a != j_ptr->to_a) return (false);
/* Require identical "artifact" names */
- if (o_ptr->name1 != j_ptr->name1) return (0);
+ if (o_ptr->name1 != j_ptr->name1) return (false);
/* Require identical "ego-item" names */
- if (o_ptr->name2 != j_ptr->name2) return (0);
+ if (o_ptr->name2 != j_ptr->name2) return (false);
/* Require identical "ego-item" names */
- if (o_ptr->name2b != j_ptr->name2b) return (0);
+ if (o_ptr->name2b != j_ptr->name2b) return (false);
/* Random artifacts don't stack !*/
- if (!o_ptr->artifact_name.empty()) return 0;
- if (!j_ptr->artifact_name.empty()) return 0;
+ if (!o_ptr->artifact_name.empty()) return false;
+ if (!j_ptr->artifact_name.empty()) return false;
/* Hack -- Identical art_flags! */
if (o_ptr->art_flags != j_ptr->art_flags)
- return (0);
+ return (false);
/* Hack -- Never stack "powerful" items */
- if (o_ptr->xtra1 || j_ptr->xtra1) return (0);
+ if (o_ptr->xtra1 || j_ptr->xtra1) return (false);
if (o_ptr->tval == TV_LITE)
{
/* Require identical "turns of light" */
- if (o_ptr->timeout != j_ptr->timeout) return (0);
+ if (o_ptr->timeout != j_ptr->timeout) return (false);
}
else
{
/* Hack -- Never stack recharging items */
- if (o_ptr->timeout || j_ptr->timeout) return (0);
+ if (o_ptr->timeout || j_ptr->timeout) return (false);
}
/* Require many identical values */
- if (o_ptr->ac != j_ptr->ac) return (0);
- if (o_ptr->dd != j_ptr->dd) return (0);
- if (o_ptr->ds != j_ptr->ds) return (0);
-
- /* Hack -- Never stack chests */
- if (o_ptr->tval == TV_CHEST) return (0);
+ if (o_ptr->ac != j_ptr->ac) return (false);
+ if (o_ptr->dd != j_ptr->dd) return (false);
+ if (o_ptr->ds != j_ptr->ds) return (false);
/* Require matching discounts */
- if (o_ptr->discount != j_ptr->discount) return (0);
+ if (o_ptr->discount != j_ptr->discount) return (false);
/* They match, so they must be similar */
- return (TRUE);
+ return true;
}
@@ -572,14 +568,14 @@ static void store_object_absorb(object_type *o_ptr, object_type *j_ptr)
* Note that the shop, just like a player, will not accept things
* it cannot hold. Before, one could "nuke" potions this way.
*/
-static bool_ store_check_num(object_type *o_ptr)
+static bool store_check_num(object_type *o_ptr)
{
auto const &st_info = game->edit_data.st_info;
/* Free space is always usable */
if (st_ptr->stock.size() < st_ptr->stock_size)
{
- return TRUE;
+ return true;
}
/* The "home" acts like the player */
@@ -591,7 +587,7 @@ static bool_ store_check_num(object_type *o_ptr)
/* Can the new object be combined with the old one? */
if (object_similar(&o_ref, o_ptr))
{
- return TRUE;
+ return true;
}
}
}
@@ -605,13 +601,13 @@ static bool_ store_check_num(object_type *o_ptr)
/* Can the new object be combined with the old one? */
if (store_object_similar(&o_ref, o_ptr))
{
- return TRUE;
+ return true;
}
}
}
/* But there was no room at the inn... */
- return FALSE;
+ return false;
}
@@ -950,9 +946,6 @@ static int store_carry(object_type *o_ptr)
return -1;
}
- /* All store items are fully *identified* */
- o_ptr->ident |= IDENT_MENTAL;
-
/* Erase the inscription */
o_ptr->inscription.clear();
@@ -1050,7 +1043,7 @@ static void store_item_optimize(int item)
auto const o_ptr = &st_ptr->stock[item];
/* Must exist */
- if (!o_ptr->k_idx) return;
+ if (!o_ptr->k_ptr) return;
/* Must have no items */
if (o_ptr->number) return;
@@ -1068,17 +1061,17 @@ static void store_item_optimize(int item)
* Crap is defined as any item that is "available" elsewhere
* Based on a suggestion by "Lee Vogt" <lvogt@cig.mcel.mot.com>
*/
-static bool_ black_market_crap(object_type *o_ptr)
+static bool black_market_crap(object_type *o_ptr)
{
auto const &st_info = game->edit_data.st_info;
/* Ego items are never crap */
- if (o_ptr->name2) return (FALSE);
+ if (o_ptr->name2) return false;
/* Good items are never crap */
- if (o_ptr->to_a > 0) return (FALSE);
- if (o_ptr->to_h > 0) return (FALSE);
- if (o_ptr->to_d > 0) return (FALSE);
+ if (o_ptr->to_a > 0) return false;
+ if (o_ptr->to_h > 0) return false;
+ if (o_ptr->to_d > 0) return false;
/* Check all stores */
for (std::size_t i = 0; i < st_info.size(); i++)
@@ -1090,12 +1083,15 @@ static bool_ black_market_crap(object_type *o_ptr)
for (auto const &stock_obj: town_info[p_ptr->town_num].store[i].stock)
{
/* Duplicate item "type", assume crappy */
- if (o_ptr->k_idx == stock_obj.k_idx) return (TRUE);
+ if (o_ptr->k_ptr == stock_obj.k_ptr)
+ {
+ return true;
+ }
}
}
/* Assume okay */
- return (FALSE);
+ return false;
}
@@ -1157,26 +1153,105 @@ static int store_tval = 0, store_level = 0;
/*
* Hack -- determine if a template is "good"
*/
-static bool_ kind_is_storeok(int k_idx)
+static bool kind_is_storeok(object_kind const *k_ptr)
{
- auto const &k_info = game->edit_data.k_info;
-
- auto k_ptr = &k_info[k_idx];
+ if (k_ptr->flags & TR_NORM_ART)
+ {
+ return false;
+ }
- if (k_info[k_idx].flags & TR_NORM_ART)
- return ( FALSE );
+ if (k_ptr->flags & TR_INSTA_ART)
+ {
+ return false;
+ }
- if (k_info[k_idx].flags & TR_INSTA_ART)
- return ( FALSE );
+ if (!kind_is_legal(k_ptr))
+ {
+ return false;
+ }
- if (!kind_is_legal(k_idx)) return FALSE;
+ if (k_ptr->tval != store_tval)
+ {
+ return false;
+ }
- if (k_ptr->tval != store_tval) return (FALSE);
- if (k_ptr->level < (store_level / 2)) return (FALSE);
+ if (k_ptr->level < (store_level / 2))
+ {
+ return false;
+ }
- return (TRUE);
+ return true;
}
+namespace { // anonymous
+
+struct is_artifact_p : public boost::static_visitor<bool> {
+
+ bool operator ()(store_item_filter_by_k_idx f) const
+ {
+ auto const &k_info = game->edit_data.k_info;
+ return bool(k_info.at(f.k_idx)->flags & TR_NORM_ART);
+ }
+
+ bool operator ()(store_item_filter_by_tval) const
+ {
+ return false;
+ }
+};
+
+class choose_k_idx : public boost::static_visitor<int> {
+
+ int m_level;
+
+public:
+
+ explicit choose_k_idx(int level)
+ : m_level(level)
+ {
+ }
+
+ int operator ()(store_item_filter_by_k_idx f) const
+ {
+ return f.k_idx;
+ }
+
+ int operator ()(store_item_filter_by_tval f) const
+ {
+ auto const &st_info = game->edit_data.st_info;
+ auto &alloc = game->alloc;
+
+ /* No themes */
+ init_match_theme(obj_theme::no_theme());
+
+ /* Activate restriction */
+ get_object_hook = kind_is_storeok;
+ store_tval = f.tval;
+
+ /* Do we forbid too shallow items ? */
+ if (st_info[st_ptr->st_idx].flags & STF_FORCE_LEVEL)
+ {
+ store_level = m_level;
+ }
+ else
+ {
+ store_level = 0;
+ }
+
+ /* Prepare allocation table */
+ get_obj_num_prep();
+
+ /* Get it! */
+ auto k_idx = get_obj_num(m_level);
+
+ /* Invalidate the cached allocation table */
+ alloc.kind_table_valid = false;
+
+ return k_idx;
+ }
+};
+
+} // namespace (anonymous)
+
/*
* Creates a random item and gives it to a store
* This algorithm needs to be rethought. A lot.
@@ -1193,12 +1268,12 @@ static void store_create()
auto const &k_info = game->edit_data.k_info;
auto &alloc = game->alloc;
- int i = 0, tries, level = 0;
+ int k_idx = -1;
+ int level = 0;
object_type forge;
object_type *q_ptr = NULL;
- bool_ obj_all_done = FALSE;
-
+ bool obj_all_done = false;
/* Paranoia -- no room left */
if (st_ptr->stock.size() >= st_ptr->stock_size)
@@ -1206,11 +1281,10 @@ static void store_create()
return;
}
-
/* Hack -- consider up to four items */
- for (tries = 0; tries < 4; tries++)
+ for (int tries = 0; tries < 4; tries++)
{
- obj_all_done = FALSE;
+ obj_all_done = false;
/* Magic Shop */
if ((st_info[st_ptr->st_idx].name == STORE_MAGIC) &&
@@ -1225,7 +1299,7 @@ static void store_create()
/* Use the forged object */
q_ptr = &forge;
- obj_all_done = TRUE;
+ obj_all_done = true;
}
/* Temple */
@@ -1241,7 +1315,7 @@ static void store_create()
/* Use the forged object */
q_ptr = &forge;
- obj_all_done = TRUE;
+ obj_all_done = true;
}
/* Black Market */
@@ -1254,7 +1328,7 @@ static void store_create()
* Even in Black Markets, illegal objects can be
* problematic -- Oxymoron?
*/
- get_obj_num_hook = kind_is_legal;
+ get_object_hook = kind_is_legal;
/* Rebuild the allocation table */
get_obj_num_prep();
@@ -1262,28 +1336,31 @@ static void store_create()
/* Pick a level for object/magic */
level = return_level();
- /* Random item (usually of given level) */
- i = get_obj_num(level);
+ /* Choose a k_info index */
+ k_idx = get_obj_num(level);
+ if (k_idx <= 0)
+ {
+ continue;
+ }
/* Invalidate the cached allocation table */
alloc.kind_table_valid = false;
- /* Handle failure */
- if (!i) continue;
-
}
/* Normal Store */
else
{
/* Hack -- Pick an item to sell */
- auto const &item = st_info[st_ptr->st_idx].items[rand_int(st_info[st_ptr->st_idx].items.size())];
- i = item.kind;
+ auto const &item = *uniform_element(st_info[st_ptr->st_idx].items);
+ auto filter = item.filter;
auto chance = item.chance;
/* Don't allow k_info artifacts */
- if ((i <= 10000) && (k_info[i].flags & TR_NORM_ART))
+ if (boost::apply_visitor(is_artifact_p(), filter))
+ {
continue;
+ }
/* Does it passes the rarity check ? */
if (!magik(chance)) continue;
@@ -1291,58 +1368,38 @@ static void store_create()
/* Hack -- fake level for apply_magic() */
level = return_level();
- /* Hack -- i > 10000 means it's a tval and all svals are allowed */
- if (i > 10000)
+ /* Choose the k_info index */
+ k_idx = boost::apply_visitor(choose_k_idx(level), filter);
+ if (k_idx <= 0)
{
- /* No themes */
- init_match_theme(obj_theme::no_theme());
-
- /* Activate restriction */
- get_obj_num_hook = kind_is_storeok;
- store_tval = i - 10000;
-
- /* Do we forbid too shallow items ? */
- if (st_info[st_ptr->st_idx].flags & STF_FORCE_LEVEL)
- {
- store_level = level;
- }
- else
- {
- store_level = 0;
- }
-
- /* Prepare allocation table */
- get_obj_num_prep();
-
- /* Get it ! */
- i = get_obj_num(level);
-
- /* Invalidate the cached allocation table */
- alloc.kind_table_valid = false;
+ continue;
}
-
- if (!i) continue;
}
/* Only if not already done */
if (!obj_all_done)
{
+ auto k_ptr = k_info.at(k_idx);
/* Don't allow k_info artifacts */
- if (k_info[i].flags & TR_NORM_ART)
+ if (k_ptr->flags & TR_NORM_ART)
+ {
continue;
+ }
/* Don't allow artifacts */
- if (k_info[i].flags & TR_INSTA_ART)
+ if (k_ptr->flags & TR_INSTA_ART)
+ {
continue;
+ }
/* Get local object */
q_ptr = &forge;
/* Create a new object of the chosen kind */
- object_prep(q_ptr, i);
+ object_prep(q_ptr, k_idx);
/* Apply some "low-level" magic (no artifacts) */
- apply_magic(q_ptr, level, FALSE, FALSE, FALSE);
+ apply_magic(q_ptr, level, false, false, false);
/* Hack -- Charge lite's */
if (q_ptr->tval == TV_LITE)
@@ -1350,7 +1407,7 @@ static void store_create()
auto const flags = object_flags(q_ptr);
if (flags & TR_FUEL_LITE)
{
- q_ptr->timeout = k_info[q_ptr->k_idx].pval2;
+ q_ptr->timeout = q_ptr->k_ptr->pval2;
}
}
@@ -1359,12 +1416,6 @@ static void store_create()
/* The item is "known" */
object_known(q_ptr);
- /* Mark it storebought */
- q_ptr->ident |= IDENT_STOREB;
-
- /* Mega-Hack -- no chests in stores */
- if (q_ptr->tval == TV_CHEST) continue;
-
/* Prune the black market */
if (st_info[st_ptr->st_idx].flags & STF_ALL_ITEM)
{
@@ -1426,7 +1477,10 @@ static void display_entry(int pos)
byte a = object_attr(o_ptr);
char c = object_char(o_ptr);
- if (!o_ptr->k_idx) c = ' ';
+ if (!o_ptr->k_ptr)
+ {
+ c = ' ';
+ }
Term_draw(cur_col, i + 6, a, c);
cur_col += 2;
@@ -1443,7 +1497,7 @@ static void display_entry(int pos)
/* Describe the object */
char o_name[80];
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
o_name[maxwid] = '\0';
c_put_str(tval_to_attr[o_ptr->tval], o_name, i + 6, cur_col);
@@ -1469,7 +1523,7 @@ static void display_entry(int pos)
/* Describe the object (fully) */
char o_name[80];
- object_desc_store(o_name, o_ptr, TRUE, 3);
+ object_desc_store(o_name, o_ptr, true, 3);
o_name[maxwid] = '\0';
c_put_str(tval_to_attr[o_ptr->tval], o_name, i + 6, cur_col);
@@ -1482,7 +1536,7 @@ static void display_entry(int pos)
}
/* Extract the "minimum" price */
- auto const x = price_item(o_ptr, ot_ptr->inflation, FALSE);
+ auto const x = price_item(o_ptr, ot_ptr->inflation, false);
/* Can we buy one ? */
if (x > p_ptr->au) color = TERM_L_DARK;
@@ -1616,7 +1670,7 @@ void display_store()
/*
* Get the ID of a store item and return its value -RAK-
*/
-static int get_stock(int *com_val, cptr pmt, int i, int j)
+static int get_stock(int *com_val, const char *pmt, int i, int j)
{
char command;
@@ -1630,7 +1684,7 @@ static int get_stock(int *com_val, cptr pmt, int i, int j)
if ((*com_val >= i) && (*com_val <= j))
{
/* Success */
- return (TRUE);
+ return true;
}
}
@@ -1646,7 +1700,7 @@ static int get_stock(int *com_val, cptr pmt, int i, int j)
I2A(i), I2A(j), pmt);
/* Ask until done */
- while (TRUE)
+ while (true)
{
int k;
@@ -1671,12 +1725,12 @@ static int get_stock(int *com_val, cptr pmt, int i, int j)
prt("", 0, 0);
/* Cancel */
- if (command == ESCAPE) return (FALSE);
+ if (command == ESCAPE) return false;
repeat_push(*com_val);
/* Success */
- return (TRUE);
+ return true;
}
@@ -1684,14 +1738,14 @@ static int get_stock(int *com_val, cptr pmt, int i, int j)
/**
* Prompt for a yes/no during selling/buying
*
- * @return TRUE if 'yes' was selected, otherwise returns FALSE.
+ * @return true if 'yes' was selected, otherwise returns false.
*/
-static bool_ prompt_yesno(cptr prompt)
+static bool prompt_yesno(const char *prompt)
{
- cptr allowed = "yn\r\n";
- cptr yes = "y\r\n";
+ const char *allowed = "yn\r\n";
+ const char *yes = "y\r\n";
char buf[128];
- bool_ ret;
+ bool ret;
/* Build prompt */
snprintf(buf, sizeof(buf), "%s [y/n/RET/ESC] ", prompt);
@@ -1701,13 +1755,13 @@ static bool_ prompt_yesno(cptr prompt)
prt(buf, 0, 0);
/* Get answer */
- while (TRUE)
+ while (true)
{
int key = inkey();
/* ESC means no. */
if (key == ESCAPE) {
- ret = FALSE;
+ ret = false;
break;
}
@@ -1734,13 +1788,12 @@ static bool_ prompt_yesno(cptr prompt)
/*
* Haggling routine -RAK-
*
- * Return TRUE if purchase is NOT successful
+ * Return true if purchase is NOT successful
*/
-static bool_ purchase_haggle(object_type *o_ptr, s32b *price)
+static bool purchase_haggle(object_type *o_ptr, s32b *price)
{
s32b cur_ask;
- bool_ cancel = FALSE;
- char out_val[160];
+ bool cancel = false;
char prompt[128];
char o_name[80];
@@ -1748,17 +1801,16 @@ static bool_ purchase_haggle(object_type *o_ptr, s32b *price)
*price = 0;
/* Extract the price */
- cur_ask = price_item(o_ptr, ot_ptr->inflation, FALSE);
+ cur_ask = price_item(o_ptr, ot_ptr->inflation, false);
/* Buy for the whole pile */
cur_ask *= o_ptr->number;
/* Describe the object (fully) */
- object_desc_store(o_name, o_ptr, TRUE, 3);
+ object_desc_store(o_name, o_ptr, true, 3);
/* Prompt */
- strnfmt(out_val, sizeof(out_val), "%s: " FMTs32b, "Price", cur_ask);
- put_str(out_val, 1, 0);
+ put_str(fmt::format("Price: {}", cur_ask), 1, 0);
strnfmt(prompt, sizeof(prompt), "Buy %s?", o_name);
cancel = !prompt_yesno(prompt);
@@ -1766,13 +1818,13 @@ static bool_ purchase_haggle(object_type *o_ptr, s32b *price)
if (cancel)
{
/* Cancel */
- return (TRUE);
+ return true;
}
else
{
*price = cur_ask;
/* Do not cancel */
- return (FALSE);
+ return false;
}
}
@@ -1780,13 +1832,12 @@ static bool_ purchase_haggle(object_type *o_ptr, s32b *price)
/*
* Haggling routine -RAK-
*
- * Return TRUE if purchase is NOT successful
+ * Return true if purchase is NOT successful
*/
-static bool_ sell_haggle(object_type *o_ptr, s32b *price)
+static bool sell_haggle(object_type *o_ptr, s32b *price)
{
s32b cur_ask;
- bool_ cancel = FALSE;
- char out_val[160];
+ bool cancel = false;
char prompt[128];
char o_name[80];
@@ -1794,7 +1845,7 @@ static bool_ sell_haggle(object_type *o_ptr, s32b *price)
*price = 0;
/* Extract price */
- cur_ask = price_item(o_ptr, ot_ptr->inflation, TRUE);
+ cur_ask = price_item(o_ptr, ot_ptr->inflation, true);
/* Limit to shopkeeper's purse */
if (cur_ask > ot_ptr->max_cost) {
@@ -1805,11 +1856,11 @@ static bool_ sell_haggle(object_type *o_ptr, s32b *price)
cur_ask *= o_ptr->number;
/* Describe the object */
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Prompt */
- strnfmt(out_val, sizeof(out_val), "%s: " FMTs32b, "Price", cur_ask);
- put_str(out_val, 1, 0);
+ put_str(fmt::format("Price: {}", cur_ask), 1, 0);
+
strnfmt(prompt, sizeof(prompt), "Sell %s?", o_name);
cancel = !prompt_yesno(prompt);
@@ -1817,13 +1868,13 @@ static bool_ sell_haggle(object_type *o_ptr, s32b *price)
if (cancel)
{
/* Cancel */
- return (TRUE);
+ return true;
}
else
{
*price = cur_ask;
/* Do not cancel */
- return (FALSE);
+ return false;
}
}
@@ -1983,7 +2034,7 @@ void store_stole()
/* Describe the transaction */
char o_name[80];
- object_desc(o_name, j_ptr, TRUE, 3);
+ object_desc(o_name, j_ptr, true, 3);
/* Message */
msg_format("You steal %s.", o_name);
@@ -1992,10 +2043,10 @@ void store_stole()
j_ptr->inscription.clear();
/* Give it to the player */
- int const item_new = inven_carry(j_ptr, FALSE);
+ int const item_new = inven_carry(j_ptr, false);
/* Describe the final result */
- object_desc(o_name, &p_ptr->inventory[item_new], TRUE, 3);
+ object_desc(o_name, &p_ptr->inventory[item_new], true, 3);
/* Message */
msg_format("You have %s (%c).",
@@ -2069,9 +2120,6 @@ void store_stole()
/* Kicked out for a LONG time */
st_ptr->store_open = turn + 500000 + randint(500000);
}
-
- /* Not kicked out */
- return;
}
/*
@@ -2146,7 +2194,7 @@ void store_purchase()
}
/* Determine the "best" price (per item) */
- auto const best = price_item(j_ptr, ot_ptr->inflation, FALSE);
+ auto const best = price_item(j_ptr, ot_ptr->inflation, false);
/* Find out how many the player wants */
int amt = 1;
@@ -2242,10 +2290,10 @@ void store_purchase()
/* Describe the transaction */
char o_name[80];
- object_desc(o_name, j_ptr, TRUE, 3);
+ object_desc(o_name, j_ptr, true, 3);
/* Message */
- msg_format("You bought %s for " FMTs32b " gold.", o_name, price);
+ msg_print(fmt::format("You bought {} for {} gold.", o_name, price));
/* Erase the inscription */
j_ptr->inscription.clear();
@@ -2261,10 +2309,10 @@ void store_purchase()
}
/* Give it to the player */
- int const item_new = inven_carry(j_ptr, FALSE);
+ int const item_new = inven_carry(j_ptr, false);
/* Describe the final result */
- object_desc(o_name, &p_ptr->inventory[item_new], TRUE, 3);
+ object_desc(o_name, &p_ptr->inventory[item_new], true, 3);
/* Message */
msg_format("You have %s (%c).",
@@ -2344,11 +2392,11 @@ void store_purchase()
}
/* Give it to the player */
- int const item_new = inven_carry(j_ptr, FALSE);
+ int const item_new = inven_carry(j_ptr, false);
/* Describe just the result */
char o_name[80];
- object_desc(o_name, &p_ptr->inventory[item_new], TRUE, 3);
+ object_desc(o_name, &p_ptr->inventory[item_new], true, 3);
/* Message */
msg_format("You have %s (%c).", o_name, index_to_label(item_new));
@@ -2379,9 +2427,6 @@ void store_purchase()
display_inventory();
}
}
-
- /* Not kicked out */
- return;
}
@@ -2406,7 +2451,8 @@ void store_sell()
bool museum = bool(st_info[st_ptr->st_idx].flags & STF_MUSEUM);
/* Prepare prompt */
- cptr q, s;
+ const char *q;
+ const char *s;
if (cur_store_num == STORE_HOME)
{
q = "Drop which item? ";
@@ -2490,7 +2536,7 @@ void store_sell()
}
/* Get a full description */
- object_desc(o_name, q_ptr, TRUE, 3);
+ object_desc(o_name, q_ptr, true, 3);
/* Remove any inscription for stores */
if ((cur_store_num != 7) && !museum)
@@ -2564,10 +2610,10 @@ void store_sell()
value = object_value(q_ptr) * q_ptr->number;
/* Get the description all over again */
- object_desc(o_name, q_ptr, TRUE, 3);
+ object_desc(o_name, q_ptr, true, 3);
/* Describe the result (in message buffer) */
- msg_format("You sold %s for " FMTs32b " gold.", o_name, price);
+ msg_print(fmt::format("You sold {} for {} gold.", o_name, price));
/* Analyze the prices (and comment verbally) */
purchase_analyze(price, value, dummy);
@@ -2605,7 +2651,7 @@ void store_sell()
else if (museum)
{
char o2_name[80];
- object_desc(o2_name, q_ptr, TRUE, 0);
+ object_desc(o2_name, q_ptr, true, 0);
msg_print("Once you donate something, you cannot take it back.");
if (!get_check(format("Do you really want to donate %s?", o2_name))) return;
@@ -2613,7 +2659,6 @@ void store_sell()
/* Identify it */
object_aware(q_ptr);
object_known(q_ptr);
- q_ptr->ident |= IDENT_MENTAL;
/*
* Hack -- Allocate charges between those wands or rods sold
@@ -2728,23 +2773,15 @@ void store_examine()
drop_near(o_ptr, -1, p_ptr->py, p_ptr->px);
}
- /* Require full knowledge */
- if (!(o_ptr->ident & (IDENT_MENTAL)))
- {
- /* This can only happen in the home */
- msg_print("You have no special knowledge about that item.");
- return;
- }
-
/* Description */
char o_name[80];
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Describe */
msg_format("Examining %s...", o_name);
/* Show the object's powers. */
- if (!object_out_desc(o_ptr, NULL, FALSE, TRUE))
+ if (!object_out_desc(o_ptr, NULL, false, true))
{
msg_print("You see nothing special.");
}
@@ -2756,17 +2793,15 @@ void store_examine()
do_cmd_browse_aux(o_ptr);
}
- return;
}
-
/*
* Hack -- set this to leave the store
*/
-static bool_ leave_store = FALSE;
+static bool leave_store = false;
/*
@@ -2805,12 +2840,15 @@ static store_action_type const *find_store_action(s16b command_cmd)
* must disable some commands which are allowed in the dungeon
* but not in the stores, to prevent chaos.
*/
-static bool_ store_process_command()
+static bool store_process_command(s16b *command_ptr)
{
- bool_ recreate = FALSE;
+ assert(command_ptr);
+ auto const &command_cmd = *command_ptr;
+
+ bool recreate = false;
/* Handle repeating the last command */
- repeat_check();
+ repeat_check(command_ptr);
auto ba_ptr = find_store_action(command_cmd);
@@ -2826,7 +2864,7 @@ static bool_ store_process_command()
/* Leave */
case ESCAPE:
{
- leave_store = TRUE;
+ leave_store = true;
break;
}
@@ -2865,6 +2903,7 @@ static bool_ store_process_command()
}
display_inventory();
}
+ break;
}
/* Redraw */
@@ -3123,7 +3162,7 @@ void do_cmd_store()
int maintain_num;
int tmp_chr;
int i;
- bool_ recreate = FALSE;
+ bool recreate = false;
cave_type *c_ptr;
@@ -3172,7 +3211,7 @@ void do_cmd_store()
/* Hack -- Character is in "icky" mode */
- character_icky = TRUE;
+ character_icky = true;
/* No command argument */
@@ -3208,7 +3247,7 @@ void do_cmd_store()
}
/* Do not leave */
- leave_store = FALSE;
+ leave_store = false;
/* Interact with player */
while (!leave_store)
@@ -3241,13 +3280,16 @@ void do_cmd_store()
show_building(st_ptr);
/* Get a command */
- request_command(TRUE);
+ request_command(true);
/* Process the command */
- if (store_process_command()) recreate = TRUE;
+ if (store_process_command(&command_cmd))
+ {
+ recreate = true;
+ }
/* Hack -- Character is still in "icky" mode */
- character_icky = TRUE;
+ character_icky = true;
/* Notice stuff */
notice_stuff();
@@ -3256,7 +3298,7 @@ void do_cmd_store()
handle_stuff();
/* XXX XXX XXX Pack Overflow */
- if (p_ptr->inventory[INVEN_PACK].k_idx)
+ if (p_ptr->inventory[INVEN_PACK].k_ptr)
{
int item = INVEN_PACK;
@@ -3269,7 +3311,7 @@ void do_cmd_store()
msg_print("Your pack is so full that you flee the store...");
/* Leave */
- leave_store = TRUE;
+ leave_store = true;
}
/* Hack -- Flee from the home */
@@ -3279,31 +3321,25 @@ void do_cmd_store()
msg_print("Your pack is so full that you flee your home...");
/* Leave */
- leave_store = TRUE;
+ leave_store = true;
}
/* Hack -- Drop items into the home */
else
{
- int item_pos;
-
- object_type forge;
- object_type *q_ptr;
-
- char o_name[80];
-
-
/* Give a message */
msg_print("Your pack overflows!");
/* Get local object */
- q_ptr = &forge;
+ object_type forge;
+ auto q_ptr = &forge;
/* Grab a copy of the item */
object_copy(q_ptr, o_ptr);
/* Describe it */
- object_desc(o_name, q_ptr, TRUE, 3);
+ char o_name[80];
+ object_desc(o_name, q_ptr, true, 3);
/* Message */
msg_format("You drop %s (%c).", o_name, index_to_label(item));
@@ -3315,7 +3351,7 @@ void do_cmd_store()
handle_stuff();
/* Let the home carry it */
- item_pos = home_carry(q_ptr);
+ int item_pos = home_carry(q_ptr);
/* Redraw the home */
if (item_pos >= 0)
@@ -3330,7 +3366,7 @@ void do_cmd_store()
if (tmp_chr != p_ptr->stat_use[A_CHR]) display_inventory();
/* Hack -- get kicked out of the store */
- if (st_ptr->store_open >= turn) leave_store = TRUE;
+ if (st_ptr->store_open >= turn) leave_store = true;
}
/* Free turn XXX XXX XXX */
@@ -3343,11 +3379,11 @@ void do_cmd_store()
p_ptr->oldpx = p_ptr->px;
p_ptr->oldpy = p_ptr->py;
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
}
/* Hack -- Character is no longer in "icky" mode */
- character_icky = FALSE;
+ character_icky = false;
/* Hack -- Cancel automatic command */
@@ -3619,7 +3655,7 @@ void do_cmd_home_trump()
/* Hack -- Character is in "icky" mode */
- character_icky = TRUE;
+ character_icky = true;
/* No command argument */
@@ -3656,7 +3692,7 @@ void do_cmd_home_trump()
}
/* Do not leave */
- leave_store = FALSE;
+ leave_store = false;
/* Interact with player */
while (!leave_store)
@@ -3701,13 +3737,13 @@ void do_cmd_home_trump()
prt("You may: ", 21, 0);
/* Get a command */
- request_command(TRUE);
+ request_command(true);
/* Process the command */
- store_process_command();
+ store_process_command(&command_cmd);
/* Hack -- Character is still in "icky" mode */
- character_icky = TRUE;
+ character_icky = true;
/* Notice stuff */
notice_stuff();
@@ -3716,7 +3752,7 @@ void do_cmd_home_trump()
handle_stuff();
/* XXX XXX XXX Pack Overflow */
- if (p_ptr->inventory[INVEN_PACK].k_idx)
+ if (p_ptr->inventory[INVEN_PACK].k_ptr)
{
int item = INVEN_PACK;
@@ -3729,7 +3765,7 @@ void do_cmd_home_trump()
msg_print("Your pack is so full that you flee the store...");
/* Leave */
- leave_store = TRUE;
+ leave_store = true;
}
/* Hack -- Flee from the home */
@@ -3739,31 +3775,25 @@ void do_cmd_home_trump()
msg_print("Your pack is so full that you flee your home...");
/* Leave */
- leave_store = TRUE;
+ leave_store = true;
}
/* Hack -- Drop items into the home */
else
{
- int item_pos;
-
- object_type forge;
- object_type *q_ptr;
-
- char o_name[80];
-
-
/* Give a message */
msg_print("Your pack overflows!");
/* Get local object */
- q_ptr = &forge;
+ object_type forge;
+ auto q_ptr = &forge;
/* Grab a copy of the item */
object_copy(q_ptr, o_ptr);
/* Describe it */
- object_desc(o_name, q_ptr, TRUE, 3);
+ char o_name[80];
+ object_desc(o_name, q_ptr, true, 3);
/* Message */
msg_format("You drop %s (%c).", o_name, index_to_label(item));
@@ -3775,7 +3805,7 @@ void do_cmd_home_trump()
handle_stuff();
/* Let the home carry it */
- item_pos = home_carry(q_ptr);
+ int const item_pos = home_carry(q_ptr);
/* Redraw the home */
if (item_pos >= 0)
@@ -3790,12 +3820,12 @@ void do_cmd_home_trump()
if (tmp_chr != p_ptr->stat_use[A_CHR]) display_inventory();
/* Hack -- get kicked out of the store */
- if (st_ptr->store_open >= turn) leave_store = TRUE;
+ if (st_ptr->store_open >= turn) leave_store = true;
}
/* Hack -- Character is no longer in "icky" mode */
- character_icky = FALSE;
+ character_icky = false;
/* Hack -- Cancel automatic command */
diff --git a/src/store_action_type.hpp b/src/store_action_type.hpp
index ee479375..cd400871 100644
--- a/src/store_action_type.hpp
+++ b/src/store_action_type.hpp
@@ -1,6 +1,9 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
+
+#include <array>
+#include <string>
/**
* Store/building actions.
diff --git a/src/store_info_type.hpp b/src/store_info_type.hpp
index 78aa071e..0d1d7d1c 100644
--- a/src/store_info_type.hpp
+++ b/src/store_info_type.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "store_flag_set.hpp"
#include "store_item.hpp"
diff --git a/src/store_item.hpp b/src/store_item.hpp
index 62d3f2a9..178d46c8 100644
--- a/src/store_item.hpp
+++ b/src/store_item.hpp
@@ -1,18 +1,59 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
+
+#include <boost/variant.hpp>
+
+struct store_item_filter_by_k_idx
+{
+ s16b k_idx = -1;
+};
+
+struct store_item_filter_by_tval
+{
+ s16b tval = -1;
+};
+
+using store_item_filter_t = boost::variant<store_item_filter_by_k_idx, store_item_filter_by_tval>;
struct store_item
{
/**
- * Legal item kinds; if > 10000, designates (TVAL - 10000) and any SVAL.
- * Otherwise designates an entry in k_info.txt.
+ * Filter for the store items.
*/
- s16b kind = 0;
+ store_item_filter_t filter;
/**
* Percentage chance of generation if the entry is chosen.
*/
s16b chance = 0;
+ /**
+ * Create a store item based on k_info index.
+ */
+ static store_item k_idx(s16b idx, s16b chance)
+ {
+ store_item_filter_by_k_idx k;
+ k.k_idx = idx;
+
+ store_item i;
+ i.chance = chance;
+ i.filter = k;
+ return i;
+ }
+
+ /**
+ * Create a store item based on TVAL.
+ */
+ static store_item tval(s16b tval, s16b chance)
+ {
+ store_item_filter_by_tval k;
+ k.tval = tval;
+
+ store_item i;
+ i.chance = chance;
+ i.filter = k;
+ return i;
+ }
+
};
diff --git a/src/store_type.hpp b/src/store_type.hpp
index 5fb4ac7f..ce2a9374 100644
--- a/src/store_type.hpp
+++ b/src/store_type.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_type_fwd.hpp"
#include <vector>
diff --git a/src/tables.cc b/src/tables.cc
index 1caa4bcf..6ca701a5 100644
--- a/src/tables.cc
+++ b/src/tables.cc
@@ -7,7 +7,6 @@
*/
#include "tables.hpp"
-#include "tables.h"
#include "modules.hpp"
#include "monster_race_flag.hpp"
@@ -43,6 +42,7 @@
#include "q_rand.hpp"
#include "stats.hpp"
#include "variable.hpp"
+#include "z-term.hpp"
@@ -1057,7 +1057,7 @@ s32b player_exp[PY_MAX_LEVEL] =
/*
* Hack -- the "basic" color names (see "TERM_xxx")
*/
-cptr color_names[16] =
+const char *color_names[16] =
{
"Dark",
"White",
@@ -1081,7 +1081,7 @@ cptr color_names[16] =
/*
* Abbreviations of healthy stats
*/
-cptr stat_names[6] =
+const char *stat_names[6] =
{
"STR", "INT", "WIS", "DEX", "CON", "CHR"
};
@@ -1089,7 +1089,7 @@ cptr stat_names[6] =
/*
* Abbreviations of damaged stats
*/
-cptr stat_names_reduced[6] =
+const char *stat_names_reduced[6] =
{
"Str", "Int", "Wis", "Dex", "Con", "Chr"
};
@@ -1109,7 +1109,7 @@ cptr stat_names_reduced[6] =
* The "ctrl-g" command (or pseudo-command) should perhaps grab a snapshot
* of the main screen into any interested windows.
*/
-cptr window_flag_desc[32] =
+const char *window_flag_desc[32] =
{
"Display inven/equip",
"Display equip/inven",
@@ -1147,7 +1147,7 @@ cptr window_flag_desc[32] =
/* Names used for random artifact name generation */
-cptr artifact_names_list =
+const char *artifact_names_list =
"adanedhel\n"
"adurant\n"
"aeglos\n"
@@ -1773,15 +1773,6 @@ martial_arts ma_blows[MAX_MA] =
{ "You hit %s with a Crushing Blow.", 48, 35, 20, 12, MA_STUN, 18 },
};
-/*
- * cptr desc; A verbose attack description
- * int min_level; Minimum level to use
- * int chance; Chance of 'success
- * int dd; Damage dice
- * int ds; Damage sides
- * s16b effect; Special effects
- * s16b power; Special effects power
- */
martial_arts bear_blows[MAX_BEAR] =
{
{ "You claw %s.", 1, 0, 3, 4, MA_STUN, 4 },
@@ -1840,11 +1831,6 @@ magic_power mindcraft_powers[MAX_MINDCRAFT_POWERS] =
"Sets up physical/elemental shield."
},
{
- 15, 12, 60,
- "Psychometry",
- "Identifies objects."
- },
- {
/* Ball -> LOS */
18, 10, 45,
"Mind Wave",
@@ -2304,24 +2290,6 @@ inscription_info_type inscription_info[MAX_INSCRIPTIONS] =
};
/*
- * Inscriptions for pseudo-id
- */
-cptr sense_desc[] =
-{
- "whoops",
- "cursed",
- "average",
- "good",
- "good",
- "excellent",
- "worthless",
- "terrible",
- "special",
- "broken",
- ""
-};
-
-/*
* Flag groups used for art creation, level gaining weapons, ...
* -----
* Name,
@@ -2431,475 +2399,13 @@ std::vector<flags_group> const &flags_groups()
return *instance;
};
-/* Powers */
-power_type powers_type[POWER_MAX] =
-{
- {
- "spit acid",
- "You can spit acid.",
- "You gain the ability to spit acid.",
- "You lose the ability to spit acid.",
- 9, 9, A_DEX, 15,
- },
- {
- "fire breath",
- "You can breath fire.",
- "You gain the ability to breathe fire.",
- "You lose the ability to breathe fire.",
- 20, 10, A_CON, 18,
- },
- {
- "hypnotic gaze",
- "Your gaze is hypnotic.",
- "Your eyes look mesmerising...",
- "Your eyes look uninteresting.",
- 12, 12, A_CHR, 18,
- },
- {
- "telekinesis",
- "You are telekinetic.",
- "You gain the ability to move objects telekinetically.",
- "You lose the ability to move objects telekinetically.",
- 9, 9, A_WIS, 14,
- },
- {
- "teleport",
- "You can teleport at will.",
- "You gain the power of teleportation at will.",
- "You lose the power of teleportation at will.",
- 7, 7, A_WIS, 15,
- },
- {
- "mind blast",
- "You can mind blast your enemies.",
- "You gain the power of Mind Blast.",
- "You lose the power of Mind Blast.",
- 5, 3, A_WIS, 15,
- },
- {
- "emit radiation",
- "You can emit hard radiation at will.",
- "You start emitting hard radiation.",
- "You stop emitting hard radiation.",
- 15, 15, A_CON, 14,
- },
- {
- "vampiric drain",
- "You can drain life from a foe.",
- "You become vampiric.",
- "You are no longer vampiric.",
- 4, 5, A_CON, 9,
- },
- {
- "smell metal",
- "You can smell nearby precious metal.",
- "You smell a metallic odour.",
- "You no longer smell a metallic odour.",
- 3, 2, A_INT, 12,
- },
- {
- "smell monsters",
- "You can smell nearby monsters.",
- "You smell filthy monsters.",
- "You no longer smell filthy monsters.",
- 5, 4, A_INT, 15,
- },
- {
- "blink",
- "You can teleport yourself short distances.",
- "You gain the power of minor teleportation.",
- "You lose the power of minor teleportation.",
- 3, 3, A_WIS, 12,
- },
- {
- "eat rock",
- "You can consume solid rock.",
- "The walls look delicious.",
- "The walls look unappetising.",
- 8, 12, A_CON, 18,
- },
- {
- "swap position",
- "You can switch locations with another being.",
- "You feel like walking a mile in someone else's shoes.",
- "You feel like staying in your own shoes.",
- 15, 12, A_DEX, 16,
- },
- {
- "shriek",
- "You can emit a horrible shriek.",
- "Your vocal cords get much tougher.",
- "Your vocal cords get much weaker.",
- 4, 4, A_CON, 6,
- },
- {
- "illuminate",
- "You can emit bright light.",
- "You can light up rooms with your presence.",
- "You can no longer light up rooms with your presence.",
- 3, 2, A_INT, 10,
- },
- {
- "detect curses",
- "You can feel the danger of evil magic.",
- "You can feel evil magic.",
- "You can no longer feel evil magic.",
- 7, 14, A_WIS, 14,
- },
- {
- "berserk",
- "You can drive yourself into a berserk frenzy.",
- "You feel a controlled rage.",
- "You no longer feel a controlled rage.",
- 8, 8, A_STR, 14,
- },
- {
- "polymorph",
- "You can polymorph yourself at will.",
- "Your body seems mutable.",
- "Your body seems stable.",
- 18, 20, A_CON, 18,
- },
- {
- "Midas touch",
- "You can turn ordinary items to gold.",
- "You gain the Midas touch.",
- "You lose the Midas touch.",
- 10, 5, A_INT, 12,
- },
- {
- "grow mold",
- "You can cause mold to grow near you.",
- "You feel a sudden affinity for mold.",
- "You feel a sudden dislike for mold.",
- 1, 6, A_CON, 14,
- },
- {
- "resist elements",
- "You can harden yourself to the ravages of the elements.",
- "You feel like you can protect yourself.",
- "You feel like you might be vulnerable.",
- 10, 12, A_CON, 12,
- },
- {
- "earthquake",
- "You can bring down the dungeon around your ears.",
- "You gain the ability to wreck the dungeon.",
- "You lose the ability to wreck the dungeon.",
- 12, 12, A_STR, 16,
- },
- {
- "eat magic",
- "You can consume magic energy for your own use.",
- "Your magic items look delicious.",
- "Your magic items no longer look delicious.",
- 17, 1, A_WIS, 15,
- },
- {
- "weigh magic",
- "You can feel the strength of the magics affecting you.",
- "You feel you can better understand the magic around you.",
- "You no longer sense magic.",
- 6, 6, A_INT, 10,
- },
- {
- "sterilise",
- "You can cause mass impotence.",
- "You can give everything around you a headache.",
- "You hear a massed sigh of relief.",
- 20, 40, A_CHR, 18,
- },
- {
- "panic hit",
- "You can run for your life after hitting something.",
- "You suddenly understand how thieves feel.",
- "You no longer feel jumpy.",
- 10, 12, A_DEX, 14,
- },
- {
- "dazzle",
- "You can emit confusing, blinding radiation.",
- "You gain the ability to emit dazzling lights.",
- "You lose the ability to emit dazzling lights.",
- 7, 15, A_CHR, 8,
- },
- {
- "spear of darkness",
- "You can create a spear of darkness.",
- "An illusory spear of darkness appears in your hand.",
- "The spear of darkness disappear.",
- 7, 10, A_WIS, 9,
- },
- {
- "recall",
- "You can travel between towns and the depths.",
- "You feel briefly homesick, but it passes.",
- "You feel briefly homesick.",
- 17, 50, A_INT, 16,
- },
- {
- "banish evil",
- "You can send evil creatures directly to the Nether Realm.",
- "You feel a holy wrath fill you.",
- "You no longer feel a holy wrath.",
- 25, 25, A_WIS, 18,
- },
- {
- "cold touch",
- "You can freeze things with a touch.",
- "Your hands get very cold.",
- "Your hands warm up.",
- 2, 2, A_CON, 11,
- },
- {
- "throw object",
- "You can hurl objects with great force.",
- "Your throwing arm feels much stronger.",
- "Your throwing arm feels much weaker.",
- 1, 10, A_STR, 6,
- },
- {
- "find secret passages",
- "You can use secret passages.",
- "You suddenly notice lots of hidden ways.",
- "You no longer can use hidden ways.",
- 15, 15, A_DEX, 12,
- },
- {
- "detect doors and traps",
- "You can detect hidden doors and traps.",
- "You develop an affinity for traps.",
- "You no longer can detect hidden doors and traps.",
- 5, 3, A_WIS, 10,
- },
- {
- "create food",
- "You can create food.",
- "Your cooking skills greatly improve.",
- "Your cooking skills return to a normal level.",
- 15, 10, A_INT, 10,
- },
- {
- "remove fear",
- "You can embolden yourself.",
- "You feel your fears lessening.",
- "You feel your fears growing again.",
- 3, 5, A_WIS, 8,
- },
- {
- "set explosive rune",
- "You can set explosive runes.",
- "You suddenly understand how explosive runes work.",
- "You suddenly forget how explosive runes work.",
- 25, 35, A_INT, 15,
- },
- {
- "stone to mud",
- "You can destroy walls.",
- "You can destroy walls.",
- "You cannot destroy walls anymore.",
- 20, 10, A_STR, 12,
- },
- {
- "poison dart",
- "You can throw poisoned darts.",
- "You get an infinite supply of poisoned darts.",
- "You lose your infinite supply of poisoned darts.",
- 12, 8, A_DEX, 14,
- },
- {
- "magic missile",
- "You can cast magic missiles.",
- "You suddenly understand the basics of magic.",
- "You forget the basics of magic.",
- 2, 2, A_INT, 9,
- },
- {
- "grow trees",
- "You can grow trees.",
- "You feel an affinity for trees.",
- "You no longer feel an affinity for trees.",
- 2, 6, A_CHR, 3,
- },
- {
- "cold breath",
- "You can breath cold.",
- "You gain the ability to breathe cold.",
- "You lose the ability to breathe cold.",
- 20, 10, A_CON, 18,
- },
- {
- "chaos breath",
- "You can breath chaos.",
- "You gain the ability to breathe chaos.",
- "You lose the ability to breathe chaos.",
- 20, 10, A_CON, 18,
- },
- {
- "elemental breath",
- "You can breath the elements.",
- "You gain the ability to breathe the elements.",
- "You lose the ability to breathe the elements.",
- 20, 10, A_CON, 18,
- },
- {
- "change the world",
- "You can wreck the world around you.",
- "You gain the ability to wreck the world.",
- "You lose the ability to wreck the world.",
- 1, 30, A_CHR, 6,
- },
- {
- "scare monster",
- "You can scare monsters.",
- "You gain the ability to scare monsters.",
- "You lose the ability to scare monsters.",
- 4, 3, A_INT, 3,
- },
- {
- "restore life",
- "You can restore lost life forces.",
- "You gain the ability to restore your life force.",
- "You lose the ability to restore your life force.",
- 30, 30, A_WIS, 18,
- },
- {
- "summon monsters",
- "You can call upon monsters.",
- "You gain the ability to call upon monsters.",
- "You lose the ability to call upon monsters.",
- 0, 0, 0, 0,
- },
- {
- "necromantic powers",
- "You can use the foul necromantic magic.",
- "You gain the ability to use the foul necromantic magic.",
- "You lose the ability to use the foul necromantic magic.",
- 0, 0, 0, 0,
- },
- {
- "Rohan Knight's Powers",
- "You can use rohir powers.",
- "You gain the ability to use rohir powers.",
- "You lose the ability to use rohir powers.",
- 0, 0, 0, 0,
- },
- {
- "Thunderlord's Powers",
- "You can use thunderlords powers.",
- "You gain the ability to use thunderlords powers.",
- "You lose the ability to use thunderlords powers.",
- 0, 0, 0, 0,
- },
- {
- "Death Mold's Powers",
- "You can use the foul deathmold magic.",
- "You gain the ability to use the foul deathmold magic.",
- "You lose the ability to use the foul deathmold magic.",
- 0, 0, 0, 0,
- },
- {
- "Hypnotise Pet",
- "You can mystify pets.",
- "You gain the ability to mystify pets.",
- "You lose the ability to mystify pets.",
- 0, 0, 0, 0,
- },
- {
- "Awaken Hypnotised Pet",
- "You can wake up a pet.",
- "You gain the ability to wake up a pet.",
- "You lose the ability to wake up a pet.",
- 0, 0, 0, 0,
- },
- {
- "Incarnate",
- "You can incarnate into a body.",
- "You feel the need to get a body.",
- "You no longer feel the need for a new body.",
- 0, 0, 0, 0,
- },
- {
- "magic map",
- "You can sense what is beyond walls.",
- "You feel you can sense what is beyond walls.",
- "You no longer can sense what is beyond walls.",
- 7, 10, A_WIS, 15,
- },
- {
- "lay trap",
- "You can lay monster traps.",
- "You suddenly understand how rogues work.",
- "You no longer understand how rogues work.",
- 1, 1, A_DEX, 1,
- },
- {
- "notused", /* Merchant abilities; no longer used, but want to
- * avoid having to move all potential places where
- * we're indexing into this table. */
- "notused",
- "notused",
- "notused",
- 0, 0, 0, 0,
- },
- {
- "turn pet into companion",
- "You can turn a pet into a companion.",
- "You suddenly gain authority over your pets.",
- "You can no longer convert pets into companions.",
- 2, 10, A_CHR, 10,
- },
- {
- "turn into a bear",
- "You can turn into a bear.",
- "You suddenly gain beorning powers.",
- "You can no longer shapeshift into a bear.",
- 2, 5, A_CON, 5,
- },
- {
- "sense dodge success",
- "You can sense your dodging success chance.",
- "You suddenly can sense your dodging success chance.",
- "You can no longer sense your dodging success chance.",
- 0, 0, 0, 0,
- },
- {
- "turn into a Balrog",
- "You can turn into a Balrog at will.",
- "You feel the fire of Udun burning in you.",
- "You no longer feel the fire of Udun in you.",
- 35, 80, A_WIS, 25,
- },
- {
- "invisibility",
- "You are able melt into the shadows to become invisible.",
- "You suddenly become able to melt into the shadows.",
- "You lose your shadow-melting ability.",
- 30, 10, A_DEX, 20,
- },
- {
- "web",
- "You are able throw a thick and very resistant spider web.",
- "You suddenly become able to weave webs.",
- "You lose your web-weaving capability.",
- 25, 30, A_DEX, 20,
- },
- {
- "control space/time continuum",
- "You are able to control the space/time continuum.",
- "You become able to control the space/time continuum.",
- "You are no more able to control the space/time continuum.",
- 1, 10, A_WIS, 10,
- },
-};
-
/*
* The Quests
*/
quest_type quest[MAX_Q_IDX] =
{
{
- FALSE,
+ false,
"",
{
"",
@@ -2922,7 +2428,7 @@ quest_type quest[MAX_Q_IDX] =
NULL,
},
{
- FALSE,
+ false,
"Dol Guldur",
{
"The forest of Mirkwood is a very dangerous place to go, mainly due to",
@@ -2945,7 +2451,7 @@ quest_type quest[MAX_Q_IDX] =
NULL,
},
{
- FALSE,
+ false,
"Sauron",
{
"It is time to take the battle to Morgoth. But, before you can",
@@ -2968,7 +2474,7 @@ quest_type quest[MAX_Q_IDX] =
NULL,
},
{
- FALSE,
+ false,
"Morgoth",
{
"Your final quest is the ultimate quest that has always been",
@@ -2993,7 +2499,7 @@ quest_type quest[MAX_Q_IDX] =
/* Bree plot */
{
- FALSE,
+ false,
"Thieves!",
{
"There are thieves robbing my people! They live in a small",
@@ -3017,7 +2523,7 @@ quest_type quest[MAX_Q_IDX] =
},
{
- FALSE,
+ false,
"Random Quest",
{
"",
@@ -3041,7 +2547,7 @@ quest_type quest[MAX_Q_IDX] =
},
{
- FALSE,
+ false,
"Lost Hobbit",
{
"Merton Proudfoot, a young hobbit, seems to have disappeared.",
@@ -3065,7 +2571,7 @@ quest_type quest[MAX_Q_IDX] =
},
{
- FALSE,
+ false,
"The Dark Horseman",
{
"A dark-cloaked horseman has been spotted several times in town.",
@@ -3089,7 +2595,7 @@ quest_type quest[MAX_Q_IDX] =
},
{
- FALSE,
+ false,
"The Trolls Glade",
{
"A group of Forest Trolls settled in an abandoned forest in the",
@@ -3108,12 +2614,12 @@ quest_type quest[MAX_Q_IDX] =
&plots[PLOT_BREE],
quest_troll_init_hook,
- {FALSE, 0},
+ {false, 0},
NULL,
},
{
- FALSE,
+ false,
"The Wight Grave",
{
"The Barrow-Downs hides many mysteries and dangers.",
@@ -3132,13 +2638,13 @@ quest_type quest[MAX_Q_IDX] =
&plots[PLOT_BREE],
quest_wight_init_hook,
- {FALSE, 0},
+ {false, 0},
NULL,
},
/* Lorien plot */
{
- FALSE,
+ false,
"Spiders of Mirkwood",
{
"Powers lurk deep within Mirkwood. Spiders have blocked the",
@@ -3161,7 +2667,7 @@ quest_type quest[MAX_Q_IDX] =
NULL,
},
{
- FALSE,
+ false,
"Poisoned Water",
{
"A curse has beset Lothlorien. All trees along the shorelines of Nimrodel",
@@ -3185,7 +2691,7 @@ quest_type quest[MAX_Q_IDX] =
},
/* Other quests */
{
- FALSE,
+ false,
"The Broken Sword",
{
"You have found Narsil, a broken sword. It is said that the sword that",
@@ -3209,7 +2715,7 @@ quest_type quest[MAX_Q_IDX] =
},
/* Gondolin plot */
{
- FALSE,
+ false,
"Eol the Dark Elf",
{
"We have disturbing tidings. Eol the Dark Elf has come seeking his kin in",
@@ -3232,7 +2738,7 @@ quest_type quest[MAX_Q_IDX] =
NULL,
},
{
- FALSE,
+ false,
"Nirnaeth Arnoediad",
{
"The fortunes of war in the north turn against us.",
@@ -3255,7 +2761,7 @@ quest_type quest[MAX_Q_IDX] =
NULL,
},
{
- FALSE,
+ false,
"Invasion of Gondolin",
{
"Morgoth is upon us! Dragons and Balrogs have poured over secret",
@@ -3279,7 +2785,7 @@ quest_type quest[MAX_Q_IDX] =
},
/* Minas Anor Plot*/
{
- FALSE,
+ false,
"The Last Alliance",
{
"The armies of Morgoth are closing in on the last remaining strongholds",
@@ -3302,7 +2808,7 @@ quest_type quest[MAX_Q_IDX] =
NULL,
},
{
- FALSE,
+ false,
"The One Ring",
{
"Find the One Ring, then bring it to Mount Doom, in Mordor, to drop",
@@ -3326,7 +2832,7 @@ quest_type quest[MAX_Q_IDX] =
},
{
- FALSE,
+ false,
"Mushroom supplies",
{
"Farmer Maggot asked you to bring him back his mushrooms.",
@@ -3350,7 +2856,7 @@ quest_type quest[MAX_Q_IDX] =
},
{
- FALSE,
+ false,
"The prisoner of Dol Guldur",
{
"You keep hearing distress cries in the dark tower of",
@@ -3375,7 +2881,7 @@ quest_type quest[MAX_Q_IDX] =
/* The 2 ultra endings go here */
{
- FALSE,
+ false,
"Falling Toward Apotheosis",
{
"You must enter the Void where Melkor spirit lurks to destroy",
@@ -3398,7 +2904,7 @@ quest_type quest[MAX_Q_IDX] =
NULL,
},
{
- FALSE,
+ false,
"Falling Toward Apotheosis",
{
"You must now launch an onslaught on Valinor itself to eliminate",
@@ -3422,7 +2928,7 @@ quest_type quest[MAX_Q_IDX] =
},
/* More Lorien */
{
- FALSE,
+ false,
"Wolves!",
{
"There are wolves pestering my people! They gather in a hut",
@@ -3446,7 +2952,7 @@ quest_type quest[MAX_Q_IDX] =
},
/* More Gondolin */
{
- FALSE,
+ false,
"Dragons!",
{
"There are dragons pestering my people! They gather in a",
@@ -3470,7 +2976,7 @@ quest_type quest[MAX_Q_IDX] =
},
/* More Minas Anor */
{
- FALSE,
+ false,
"Haunted House!",
{
"There are undead pestering my people! They gather in a hut",
@@ -3494,7 +3000,7 @@ quest_type quest[MAX_Q_IDX] =
},
/* Khazad-Dum Plot*/
{
- FALSE,
+ false,
"Evil!",
{
"We have burrowed too deep, and let out some creatures of",
@@ -3518,7 +3024,7 @@ quest_type quest[MAX_Q_IDX] =
},
/* Bounty */
{
- FALSE,
+ false,
"Bounty quest",
{
"", /* dynamic desc */
@@ -3532,7 +3038,7 @@ quest_type quest[MAX_Q_IDX] =
},
/* Fireproofing */
{
- FALSE,
+ false,
"Old Mages quest",
{
"", /* dynamic desc */
@@ -3546,7 +3052,7 @@ quest_type quest[MAX_Q_IDX] =
},
/* Library */
{
- FALSE,
+ false,
"Library quest",
{
"", /* dynamic desc */
@@ -3560,7 +3066,7 @@ quest_type quest[MAX_Q_IDX] =
},
/* God quest */
{
- FALSE,
+ false,
"God quest",
{
"", /* dynamic desc */
@@ -3575,7 +3081,7 @@ quest_type quest[MAX_Q_IDX] =
4 /* dun_maxdepth */,
0 /* dun_minplev */,
0 /* relic_gen_tries */,
- FALSE /* relic_generated */,
+ false /* relic_generated */,
1 /* dung_x */,
1 /* dung_y */,
},
@@ -3587,94 +3093,94 @@ quest_type quest[MAX_Q_IDX] =
/* List of powers for Symbiants/Powers */
monster_power monster_powers[] =
{
- { SF_SHRIEK_IDX, "Aggravate Monster", 1, FALSE },
- { SF_MULTIPLY_IDX, "Multiply", 10, FALSE },
- { SF_S_ANIMAL_IDX, "Summon Animal", 30, FALSE },
- { SF_ROCKET_IDX, "Fire a Rocket", 40, TRUE },
- { SF_ARROW_1_IDX, "Light Arrow", 1, FALSE },
- { SF_ARROW_2_IDX, "Minor Arrow", 3, FALSE },
- { SF_ARROW_3_IDX, "Major Arrow", 7, TRUE },
- { SF_ARROW_4_IDX, "Great Arrow", 9, TRUE },
- { SF_BR_ACID_IDX, "Breathe Acid", 10, FALSE },
- { SF_BR_ELEC_IDX, "Breathe Lightning", 10, FALSE },
- { SF_BR_FIRE_IDX, "Breathe Fire", 10, FALSE },
- { SF_BR_COLD_IDX, "Breathe Cold", 10, FALSE },
- { SF_BR_POIS_IDX, "Breathe Poison", 15, TRUE },
- { SF_BR_NETH_IDX, "Breathe Nether", 30, TRUE },
- { SF_BR_LITE_IDX, "Breathe Light", 20, TRUE },
- { SF_BR_DARK_IDX, "Breathe Dark", 20, TRUE },
- { SF_BR_CONF_IDX, "Breathe Confusion", 15, TRUE },
- { SF_BR_SOUN_IDX, "Breathe Sound", 30, TRUE },
- { SF_BR_CHAO_IDX, "Breathe Chaos", 30, TRUE },
- { SF_BR_DISE_IDX, "Breathe Disenchantment", 30, TRUE },
- { SF_BR_NEXU_IDX, "Breathe Nexus", 30, TRUE },
- { SF_BR_TIME_IDX, "Breathe Time", 30, TRUE },
- { SF_BR_INER_IDX, "Breathe Inertia", 30, TRUE },
- { SF_BR_GRAV_IDX, "Breathe Gravity", 30, TRUE },
- { SF_BR_SHAR_IDX, "Breathe Shards", 30, TRUE },
- { SF_BR_PLAS_IDX, "Breathe Plasma", 30, TRUE },
- { SF_BR_WALL_IDX, "Breathe Force", 30, TRUE },
- { SF_BR_MANA_IDX, "Breathe Mana", 40, TRUE },
- { SF_BA_NUKE_IDX, "Nuke Ball", 30, TRUE },
- { SF_BR_NUKE_IDX, "Breathe Nuke", 40, TRUE },
- { SF_BA_CHAO_IDX, "Chaos Ball", 30, TRUE },
- { SF_BR_DISI_IDX, "Breathe Disintegration", 40, TRUE },
- { SF_BA_ACID_IDX, "Acid Ball", 8, FALSE },
- { SF_BA_ELEC_IDX, "Lightning Ball", 8, FALSE },
- { SF_BA_FIRE_IDX, "Fire Ball", 8, FALSE },
- { SF_BA_COLD_IDX, "Cold Ball", 8, FALSE },
- { SF_BA_POIS_IDX, "Poison Ball", 20, TRUE },
- { SF_BA_NETH_IDX, "Nether Ball", 20, TRUE },
- { SF_BA_WATE_IDX, "Water Ball", 20, TRUE },
- { SF_BA_MANA_IDX, "Mana Ball", 50, TRUE },
- { SF_BA_DARK_IDX, "Darkness Ball", 20, TRUE },
- { SF_CAUSE_1_IDX, "Cause Light Wounds", 20, FALSE },
- { SF_CAUSE_2_IDX, "Cause Medium Wounds", 30, FALSE },
- { SF_CAUSE_3_IDX, "Cause Critical Wounds", 35, TRUE },
- { SF_CAUSE_4_IDX, "Cause Mortal Wounds", 45, TRUE },
- { SF_BO_ACID_IDX, "Acid Bolt", 5, FALSE },
- { SF_BO_ELEC_IDX, "Lightning Bolt", 5, FALSE },
- { SF_BO_FIRE_IDX, "Fire Bolt", 5, FALSE },
- { SF_BO_COLD_IDX, "Cold Bolt", 5, FALSE },
- { SF_BO_POIS_IDX, "Poison Bolt", 10, TRUE },
- { SF_BO_NETH_IDX, "Nether Bolt", 15, TRUE },
- { SF_BO_WATE_IDX, "Water Bolt", 20, TRUE },
- { SF_BO_MANA_IDX, "Mana Bolt", 25, TRUE },
- { SF_BO_PLAS_IDX, "Plasma Bolt", 20, TRUE },
- { SF_BO_ICEE_IDX, "Ice Bolt", 20, TRUE },
- { SF_MISSILE_IDX, "Magic Missile", 1, FALSE },
- { SF_SCARE_IDX, "Scare", 4, FALSE },
- { SF_BLIND_IDX, "Blindness", 6, FALSE },
- { SF_CONF_IDX, "Confusion", 7, FALSE },
- { SF_SLOW_IDX, "Slowness", 10, FALSE },
- { SF_HOLD_IDX, "Paralyse", 10, FALSE },
- { SF_HASTE_IDX, "Haste Self", 50, FALSE },
- { SF_HAND_DOOM_IDX, "Hand of Doom", 30, TRUE },
- { SF_HEAL_IDX, "Healing", 60, FALSE },
- { SF_S_ANIMALS_IDX, "Summon Animals", 60, TRUE },
- { SF_BLINK_IDX, "Phase Door", 2, FALSE },
- { SF_TPORT_IDX, "Teleport", 10, FALSE },
- { SF_TELE_TO_IDX, "Teleport To", 20, TRUE },
- { SF_TELE_AWAY_IDX, "Teleport Away", 20, FALSE },
- { SF_TELE_LEVEL_IDX, "Teleport Level", 20, TRUE },
- { SF_DARKNESS_IDX, "Darkness", 3, FALSE },
- { SF_RAISE_DEAD_IDX, "Raise the Dead", 400, TRUE },
- { SF_S_THUNDERLORD_IDX, "Summon Thunderlords", 90, TRUE },
- { SF_S_KIN_IDX, "Summon Kin", 80, FALSE },
- { SF_S_HI_DEMON_IDX, "Summon Greater Demons", 90, TRUE },
- { SF_S_MONSTER_IDX, "Summon Monster", 50, FALSE },
- { SF_S_MONSTERS_IDX, "Summon Monsters", 60, TRUE },
- { SF_S_ANT_IDX, "Summon Ants", 30, FALSE },
- { SF_S_SPIDER_IDX, "Summon Spider", 30, FALSE },
- { SF_S_HOUND_IDX, "Summon Hound", 50, TRUE },
- { SF_S_HYDRA_IDX, "Summon Hydra", 40, TRUE },
- { SF_S_ANGEL_IDX, "Summon Angel", 60, TRUE },
- { SF_S_DEMON_IDX, "Summon Demon", 60, TRUE },
- { SF_S_UNDEAD_IDX, "Summon Undead", 70, TRUE },
- { SF_S_DRAGON_IDX, "Summon Dragon", 70, TRUE },
- { SF_S_HI_UNDEAD_IDX, "Summon High Undead", 90, TRUE },
- { SF_S_HI_DRAGON_IDX, "Summon High Dragon", 90, TRUE },
- { SF_S_WRAITH_IDX, "Summon Wraith", 90, TRUE },
+ { SF_SHRIEK_IDX, "Aggravate Monster", 1, false },
+ { SF_MULTIPLY_IDX, "Multiply", 10, false },
+ { SF_S_ANIMAL_IDX, "Summon Animal", 30, false },
+ { SF_ROCKET_IDX, "Fire a Rocket", 40, true },
+ { SF_ARROW_1_IDX, "Light Arrow", 1, false },
+ { SF_ARROW_2_IDX, "Minor Arrow", 3, false },
+ { SF_ARROW_3_IDX, "Major Arrow", 7, true },
+ { SF_ARROW_4_IDX, "Great Arrow", 9, true },
+ { SF_BR_ACID_IDX, "Breathe Acid", 10, false },
+ { SF_BR_ELEC_IDX, "Breathe Lightning", 10, false },
+ { SF_BR_FIRE_IDX, "Breathe Fire", 10, false },
+ { SF_BR_COLD_IDX, "Breathe Cold", 10, false },
+ { SF_BR_POIS_IDX, "Breathe Poison", 15, true },
+ { SF_BR_NETH_IDX, "Breathe Nether", 30, true },
+ { SF_BR_LITE_IDX, "Breathe Light", 20, true },
+ { SF_BR_DARK_IDX, "Breathe Dark", 20, true },
+ { SF_BR_CONF_IDX, "Breathe Confusion", 15, true },
+ { SF_BR_SOUN_IDX, "Breathe Sound", 30, true },
+ { SF_BR_CHAO_IDX, "Breathe Chaos", 30, true },
+ { SF_BR_DISE_IDX, "Breathe Disenchantment", 30, true },
+ { SF_BR_NEXU_IDX, "Breathe Nexus", 30, true },
+ { SF_BR_TIME_IDX, "Breathe Time", 30, true },
+ { SF_BR_INER_IDX, "Breathe Inertia", 30, true },
+ { SF_BR_GRAV_IDX, "Breathe Gravity", 30, true },
+ { SF_BR_SHAR_IDX, "Breathe Shards", 30, true },
+ { SF_BR_PLAS_IDX, "Breathe Plasma", 30, true },
+ { SF_BR_WALL_IDX, "Breathe Force", 30, true },
+ { SF_BR_MANA_IDX, "Breathe Mana", 40, true },
+ { SF_BA_NUKE_IDX, "Nuke Ball", 30, true },
+ { SF_BR_NUKE_IDX, "Breathe Nuke", 40, true },
+ { SF_BA_CHAO_IDX, "Chaos Ball", 30, true },
+ { SF_BR_DISI_IDX, "Breathe Disintegration", 40, true },
+ { SF_BA_ACID_IDX, "Acid Ball", 8, false },
+ { SF_BA_ELEC_IDX, "Lightning Ball", 8, false },
+ { SF_BA_FIRE_IDX, "Fire Ball", 8, false },
+ { SF_BA_COLD_IDX, "Cold Ball", 8, false },
+ { SF_BA_POIS_IDX, "Poison Ball", 20, true },
+ { SF_BA_NETH_IDX, "Nether Ball", 20, true },
+ { SF_BA_WATE_IDX, "Water Ball", 20, true },
+ { SF_BA_MANA_IDX, "Mana Ball", 50, true },
+ { SF_BA_DARK_IDX, "Darkness Ball", 20, true },
+ { SF_CAUSE_1_IDX, "Cause Light Wounds", 20, false },
+ { SF_CAUSE_2_IDX, "Cause Medium Wounds", 30, false },
+ { SF_CAUSE_3_IDX, "Cause Critical Wounds", 35, true },
+ { SF_CAUSE_4_IDX, "Cause Mortal Wounds", 45, true },
+ { SF_BO_ACID_IDX, "Acid Bolt", 5, false },
+ { SF_BO_ELEC_IDX, "Lightning Bolt", 5, false },
+ { SF_BO_FIRE_IDX, "Fire Bolt", 5, false },
+ { SF_BO_COLD_IDX, "Cold Bolt", 5, false },
+ { SF_BO_POIS_IDX, "Poison Bolt", 10, true },
+ { SF_BO_NETH_IDX, "Nether Bolt", 15, true },
+ { SF_BO_WATE_IDX, "Water Bolt", 20, true },
+ { SF_BO_MANA_IDX, "Mana Bolt", 25, true },
+ { SF_BO_PLAS_IDX, "Plasma Bolt", 20, true },
+ { SF_BO_ICEE_IDX, "Ice Bolt", 20, true },
+ { SF_MISSILE_IDX, "Magic Missile", 1, false },
+ { SF_SCARE_IDX, "Scare", 4, false },
+ { SF_BLIND_IDX, "Blindness", 6, false },
+ { SF_CONF_IDX, "Confusion", 7, false },
+ { SF_SLOW_IDX, "Slowness", 10, false },
+ { SF_HOLD_IDX, "Paralyse", 10, false },
+ { SF_HASTE_IDX, "Haste Self", 50, false },
+ { SF_HAND_DOOM_IDX, "Hand of Doom", 30, true },
+ { SF_HEAL_IDX, "Healing", 60, false },
+ { SF_S_ANIMALS_IDX, "Summon Animals", 60, true },
+ { SF_BLINK_IDX, "Phase Door", 2, false },
+ { SF_TPORT_IDX, "Teleport", 10, false },
+ { SF_TELE_TO_IDX, "Teleport To", 20, true },
+ { SF_TELE_AWAY_IDX, "Teleport Away", 20, false },
+ { SF_TELE_LEVEL_IDX, "Teleport Level", 20, true },
+ { SF_DARKNESS_IDX, "Darkness", 3, false },
+ { SF_RAISE_DEAD_IDX, "Raise the Dead", 400, true },
+ { SF_S_THUNDERLORD_IDX, "Summon Thunderlords", 90, true },
+ { SF_S_KIN_IDX, "Summon Kin", 80, false },
+ { SF_S_HI_DEMON_IDX, "Summon Greater Demons", 90, true },
+ { SF_S_MONSTER_IDX, "Summon Monster", 50, false },
+ { SF_S_MONSTERS_IDX, "Summon Monsters", 60, true },
+ { SF_S_ANT_IDX, "Summon Ants", 30, false },
+ { SF_S_SPIDER_IDX, "Summon Spider", 30, false },
+ { SF_S_HOUND_IDX, "Summon Hound", 50, true },
+ { SF_S_HYDRA_IDX, "Summon Hydra", 40, true },
+ { SF_S_ANGEL_IDX, "Summon Angel", 60, true },
+ { SF_S_DEMON_IDX, "Summon Demon", 60, true },
+ { SF_S_UNDEAD_IDX, "Summon Undead", 70, true },
+ { SF_S_DRAGON_IDX, "Summon Dragon", 70, true },
+ { SF_S_HI_UNDEAD_IDX, "Summon High Undead", 90, true },
+ { SF_S_HI_DRAGON_IDX, "Summon High Dragon", 90, true },
+ { SF_S_WRAITH_IDX, "Summon Wraith", 90, true },
};
@@ -3718,7 +3224,6 @@ tval_desc tvals[] =
{ TV_DAEMON_BOOK, "Daemon Book" },
{ TV_SPIKE, "Spikes" },
{ TV_DIGGING, "Digger" },
- { TV_CHEST, "Chest" },
{ TV_FOOD, "Food" },
{ TV_FLASK, "Flask" },
{ TV_MSTAFF, "Mage Staff" },
@@ -3965,7 +3470,7 @@ tval_desc tval_descs[] =
/*
* List of the between exits
* s16b corresp; Corresponding between gate
- * bool_ dungeon; Do we exit in a dungeon or in the wild ?
+ * bool dungeon; Do we exit in a dungeon or in the wild ?
*
* s16b wild_x, wild_y; Wilderness spot to land onto
* s16b p_ptr->px, p_ptr->py; Location of the map
@@ -3977,14 +3482,12 @@ between_exit between_exits[MAX_BETWEEN_EXITS] =
{
{
1,
- FALSE,
49, 11,
119, 25,
0, 0
},
{
0,
- FALSE,
60, 56,
10, 35,
0, 0
@@ -3992,7 +3495,6 @@ between_exit between_exits[MAX_BETWEEN_EXITS] =
/* Theme: Minas Tirith -> Gondolin link */
{
0,
- FALSE,
3, 11,
119, 25,
0, 0
@@ -4090,7 +3592,6 @@ gf_name_type gf_names[] =
{ GF_DOMINATION, "domination" },
{ GF_DISP_GOOD, "dispel good" },
{ GF_RAISE, "raise dead" },
- { GF_STAR_IDENTIFY, "*identification*" },
{ GF_DESTRUCTION, "destruction" },
{ GF_STUN_CONF, "stunning and confusion" },
{ GF_STUN_DAM, "stunning and damage" },
@@ -4116,7 +3617,7 @@ module_type modules[MAX_MODULES] =
{
{
{ "ToME",
- { 2, 4, 0 },
+ { 2, 4, 1 },
{ "DarkGod", "darkgod@t-o-m-e.net" },
"The Tales of Middle-earth, the standard and official game.\n"
"You are set on a quest to investigate the old tower of Dol Guldur.\n"
diff --git a/src/tables.h b/src/tables.h
deleted file mode 100644
index 9a5cfb58..00000000
--- a/src/tables.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-// C linkage required for these functions since main-* code uses them.
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern char hexsym[16];
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/src/tables.hpp b/src/tables.hpp
index 613dbddb..2798a38a 100644
--- a/src/tables.hpp
+++ b/src/tables.hpp
@@ -1,10 +1,10 @@
#pragma once
-#include "angband.h"
#include "activation.hpp"
#include "between_exit.hpp"
#include "body.hpp"
#include "cli_comm_fwd.hpp"
+#include "defines.hpp"
#include "flags_group.hpp"
#include "gf_name_type.hpp"
#include "inscription_info_type.hpp"
@@ -48,10 +48,10 @@ extern byte adj_con_mhp[];
extern byte blows_table[12][12];
extern byte extract_energy[300];
extern s32b player_exp[PY_MAX_LEVEL];
-extern cptr color_names[16];
-extern cptr stat_names[6];
-extern cptr stat_names_reduced[6];
-extern cptr window_flag_desc[32];
+extern const char *color_names[16];
+extern const char *stat_names[6];
+extern const char *stat_names_reduced[6];
+extern const char *window_flag_desc[32];
extern martial_arts bear_blows[MAX_BEAR];
extern martial_arts ma_blows[MAX_MA];
extern magic_power mindcraft_powers[MAX_MINDCRAFT_POWERS];
@@ -62,19 +62,18 @@ extern move_info_type move_info[9];
extern tactic_info_type tactic_info[9];
extern activation activation_info[MAX_T_ACT];
extern inscription_info_type inscription_info[MAX_INSCRIPTIONS];
-extern cptr sense_desc[];
std::vector<flags_group> const &flags_groups();
-extern power_type powers_type[POWER_MAX];
-extern cptr artifact_names_list;
+extern const char *artifact_names_list;
extern monster_power monster_powers[MONSTER_POWERS_MAX];
extern tval_desc tvals[];
extern tval_desc tval_descs[];
extern between_exit between_exits[MAX_BETWEEN_EXITS];
extern int month_day[9];
-extern cptr month_name[9];
+extern const char *month_name[9];
extern cli_comm *cli_info;
extern int cli_total;
extern quest_type quest[MAX_Q_IDX];
extern int max_body_part[BODY_MAX];
extern gf_name_type gf_names[];
extern module_type modules[MAX_MODULES];
+extern char hexsym[16];
diff --git a/src/tactic_info_type.hpp b/src/tactic_info_type.hpp
index 4cb330f4..f37e1dad 100644
--- a/src/tactic_info_type.hpp
+++ b/src/tactic_info_type.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
/**
* Tactics descriptor.
@@ -12,5 +12,5 @@ struct tactic_info_type
s16b to_ac;
s16b to_stealth;
s16b to_saving;
- cptr name;
+ const char *name;
};
diff --git a/src/timer_type.hpp b/src/timer_type.hpp
index d682b3bd..dac56692 100644
--- a/src/timer_type.hpp
+++ b/src/timer_type.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include <functional>
diff --git a/src/town_type.hpp b/src/town_type.hpp
index 0b903138..738f4bec 100644
--- a/src/town_type.hpp
+++ b/src/town_type.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "seed.hpp"
#include "store_type_fwd.hpp"
@@ -11,7 +11,7 @@
*/
struct town_type
{
- cptr name = nullptr;
+ const char *name = nullptr;
seed_t seed = seed_t::system(); /* Seed for RNG */
@@ -19,7 +19,7 @@ struct town_type
byte flags = 0; /* Town flags */
- bool_ stocked = FALSE; /* Is the town actualy stocked ? */
+ bool stocked = false; /* Is the town actualy stocked ? */
- bool_ destroyed = FALSE; /* Is the town destroyed? */
+ bool destroyed = false; /* Is the town destroyed? */
};
diff --git a/src/util.cc b/src/util.cc
index 7d795828..4928a294 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -3,7 +3,6 @@
/* Purpose: Angband utilities -BEN- */
#include "util.hpp"
-#include "util.h"
#include "cli_comm.hpp"
#include "cmd3.hpp"
@@ -18,22 +17,140 @@
#include "player_race.hpp"
#include "player_race_mod.hpp"
#include "player_type.hpp"
-#include "tables.h"
#include "tables.hpp"
#include "timer_type.hpp"
-#include "variable.h"
#include "variable.hpp"
#include "xtra1.hpp"
+#include "z-form.hpp"
#include <boost/algorithm/string/predicate.hpp>
#include <chrono>
+#include <cstdio>
+#include <fcntl.h>
+#include <fmt/format.h>
#include <sstream>
#include <thread>
+#ifdef SET_UID
+#include <pwd.h>
+#endif
+
using boost::algorithm::iequals;
+using boost::algorithm::equals;
+using boost::algorithm::starts_with;
using std::this_thread::sleep_for;
using std::chrono::milliseconds;
+
+enum class display_option_t {
+ IMMEDIATE,
+ DELAY,
+};
+
+/*
+ * Read a number at a specific location on the screen
+ *
+ * Allow numbers of any size and save the last keypress.
+ */
+static std::tuple<u32b, char> get_number(u32b def, u32b max, int y, int x, display_option_t display_option)
+{
+ auto display_number = [x, y](u32b i)
+ {
+ prt(fmt::format("{}", i), y, x);
+ };
+
+ /* Player has not typed anything yet */
+ bool no_keys = true;
+
+ /* Begin the input with default */
+ u32b res = def;
+
+ /* Display? */
+ switch (display_option)
+ {
+ case display_option_t::IMMEDIATE:
+ // Show current value immediately
+ display_number(res);
+ break;
+ case display_option_t::DELAY:
+ // Don't show
+ break;
+ }
+
+ /* Get a command count */
+ while (true)
+ {
+ /* Get a new keypress */
+ char key = inkey();
+
+ /* Simple editing (delete or backspace) */
+ if ((key == 0x7F) || (key == KTRL('H')))
+ {
+ /* Override the default */
+ no_keys = false;
+
+ /* Delete a digit */
+ res = res / 10;
+
+ display_number(res);
+ }
+
+ /* Actual numeric data */
+ else if (key >= '0' && key <= '9')
+ {
+ /* Override the default */
+ if (no_keys)
+ {
+ no_keys = false;
+ res = 0;
+ }
+
+ /* Don't overflow */
+ if (((u32b)(0 - 1) - D2I(key)) / 10 < res)
+ {
+ /* Warn */
+ bell();
+
+ /* Limit */
+ res = (max + 1 == 0) ? (u32b)(0 - 1) : max;
+ }
+
+ /* Stop count at maximum */
+ else if (res * 10 + D2I(key) > max)
+ {
+ /* Warn */
+ bell();
+
+ /* Limit */
+ res = max;
+ }
+
+ /* Increase count */
+ else
+ {
+ /* Incorporate that digit */
+ res = res * 10 + D2I(key);
+ }
+
+ /* Show current count */
+ display_number(res);
+ }
+
+ /* Escape cancels */
+ else if (key == ESCAPE)
+ {
+ return { 0, key };
+ }
+
+ /* Exit on "unusable" input */
+ else
+ {
+ return { res, key };
+ }
+ }
+}
+
+
/*
* Find a default user name from the system.
*/
@@ -94,11 +211,11 @@ std::string user_name()
* But leading tilde symbols must be handled in a special way
* Replace "~/" by the home directory of the current user
*/
-errr path_parse(char *buf, int max, cptr file)
+errr path_parse(char *buf, int max, const char *file)
{
- cptr u, s;
- struct passwd *pw;
-
+ const char *u;
+ const char *s;
+ struct passwd *pw;
/* Assume no result */
buf[0] = '\0';
@@ -154,7 +271,7 @@ errr path_parse(char *buf, int max, cptr file)
* This requires no special processing on simple machines,
* except for verifying the size of the filename.
*/
-errr path_parse(char *buf, int max, cptr file)
+errr path_parse(char *buf, int max, const char *file)
{
/* Accept the filename */
strnfmt(buf, max, "%s", file);
@@ -180,7 +297,7 @@ errr path_parse(char *buf, int max, cptr file)
* Note that this function yields a path which must be "parsed"
* using the "parse" function above.
*/
-errr path_build(char *buf, int max, cptr path, cptr file)
+errr path_build(char *buf, int max, const char *path, const char *file)
{
/* Special file */
if (file[0] == '~')
@@ -190,7 +307,7 @@ errr path_build(char *buf, int max, cptr path, cptr file)
}
/* Absolute file, on "normal" systems */
- else if (prefix(file, PATH_SEP) && !streq(PATH_SEP, ""))
+ else if (starts_with(file, PATH_SEP) && !equals(PATH_SEP, ""))
{
/* Use the file itself */
strnfmt(buf, max, "%s", file);
@@ -218,7 +335,7 @@ errr path_build(char *buf, int max, cptr path, cptr file)
/*
* Hack -- replacement for "fopen()"
*/
-FILE *my_fopen(cptr file, cptr mode)
+FILE *my_fopen(const char *file, const char *mode)
{
char buf[1024];
@@ -255,11 +372,11 @@ errr my_fclose(FILE *fff)
*
* Process tabs, strip internal non-printables
*/
-errr my_fgets(FILE *fff, char *buf, huge n)
+errr my_fgets(FILE *fff, char *buf, unsigned long n)
{
- huge i = 0;
+ unsigned long i = 0;
- while (TRUE)
+ while (true)
{
int c = fgetc(fff);
@@ -336,7 +453,7 @@ errr my_fgets(FILE *fff, char *buf, huge n)
/*
* Hack -- attempt to delete a file
*/
-errr fd_kill(cptr file)
+errr fd_kill(const char *file)
{
char buf[1024];
@@ -354,7 +471,7 @@ errr fd_kill(cptr file)
/*
* Hack -- attempt to move a file
*/
-errr fd_move(cptr file, cptr what)
+errr fd_move(const char *file, const char *what)
{
char buf[1024];
char aux[1024];
@@ -381,7 +498,7 @@ errr fd_move(cptr file, cptr what)
* Note that we assume that the file should be "binary"
*
*/
-int fd_make(cptr file, int mode)
+int fd_make(const char *file, int mode)
{
char buf[1024];
@@ -401,7 +518,7 @@ return (open(buf, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode));
*
* Note that we assume that the file should be "binary"
*/
-int fd_open(cptr file, int flags)
+int fd_open(const char *file, int flags)
{
char buf[1024];
@@ -418,7 +535,7 @@ return (open(buf, flags | O_BINARY, 0));
/*
* Hack -- attempt to seek on a file descriptor
*/
-errr fd_seek(int fd, huge n)
+errr fd_seek(int fd, unsigned long n)
{
s32b p;
@@ -432,7 +549,7 @@ errr fd_seek(int fd, huge n)
if (p < 0) return (1);
/* Failure */
- if ((huge)p != n) return (1);
+ if ((unsigned long)p != n) return (1);
/* Success */
return (0);
@@ -442,7 +559,7 @@ errr fd_seek(int fd, huge n)
/*
* Hack -- attempt to read data from a file descriptor
*/
-errr fd_read(int fd, char *buf, huge n)
+errr fd_read(int fd, char *buf, unsigned long n)
{
/* Verify the fd */
if (fd < 0) return ( -1);
@@ -465,7 +582,7 @@ errr fd_read(int fd, char *buf, huge n)
#endif
/* Read the final piece */
- if ((huge)read(fd, buf, n) != n) return (1);
+ if ((unsigned long)read(fd, buf, n) != n) return (1);
/* Success */
return (0);
@@ -475,7 +592,7 @@ errr fd_read(int fd, char *buf, huge n)
/*
* Hack -- Attempt to write data to a file descriptor
*/
-errr fd_write(int fd, cptr buf, huge n)
+errr fd_write(int fd, const char *buf, unsigned long n)
{
/* Verify the fd */
if (fd < 0) return ( -1);
@@ -498,7 +615,7 @@ errr fd_write(int fd, cptr buf, huge n)
#endif
/* Write the final piece */
- if ((huge)write(fd, buf, n) != n) return (1);
+ if ((unsigned long)write(fd, buf, n) != n) return (1);
/* Success */
return (0);
@@ -567,20 +684,11 @@ errr fd_close(int fd)
*/
-/*
-* Move the cursor
-*/
-void move_cursor(int row, int col)
-{
- Term_gotoxy(col, row);
-}
-
-
/*
* Convert a decimal to a single digit octal number
*/
-static char octify(uint i)
+static char octify(unsigned int i)
{
return (hexsym[i % 8]);
}
@@ -588,7 +696,7 @@ static char octify(uint i)
/*
* Convert a decimal to a single digit hex number
*/
-static char hexify(uint i)
+static char hexify(unsigned int i)
{
return (hexsym[i % 16]);
}
@@ -615,25 +723,25 @@ static int dehex(char c)
}
-static void trigger_text_to_ascii(char **bufptr, cptr *strptr)
+static void trigger_text_to_ascii(char **bufptr, const char **strptr)
{
char *s = *bufptr;
- cptr str = *strptr;
- bool_ mod_status[MAX_MACRO_MOD];
+ const char *str = *strptr;
+ bool mod_status[MAX_MACRO_MOD];
int i, len = 0;
int shiftstatus = 0;
- cptr key_code;
+ const char *key_code;
if (macro_template == NULL)
return;
for (i = 0; macro_modifier_chr[i]; i++)
- mod_status[i] = FALSE;
+ mod_status[i] = false;
str++;
/* Examine modifier keys */
- while (1)
+ while (true)
{
for (i = 0; macro_modifier_chr[i]; i++)
{
@@ -643,7 +751,7 @@ static void trigger_text_to_ascii(char **bufptr, cptr *strptr)
}
if (!macro_modifier_chr[i]) break;
str += len;
- mod_status[i] = TRUE;
+ mod_status[i] = true;
if ('S' == macro_modifier_chr[i])
shiftstatus = 1;
}
@@ -701,8 +809,7 @@ static void trigger_text_to_ascii(char **bufptr, cptr *strptr)
*s++ = (char)13;
*bufptr = s;
- *strptr = str; /* where **strptr == ']' */
- return;
+ *strptr = str;
}
@@ -713,7 +820,7 @@ static void trigger_text_to_ascii(char **bufptr, cptr *strptr)
* parsing "\xFF" into a (signed) char. Whoever thought of making
* the "sign" of a "char" undefined is a complete moron. Oh well.
*/
-void text_to_ascii(char *buf, cptr str)
+void text_to_ascii(char *buf, const char *str)
{
char *s = buf;
@@ -838,16 +945,16 @@ void text_to_ascii(char *buf, cptr str)
}
-bool_ trigger_ascii_to_text(char **bufptr, cptr *strptr)
+static bool trigger_ascii_to_text(char **bufptr, const char **strptr)
{
char *s = *bufptr;
- cptr str = *strptr;
+ const char *str = *strptr;
char key_code[100];
int i;
- cptr tmp;
+ const char *tmp;
if (macro_template == NULL)
- return FALSE;
+ return false;
*s++ = '\\';
*s++ = '[';
@@ -874,11 +981,11 @@ bool_ trigger_ascii_to_text(char **bufptr, cptr *strptr)
key_code[j] = '\0';
break;
default:
- if (ch != *str) return FALSE;
+ if (ch != *str) return false;
str++;
}
}
- if (*str++ != (char)13) return FALSE;
+ if (*str++ != (char)13) return false;
for (i = 0; i < max_macrotrigger; i++)
{
@@ -887,7 +994,7 @@ bool_ trigger_ascii_to_text(char **bufptr, cptr *strptr)
break;
}
if (i == max_macrotrigger)
- return FALSE;
+ return false;
tmp = macro_trigger_name[i];
while (*tmp) *s++ = *tmp++;
@@ -896,14 +1003,14 @@ bool_ trigger_ascii_to_text(char **bufptr, cptr *strptr)
*bufptr = s;
*strptr = str;
- return TRUE;
+ return true;
}
/*
* Hack -- convert a string into a printable form
*/
-void ascii_to_text(char *buf, cptr str)
+void ascii_to_text(char *buf, const char *str)
{
char *s = buf;
@@ -1005,13 +1112,13 @@ void ascii_to_text(char *buf, cptr str)
/*
* Determine if any macros have ever started with a given character.
*/
-static bool_ macro__use[256];
+static bool macro__use[256];
/*
* Find the macro (if any) which exactly matches the given pattern
*/
-sint macro_find_exact(cptr pat)
+int macro_find_exact(const char *pat)
{
int i;
@@ -1025,7 +1132,7 @@ sint macro_find_exact(cptr pat)
for (i = 0; i < macro__num; ++i)
{
/* Skip macros which do not match the pattern */
- if (!streq(macro__pat[i], pat)) continue;
+ if (!equals(macro__pat[i], pat)) continue;
/* Found one */
return (i);
@@ -1039,7 +1146,7 @@ sint macro_find_exact(cptr pat)
/*
* Find the first macro (if any) which contains the given pattern
*/
-static sint macro_find_check(cptr pat)
+static int macro_find_check(const char *pat)
{
int i;
@@ -1053,7 +1160,7 @@ static sint macro_find_check(cptr pat)
for (i = 0; i < macro__num; ++i)
{
/* Skip macros which do not contain the pattern */
- if (!prefix(macro__pat[i], pat)) continue;
+ if (!starts_with(macro__pat[i], pat)) continue;
/* Found one */
return (i);
@@ -1067,7 +1174,7 @@ static sint macro_find_check(cptr pat)
/*
* Find the first macro (if any) which contains the given pattern and more
*/
-static sint macro_find_maybe(cptr pat)
+static int macro_find_maybe(const char *pat)
{
int i;
@@ -1081,10 +1188,10 @@ static sint macro_find_maybe(cptr pat)
for (i = 0; i < macro__num; ++i)
{
/* Skip macros which do not contain the pattern */
- if (!prefix(macro__pat[i], pat)) continue;
+ if (!starts_with(macro__pat[i], pat)) continue;
/* Skip macros which exactly match the pattern XXX XXX */
- if (streq(macro__pat[i], pat)) continue;
+ if (equals(macro__pat[i], pat)) continue;
/* Found one */
return (i);
@@ -1098,7 +1205,7 @@ static sint macro_find_maybe(cptr pat)
/*
* Find the longest macro (if any) which starts with the given pattern
*/
-static sint macro_find_ready(cptr pat)
+static int macro_find_ready(const char *pat)
{
int i, t, n = -1, s = -1;
@@ -1112,7 +1219,7 @@ static sint macro_find_ready(cptr pat)
for (i = 0; i < macro__num; ++i)
{
/* Skip macros which are not contained by the pattern */
- if (!prefix(pat, macro__pat[i])) continue;
+ if (!starts_with(pat, macro__pat[i])) continue;
/* Obtain the length of this macro */
t = strlen(macro__pat[i]);
@@ -1144,7 +1251,7 @@ static sint macro_find_ready(cptr pat)
* with some kind of "powerful keymap" ability, but this might make it hard
* to change the "roguelike" option from inside the game. XXX XXX XXX
*/
-errr macro_add(cptr pat, cptr act)
+errr macro_add(const char *pat, const char *act)
{
int n;
@@ -1177,7 +1284,7 @@ errr macro_add(cptr pat, cptr act)
macro__act[n] = strdup(act);
/* Efficiency */
- macro__use[(byte)(pat[0])] = TRUE;
+ macro__use[(byte)(pat[0])] = true;
/* Success */
return (0);
@@ -1188,7 +1295,7 @@ errr macro_add(cptr pat, cptr act)
/*
* Local "need flush" variable
*/
-static bool_ flush_later = FALSE;
+static bool flush_later = false;
/*
@@ -1196,14 +1303,14 @@ static bool_ flush_later = FALSE;
*
* Do not match any macros until "ascii 30" is found.
*/
-static bool_ parse_macro = FALSE;
+static bool parse_macro = false;
/*
* Local variable -- we are inside a "macro trigger"
*
* Strip all keypresses until a low ascii value is found.
*/
-static bool_ parse_under = FALSE;
+static bool parse_under = false;
/*
@@ -1216,7 +1323,7 @@ static bool_ parse_under = FALSE;
void flush()
{
/* Do it later */
- flush_later = TRUE;
+ flush_later = true;
}
@@ -1275,17 +1382,18 @@ static char inkey_aux()
char ch;
- cptr pat, act;
+ const char *pat;
+ const char *act;
char buf[1024];
/* Wait for a keypress */
- (Term_inkey(&ch, TRUE, TRUE));
+ Term_inkey(&ch, true, true);
/* End "macro action" */
- if (ch == 30) parse_macro = FALSE;
+ if (ch == 30) parse_macro = false;
/* Inside "macro action" */
if (ch == 30) return (ch);
@@ -1310,7 +1418,7 @@ static char inkey_aux()
/* Wait for a macro, or a timeout */
- while (TRUE)
+ while (true)
{
/* Check for pending macro */
k = macro_find_maybe(buf);
@@ -1319,7 +1427,7 @@ static char inkey_aux()
if (k < 0) break;
/* Check for (and remove) a pending key */
- if (0 == Term_inkey(&ch, FALSE, TRUE))
+ if (0 == Term_inkey(&ch, false, true))
{
/* Append the key */
buf[p++] = ch;
@@ -1358,7 +1466,7 @@ static char inkey_aux()
}
/* Wait for (and remove) a pending key */
- Term_inkey(&ch, TRUE, TRUE);
+ Term_inkey(&ch, true, true);
/* Return the key */
return (ch);
@@ -1380,7 +1488,7 @@ static char inkey_aux()
/* Begin "macro action" */
- parse_macro = TRUE;
+ parse_macro = true;
/* Push the "end of macro action" key */
if (Term_key_push(30)) return (0);
@@ -1413,34 +1521,34 @@ static char inkey_aux()
* trigger any macros, and cannot be bypassed by the Borg. It is used
* in Angband to handle "keymaps".
*/
-static cptr inkey_next = NULL;
+static const char *inkey_next = NULL;
-bool_ inkey_flag = FALSE;
+bool inkey_flag = false;
/*
* Get a keypress from the user.
*
* This function recognizes a few "global parameters". These are variables
-* which, if set to TRUE before calling this function, will have an effect
-* on this function, and which are always reset to FALSE by this function
+* which, if set to true before calling this function, will have an effect
+* on this function, and which are always reset to false by this function
* before this function returns. Thus they function just like normal
* parameters, except that most calls to this function can ignore them.
*
-* If "inkey_scan" is TRUE, then we will immediately return "zero" if no
+* If "inkey_scan" is true, then we will immediately return "zero" if no
* keypress is available, instead of waiting for a keypress.
*
-* If "inkey_base" is TRUE, then all macro processing will be bypassed.
-* If "inkey_base" and "inkey_scan" are both TRUE, then this function will
+* If "inkey_base" is true, then all macro processing will be bypassed.
+* If "inkey_base" and "inkey_scan" are both true, then this function will
* not return immediately, but will wait for a keypress for as long as the
* normal macro matching code would, allowing the direct entry of macro
* triggers. The "inkey_base" flag is extremely dangerous!
*
-* If "inkey_flag" is TRUE, then we will assume that we are waiting for a
+* If "inkey_flag" is true, then we will assume that we are waiting for a
* normal command, and we will only show the cursor if "hilite_player" is
-* TRUE (or if the player is in a store), instead of always showing the
+* true (or if the player is in a store), instead of always showing the
* cursor. The various "main-xxx.c" files should avoid saving the game
-* in response to a "menu item" request unless "inkey_flag" is TRUE, to
+* in response to a "menu item" request unless "inkey_flag" is true, to
* prevent savefile corruption.
*
* If we are waiting for a keypress, and no keypress is ready, then we will
@@ -1472,30 +1580,20 @@ bool_ inkey_flag = FALSE;
*
* Hack -- Note the use of "inkey_next" to allow "keymaps" to be processed.
*/
-static char inkey_real(bool_ inkey_scan)
+static char inkey_real(bool inkey_scan)
{
- int v;
-
- char kk;
-
- char ch = 0;
-
- bool_ done = FALSE;
-
- term *old = Term;
-
/* Hack -- Use the "inkey_next" pointer */
if (inkey_next && *inkey_next)
{
/* Get next character, and advance */
- ch = *inkey_next++;
+ char ch = *inkey_next++;
/* Cancel the various "global parameters" */
- inkey_base = inkey_flag = inkey_scan = FALSE;
+ inkey_base = inkey_flag = inkey_scan = false;
/* Accept result */
macro_recorder_add(ch);
- return (ch);
+ return ch;
}
/* Forget pointer */
@@ -1503,166 +1601,158 @@ static char inkey_real(bool_ inkey_scan)
/* Access cursor state */
- Term_get_cursor(&v);
-
- /* Show the cursor if waiting, except sometimes in "command" mode */
- if (!inkey_scan && (!inkey_flag || options->hilite_player || character_icky))
- {
- /* Show the cursor */
- Term_set_cursor(1);
- }
-
-
- /* Hack -- Activate main screen */
- Term_activate(angband_term[0]);
+ char ch = '\0';
+ Term_with_saved_cursor_visbility([&ch, &inkey_scan]() {
-
- /* Get a key */
- while (!ch)
- {
- /* Hack -- Handle "inkey_scan" */
- if (!inkey_base && inkey_scan &&
- (0 != Term_inkey(&kk, FALSE, FALSE)))
- {
- break;
- }
-
-
- /* Hack -- Flush output once when no key ready */
- if (!done && (0 != Term_inkey(&kk, FALSE, FALSE)))
+ /* Show the cursor if waiting, except sometimes in "command" mode */
+ if (!inkey_scan && (!inkey_flag || options->hilite_player || character_icky))
{
- /* Hack -- activate proper term */
- Term_activate(old);
-
- /* Flush output */
- Term_fresh();
-
- /* Hack -- activate main screen */
- Term_activate(angband_term[0]);
-
- /* Only once */
- done = TRUE;
+ Term_show_cursor();
}
-
- /* Hack -- Handle "inkey_base" */
- if (inkey_base)
- {
- int w = 0;
-
- /* Wait forever */
- if (!inkey_scan)
+ /* Hack -- Activate main screen */
+ auto old = Term;
+ Term_with_active(angband_term[0], [&ch, &old, &inkey_scan]() {
+ /* Have with flushed the output? */
+ bool flushed = false;
+ /* Get a key */
+ while (!ch)
{
- /* Wait for (and remove) a pending key */
- if (0 == Term_inkey(&ch, TRUE, TRUE))
- {
- /* Done */
- break;
- }
+ char kk;
- /* Oops */
- break;
- }
-
- /* Wait */
- while (TRUE)
- {
- /* Check for (and remove) a pending key */
- if (0 == Term_inkey(&ch, FALSE, TRUE))
+ /* Hack -- Handle "inkey_scan" */
+ if (!inkey_base && inkey_scan &&
+ (0 != Term_inkey(&kk, false, false)))
{
- /* Done */
break;
}
- /* No key ready */
- else
- {
- /* Increase "wait" */
- w += 10;
- /* Excessive delay */
- if (w >= 100) break;
+ /* Hack -- Flush output once when no key ready */
+ if (!flushed && (0 != Term_inkey(&kk, false, false)))
+ {
+ /* Hack -- activate proper term */
+ Term_with_active(old, []() {
+ Term_fresh();
+ });
- /* Delay */
- sleep_for(milliseconds(w));
+ /* Only once */
+ flushed = true;
}
- }
- /* Done */
- break;
- }
+ /* Hack -- Handle "inkey_base" */
+ if (inkey_base)
+ {
+ int w = 0;
- /* Get a key (see above) */
- ch = inkey_aux();
+ /* Wait forever */
+ if (!inkey_scan)
+ {
+ /* Wait for (and remove) a pending key */
+ if (0 == Term_inkey(&ch, true, true))
+ {
+ /* Done */
+ break;
+ }
+
+ /* Oops */
+ break;
+ }
+ /* Wait */
+ while (true)
+ {
+ /* Check for (and remove) a pending key */
+ if (0 == Term_inkey(&ch, false, true))
+ {
+ /* Done */
+ break;
+ }
+
+ /* No key ready */
+ else
+ {
+ /* Increase "wait" */
+ w += 10;
+
+ /* Excessive delay */
+ if (w >= 100) break;
+
+ /* Delay */
+ sleep_for(milliseconds(w));
+ }
+ }
- /* Handle "control-right-bracket" */
- if ((ch == 29) || ((!options->rogue_like_commands) && (ch == KTRL('D'))))
- {
- /* Strip this key */
- ch = 0;
+ /* Done */
+ break;
+ }
- /* Do an html dump */
- do_cmd_html_dump();
- /* Continue */
- continue;
- }
+ /* Get a key (see above) */
+ ch = inkey_aux();
- /* Treat back-quote as escape */
- if (ch == '`') ch = ESCAPE;
+ /* Handle "control-right-bracket" */
+ if ((ch == 29) || ((!options->rogue_like_commands) && (ch == KTRL('D'))))
+ {
+ /* Strip this key */
+ ch = 0;
+ /* Do an html dump */
+ do_cmd_html_dump();
- /* End "macro trigger" */
- if (parse_under && (ch <= 32))
- {
- /* Strip this key */
- ch = 0;
+ /* Continue */
+ continue;
+ }
- /* End "macro trigger" */
- parse_under = FALSE;
- }
+ /* Treat back-quote as escape */
+ if (ch == '`') ch = ESCAPE;
- /* Handle "control-caret" */
- if (ch == 30)
- {
- /* Strip this key */
- ch = 0;
- }
- /* Handle "control-underscore" */
- else if (ch == 31)
- {
- /* Strip this key */
- ch = 0;
+ /* End "macro trigger" */
+ if (parse_under && (ch <= 32))
+ {
+ /* Strip this key */
+ ch = 0;
- /* Begin "macro trigger" */
- parse_under = TRUE;
- }
+ /* End "macro trigger" */
+ parse_under = false;
+ }
- /* Inside "macro trigger" */
- else if (parse_under)
- {
- /* Strip this key */
- ch = 0;
- }
- }
+ /* Handle "control-caret" */
+ if (ch == 30)
+ {
+ /* Strip this key */
+ ch = 0;
+ }
- /* Hack -- restore the term */
- Term_activate(old);
+ /* Handle "control-underscore" */
+ else if (ch == 31)
+ {
+ /* Strip this key */
+ ch = 0;
+ /* Begin "macro trigger" */
+ parse_under = true;
+ }
- /* Restore the cursor */
- Term_set_cursor(v);
+ /* Inside "macro trigger" */
+ else if (parse_under)
+ {
+ /* Strip this key */
+ ch = 0;
+ }
+ }
+ });
- /* Cancel the various "global parameters" */
- inkey_base = inkey_flag = FALSE;
+ });
+ /* Cancel the various "global parameters" */
+ inkey_base = inkey_flag = false;
/* Return the keypress */
macro_recorder_add(ch);
@@ -1670,11 +1760,11 @@ static char inkey_real(bool_ inkey_scan)
}
char inkey() {
- return inkey_real(FALSE);
+ return inkey_real(false);
}
char inkey_scan() {
- return inkey_real(TRUE);
+ return inkey_real(true);
}
/*
@@ -1688,7 +1778,7 @@ static void msg_flush(int x)
Term_putstr(x, 0, -1, a, "-more-");
/* Get an acceptable keypress */
- while (1)
+ while (true)
{
int cmd = inkey();
if (options->quick_messages) break;
@@ -1702,7 +1792,7 @@ static void msg_flush(int x)
}
/* Display a message */
-void display_message(int x, int y, int split, byte color, cptr t)
+void display_message(int x, int y, int split, byte color, const char *t)
{
int i = 0, j = 0;
@@ -1756,7 +1846,7 @@ void display_message(int x, int y, int split, byte color, cptr t)
* XXX XXX XXX Note that "msg_print(NULL)" will clear the top line
* even if no messages are pending. This is probably a hack.
*/
-void cmsg_print(byte color, cptr msg)
+void cmsg_print(byte color, const char *msg)
{
auto &messages = game->messages;
@@ -1783,7 +1873,7 @@ void cmsg_print(byte color, cptr msg)
msg_flush(p);
/* Forget it */
- msg_flag = FALSE;
+ msg_flag = false;
/* Reset */
p = 0;
@@ -1877,7 +1967,7 @@ void cmsg_print(byte color, cptr msg)
}
/* Remember the message */
- msg_flag = TRUE;
+ msg_flag = true;
/* Remember the position */
p += n + 1;
@@ -1892,11 +1982,16 @@ void cmsg_print(byte color, std::string const &msg)
}
/* Hack -- for compatibility and easy sake */
-void msg_print(cptr msg)
+void msg_print(const char *msg)
{
cmsg_print(TERM_WHITE, msg);
}
+void msg_print(std::string const &msg)
+{
+ cmsg_print(TERM_WHITE, msg.c_str());
+}
+
/*
* Hack -- prevent "accidents" in "screen_save()" or "screen_load()"
@@ -1917,10 +2012,18 @@ void screen_save()
/* Save the screen (if legal) */
if (screen_depth++ == 0) Term_save();
- /* Increase "icky" depth */
- character_icky++;
+ /* Enter "icky" mode */
+ character_icky = true;
}
+void screen_save_no_flush()
+{
+ /* Enter "icky" mode */
+ character_icky = true;
+
+ /* Save the screen */
+ Term_save();
+}
/*
* Load the screen, and decrease the "icky" depth.
@@ -1935,15 +2038,24 @@ void screen_load()
/* Load the screen (if legal) */
if (--screen_depth == 0) Term_load();
- /* Decrease "icky" depth */
- character_icky--;
+ /* Leave "icky" mode */
+ character_icky = false;
+}
+
+void screen_load_no_flush()
+{
+ /* Restore the screen */
+ Term_load();
+
+ /* Leave "icky" mode */
+ character_icky = false;
}
/*
* Display a formatted message, using "vstrnfmt()" and "msg_print()".
*/
-void msg_format(cptr fmt, ...)
+void msg_format(const char *fmt, ...)
{
va_list vp;
@@ -1962,7 +2074,7 @@ void msg_format(cptr fmt, ...)
cmsg_print(TERM_WHITE, buf);
}
-void cmsg_format(byte color, cptr fmt, ...)
+void cmsg_format(byte color, const char *fmt, ...)
{
va_list vp;
@@ -1981,7 +2093,7 @@ void cmsg_format(byte color, cptr fmt, ...)
cmsg_print(color, buf);
}
-void c_put_str(byte attr, cptr str, int row, int col)
+void c_put_str(byte attr, const char *str, int row, int col)
{
Term_putstr(col, row, -1, attr, str);
}
@@ -1991,7 +2103,7 @@ void c_put_str(byte attr, std::string const &str, int row, int col)
Term_putstr(col, row, -1, attr, str.c_str());
}
-void put_str(cptr str, int row, int col)
+void put_str(const char *str, int row, int col)
{
Term_putstr(col, row, -1, TERM_WHITE, str);
}
@@ -2006,7 +2118,7 @@ void put_str(std::string const &str, int row, int col)
* Display a string on the screen using an attribute, and clear
* to the end of the line.
*/
-void c_prt(byte attr, cptr str, int row, int col)
+void c_prt(byte attr, const char *str, int row, int col)
{
/* Clear line, position cursor */
Term_erase(col, row, 255);
@@ -2020,7 +2132,7 @@ void c_prt(byte attr, std::string const &s, int row, int col)
c_prt(attr, s.c_str(), row, col);
}
-void prt(cptr str, int row, int col)
+void prt(const char *str, int row, int col)
{
c_prt(TERM_WHITE, str, row, col);
}
@@ -2044,7 +2156,7 @@ void prt(std::string const &s, int row, int col)
* This function will correctly handle any width up to the maximum legal
* value of 256, though it works best for a standard 80 character width.
*/
-void text_out_to_screen(byte a, cptr str)
+void text_out_to_screen(byte a, const char *str)
{
int x, y;
@@ -2052,7 +2164,7 @@ void text_out_to_screen(byte a, cptr str)
int wrap;
- cptr s;
+ const char *s;
/* Obtain the size */
@@ -2154,7 +2266,7 @@ void text_out_to_screen(byte a, cptr str)
* You must be careful to end all file output with a newline character
* to "flush" the stored line position.
*/
-void text_out_to_file(byte a, cptr str)
+void text_out_to_file(byte a, const char *str)
{
/* Current position on the line */
static int pos = 0;
@@ -2163,7 +2275,7 @@ void text_out_to_file(byte a, cptr str)
int wrap = 75;
/* Current location within "str" */
- cptr s = str;
+ const char *s = str;
/* Unused parameter */
a;
@@ -2258,9 +2370,6 @@ void text_out_to_file(byte a, cptr str)
/* Skip whitespace */
while (*s == ' ') s++;
}
-
- /* We are done */
- return;
}
@@ -2268,7 +2377,12 @@ void text_out_to_file(byte a, cptr str)
* Output text to the screen or to a file depending on the selected
* text_out hook.
*/
-void text_out(cptr str)
+void text_out(const char *str)
+{
+ text_out_c(TERM_WHITE, str);
+}
+
+void text_out(std::string const &str)
{
text_out_c(TERM_WHITE, str);
}
@@ -2278,12 +2392,15 @@ void text_out(cptr str)
* Output text to the screen (in color) or to a file depending on the
* selected hook.
*/
-void text_out_c(byte a, cptr str)
+void text_out_c(byte a, const char *str)
{
text_out_hook(a, str);
}
-
+void text_out_c(byte a, std::string const &str)
+{
+ text_out_c(a, str.c_str());
+}
/*
@@ -2316,7 +2433,7 @@ static char complete_buf[100];
static int complete_command(char *buf, int clen, int mlen)
{
int i, j = 1, max = clen;
- bool_ gotone = FALSE;
+ bool gotone = false;
/* Forget the characters after the end of the string. */
complete_buf[clen] = '\0';
@@ -2334,7 +2451,7 @@ static int complete_command(char *buf, int clen, int mlen)
if (!gotone)
{
sprintf(buf, "%.*s", mlen, cli_ptr->comm);
- gotone = TRUE;
+ gotone = true;
}
/* For later matches, simply notice how much of buf it
* matches. */
@@ -2379,12 +2496,12 @@ bool askfor_aux(std::string *buf, std::size_t max_len)
* Pressing RETURN right away accepts the default entry.
* Normal chars clear the default and append the char.
* Backspace clears the default or deletes the final char.
-* ESCAPE clears the buffer and the window and returns FALSE.
-* RETURN accepts the current buffer contents and returns TRUE.
+* ESCAPE clears the buffer and the window and returns false.
+* RETURN accepts the current buffer contents and returns true.
*/
-static bool_ askfor_aux_complete = FALSE;
+static bool askfor_aux_complete = false;
-bool_ askfor_aux(char *buf, int len)
+bool askfor_aux(char *buf, int len)
{
int y, x;
@@ -2394,7 +2511,7 @@ bool_ askfor_aux(char *buf, int len)
int wid, hgt;
- bool_ done = FALSE;
+ bool done = false;
/* Locate the cursor */
@@ -2439,13 +2556,13 @@ bool_ askfor_aux(char *buf, int len)
{
case ESCAPE:
k = 0;
- done = TRUE;
+ done = true;
break;
case '\n':
case '\r':
k = strlen(buf);
- done = TRUE;
+ done = true;
break;
case '\t':
@@ -2493,17 +2610,17 @@ bool_ askfor_aux(char *buf, int len)
}
/* Aborted */
- if (i == ESCAPE) return (FALSE);
+ if (i == ESCAPE) return false;
/* Success */
- return (TRUE);
+ return true;
}
-bool_ askfor_aux_with_completion(char *buf, int len)
+bool askfor_aux_with_completion(char *buf, int len)
{
- askfor_aux_complete = TRUE;
- bool_ res = askfor_aux(buf, len);
- askfor_aux_complete = FALSE;
+ askfor_aux_complete = true;
+ bool res = askfor_aux(buf, len);
+ askfor_aux_complete = false;
return res;
}
@@ -2515,11 +2632,11 @@ bool_ askfor_aux_with_completion(char *buf, int len)
* Note that the initial contents of the string is used as
* the default response, so be sure to "clear" it if needed.
*
-* We clear the input, and return FALSE, on "ESCAPE".
+* We clear the input, and return false, on "ESCAPE".
*/
-bool_ get_string(cptr prompt, char *buf, int len)
+bool get_string(const char *prompt, char *buf, int len)
{
- bool_ res;
+ bool res;
/* Paranoia XXX XXX XXX */
msg_print(NULL);
@@ -2545,7 +2662,7 @@ bool_ get_string(cptr prompt, char *buf, int len)
*
* Note that "[y/n]" is appended to the prompt.
*/
-bool_ get_check(cptr prompt)
+bool get_check(const char *prompt)
{
int i;
@@ -2561,7 +2678,7 @@ bool_ get_check(cptr prompt)
prt(buf, 0, 0);
/* Get an acceptable answer */
- while (TRUE)
+ while (true)
{
i = inkey();
if (options->quick_messages) break;
@@ -2574,10 +2691,16 @@ bool_ get_check(cptr prompt)
prt("", 0, 0);
/* Normal negation */
- if ((i != 'Y') && (i != 'y')) return (FALSE);
+ if ((i != 'Y') && (i != 'y')) return false;
/* Success */
- return (TRUE);
+ return true;
+}
+
+
+bool get_check(std::string const &prompt)
+{
+ return get_check(prompt.c_str());
}
@@ -2586,9 +2709,9 @@ bool_ get_check(cptr prompt)
*
* The "prompt" should take the form "Command: "
*
-* Returns TRUE unless the character is "Escape"
+* Returns true unless the character is "Escape"
*/
-bool_ get_com(cptr prompt, char *command)
+bool get_com(const char *prompt, char *command)
{
/* Paranoia XXX XXX XXX */
msg_print(NULL);
@@ -2603,10 +2726,10 @@ bool_ get_com(cptr prompt, char *command)
prt("", 0, 0);
/* Handle "cancel" */
- if (*command == ESCAPE) return (FALSE);
+ if (*command == ESCAPE) return false;
/* Success */
- return (TRUE);
+ return true;
}
@@ -2615,7 +2738,7 @@ bool_ get_com(cptr prompt, char *command)
*
* Hack -- allow "command_arg" to specify a quantity
*/
-s32b get_quantity(cptr prompt, s32b max)
+s32b get_quantity(const char *prompt, s32b max)
{
s32b amt;
int aamt;
@@ -2724,7 +2847,7 @@ char request_command_ignore_keymaps[MAX_IGNORE_KEYMAPS];
* Mega-Hack -- flag set by do_cmd_{inven,equip}() to allow keymaps in
* auto-command mode.
*/
-bool_ request_command_inven_mode = FALSE;
+bool request_command_inven_mode = false;
/*
@@ -2755,7 +2878,7 @@ void request_command(int shopping)
int mode;
- cptr act;
+ const char *act;
/* Keymap mode */
@@ -2772,7 +2895,7 @@ void request_command(int shopping)
/* Get command */
- while (1)
+ while (true)
{
/* Hack -- auto-commands */
if (command_new)
@@ -2793,17 +2916,17 @@ void request_command(int shopping)
}
/* Mega-Hack -- turn off this flag immediately */
- request_command_inven_mode = FALSE;
+ request_command_inven_mode = false;
}
/* Get a keypress in "command" mode */
else
{
/* Hack -- no flush needed */
- msg_flag = FALSE;
+ msg_flag = false;
/* Activate "command mode" */
- inkey_flag = TRUE;
+ inkey_flag = true;
/* Get a command */
cmd = inkey();
@@ -2818,58 +2941,9 @@ void request_command(int shopping)
{
int old_arg = command_arg;
- /* Reset */
- command_arg = 0;
-
- /* Begin the input */
prt("Count: ", 0, 0);
-
- /* Get a command count */
- while (1)
- {
- /* Get a new keypress */
- cmd = inkey();
-
- /* Simple editing (delete or backspace) */
- if ((cmd == 0x7F) || (cmd == KTRL('H')))
- {
- /* Delete a digit */
- command_arg = command_arg / 10;
-
- /* Show current count */
- prt(format("Count: %d", command_arg), 0, 0);
- }
-
- /* Actual numeric data */
- else if (cmd >= '0' && cmd <= '9')
- {
- /* Stop count at 9999 */
- if (command_arg >= 1000)
- {
- /* Warn */
- bell();
-
- /* Limit */
- command_arg = 9999;
- }
-
- /* Increase count */
- else
- {
- /* Incorporate that digit */
- command_arg = command_arg * 10 + D2I(cmd);
- }
-
- /* Show current count */
- prt(format("Count: %d", command_arg), 0, 0);
- }
-
- /* Exit on "unusable" input */
- else
- {
- break;
- }
- }
+ std::tie(command_arg, cmd) =
+ get_number(0, 9999, 0, 7, display_option_t::DELAY);
/* Hack -- Handle "zero" */
if (command_arg == 0)
@@ -2878,7 +2952,7 @@ void request_command(int shopping)
command_arg = 99;
/* Show current count */
- prt(format("Count: %d", command_arg), 0, 0);
+ prt(fmt::format("Count: {}", command_arg), 0, 0);
}
/* Hack -- Handle "old_arg" */
@@ -2888,14 +2962,14 @@ void request_command(int shopping)
command_arg = old_arg;
/* Show current count */
- prt(format("Count: %d", command_arg), 0, 0);
+ prt(fmt::format("Count: {}", command_arg), 0, 0);
}
/* Hack -- white-space means "enter command now" */
if ((cmd == ' ') || (cmd == '\n') || (cmd == '\r'))
{
/* Get a real command */
- bool_ temp = get_com("Command: ", &cmd_char);
+ bool temp = get_com("Command: ", &cmd_char);
cmd = cmd_char;
if (!temp)
@@ -2988,7 +3062,10 @@ void request_command(int shopping)
object_type *o_ptr = &p_ptr->inventory[i];
/* Skip non-objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
/* No inscription */
if (o_ptr->inscription.empty())
@@ -3032,7 +3109,7 @@ void request_command(int shopping)
/*
* Check a char for "vowel-hood"
*/
-bool_ is_a_vowel(int ch)
+bool is_a_vowel(int ch)
{
switch (ch)
{
@@ -3046,10 +3123,10 @@ bool_ is_a_vowel(int ch)
case 'I':
case 'O':
case 'U':
- return (TRUE);
+ return true;
}
- return (FALSE);
+ return false;
}
@@ -3067,9 +3144,9 @@ int get_keymap_dir(char ch)
int mode;
- cptr act;
+ const char *act;
- cptr s;
+ const char *s;
/* Already a direction? */
@@ -3130,21 +3207,22 @@ void repeat_push(int what)
}
-bool_ repeat_pull(int *what)
+bool repeat_pull(int *what)
{
/* All out of keys */
- if (repeat__idx == repeat__cnt) return (FALSE);
+ if (repeat__idx == repeat__cnt) return false;
/* Grab the next key, advance */
*what = repeat__key[repeat__idx++];
/* Success */
- return (TRUE);
+ return true;
}
-void repeat_check()
+void repeat_check(s16b *command_ptr)
{
- int what;
+ assert(command_ptr);
+ auto &command_cmd = *command_ptr;
/* Ignore some commands */
if (command_cmd == ESCAPE) return;
@@ -3159,6 +3237,7 @@ void repeat_check()
repeat__idx = 0;
/* Get the command */
+ int what;
if (repeat_pull(&what))
{
/* Save the command */
@@ -3173,115 +3252,16 @@ void repeat_check()
repeat__cnt = 0;
repeat__idx = 0;
- what = command_cmd;
-
/* Save this command */
- repeat_push(what);
- }
-}
-
-
-/*
- * Read a number at a specific location on the screen
- *
- * Allow numbers of any size and save the last keypress.
- */
-static u32b get_number(u32b def, u32b max, int y, int x, char *cmd)
-{
- u32b res = def;
-
- /* Player has not typed anything yet */
- bool_ no_keys = TRUE;
-
- /* Begin the input with default */
- prt(format("%lu", def), y, x);
-
- /* Get a command count */
- while (1)
- {
- /* Get a new keypress */
- *cmd = inkey();
-
- /* Simple editing (delete or backspace) */
- if ((*cmd == 0x7F) || (*cmd == KTRL('H')))
- {
- /* Override the default */
- no_keys = FALSE;
-
- /* Delete a digit */
- res = res / 10;
-
- prt(format("%lu", res), y, x);
- }
-
- /* Actual numeric data */
- else if (*cmd >= '0' && *cmd <= '9')
- {
- /* Override the default */
- if (no_keys)
- {
- no_keys = FALSE;
- res = 0;
- }
-
- /* Don't overflow */
- if (((u32b)(0 - 1) - D2I(*cmd)) / 10 < res)
- {
- /* Warn */
- bell();
-
- /* Limit */
- res = (max + 1 == 0) ? (u32b)(0 - 1) : max;
- }
-
- /* Stop count at maximum */
- else if (res * 10 + D2I(*cmd) > max)
- {
- /* Warn */
- bell();
-
- /* Limit */
- res = max;
- }
-
- /* Increase count */
- else
- {
- /* Incorporate that digit */
- res = res * 10 + D2I(*cmd);
- }
-
- /* Show current count */
- prt(format("%lu", res), y, x);
- }
-
- /* Escape cancels */
- else if (*cmd == ESCAPE)
- {
- res = 0;
- break;
- }
-
- /* Exit on "unusable" input */
- else
- {
- break;
- }
+ repeat_push(command_cmd);
}
-
- return res;
}
/*
* Allow the user to select multiple items without pressing '0'
*/
-void get_count(int number, int max)
+s16b get_count(int number, int max)
{
- char cmd;
-
- /* Use the default */
- command_arg = number;
-
/* Hack -- Optional flush */
if (options->flush_command)
{
@@ -3295,9 +3275,11 @@ void get_count(int number, int max)
prt("How many?", 0, 0);
/* Actually get a number */
- command_arg = get_number(command_arg, max, 0, 10, &cmd);
+ auto [res, cmd] = get_number(number, max, 0, 10, display_option_t::IMMEDIATE);
prt("", 0, 0);
+
+ return res;
}
byte count_bits(u32b array)
@@ -3327,7 +3309,7 @@ void strlower(char *buf)
* must exactly match (look out for commas and the like!), or else 0 is
* returned. Case doesn't matter. -GSN-
*/
-int test_monster_name(cptr name)
+int test_monster_name(const char *name)
{
auto const &r_info = game->edit_data.r_info;
@@ -3342,7 +3324,7 @@ int test_monster_name(cptr name)
return (0);
}
-int test_mego_name(cptr needle)
+int test_mego_name(const char *needle)
{
const auto &re_info = game->edit_data.re_info;
@@ -3360,24 +3342,22 @@ int test_mego_name(cptr needle)
/*
* Given item name as string, return the index in k_info array. Name
- * must exactly match (look out for commas and the like!), or else 0 is
+ * must exactly match (look out for commas and the like!), or else -1 is
* returned. Case doesn't matter. -DG-
*/
-
-int test_item_name(cptr needle)
+int test_item_name(const char *needle)
{
auto const &k_info = game->edit_data.k_info;
- for (std::size_t i = 0; i < k_info.size(); i++)
+ for (auto const &k_entry: k_info)
{
- auto const &name = k_info[i].name;
- if (name && iequals(needle, name))
+ if (iequals(needle, k_entry.second->name))
{
- return i;
+ return k_entry.first;
}
}
- return 0;
+ return -1;
}
/*
@@ -3454,23 +3434,21 @@ std::string get_player_race_name(int pr, int ps)
/*
* Ask to select an item in a list
*/
-int ask_menu(cptr ask, const std::vector<std::string> &items)
+int ask_menu(const char *ask, const std::vector<std::string> &items)
{
int ret = -1, i, start = 0;
char c;
int size = static_cast<int>(items.size()); // Convert to int to avoid warnings
- /* Enter "icky" mode */
- character_icky = TRUE;
-
/* Save the screen */
- Term_save();
+ screen_save_no_flush();
- while (TRUE)
+ while (true)
{
/* Display list */
- Term_load();
- Term_save();
+ screen_load_no_flush();
+ screen_save_no_flush();
+
prt(ask, 0, 0);
for (i = start; (i < size) && (i < start + 20); i++)
{
@@ -3519,38 +3497,12 @@ int ask_menu(cptr ask, const std::vector<std::string> &items)
}
}
- /* Load the screen */
- Term_load();
-
- /* Leave "icky" mode */
- character_icky = FALSE;
+ screen_load_no_flush();
return ret;
}
/*
- * Determine if string "t" is a prefix of string "s"
- */
-bool_ prefix(cptr s, cptr t)
-{
- /* Paranoia */
- if (!s || !t)
- {
- return FALSE;
- }
-
- /* Scan "t" */
- while (*t)
- {
- /* Compare content and length */
- if (*t++ != *s++) return (FALSE);
- }
-
- /* Matched, we have a prefix */
- return (TRUE);
-}
-
-/*
* Displays a box
*/
void draw_box(int y, int x, int h, int w)
@@ -3581,7 +3533,7 @@ void draw_box(int y, int x, int h, int w)
/*
* Displays a scrollable boxed list with a selected item
*/
-void display_list(int y, int x, int h, int w, cptr title, std::vector<std::string> const &list, std::size_t begin, std::size_t sel, byte sel_color)
+void display_list(int y, int x, int h, int w, const char *title, std::vector<std::string> const &list, std::size_t begin, std::size_t sel, byte sel_color)
{
draw_box(y, x, h, w);
c_put_str(TERM_L_BLUE, title, y, x + ((w - strlen(title)) / 2));
diff --git a/src/util.h b/src/util.h
deleted file mode 100644
index 7be705a0..00000000
--- a/src/util.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#pragma once
-
-#include "h-basic.h"
-
-// C linkage required for these functions since main-* code uses them.
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-errr path_build(char *buf, int max, cptr path, cptr file);
-void bell();
-errr macro_add(cptr pat, cptr act);
-sint macro_find_exact(cptr pat);
-char inkey();
-void prt(cptr str, int row, int col);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/src/util.hpp b/src/util.hpp
index 1f5c3aed..32568cba 100644
--- a/src/util.hpp
+++ b/src/util.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "timer_type_fwd.hpp"
#include <vector>
@@ -12,75 +12,86 @@ bool input_box(std::string const &text, int y, int x, std::string *buf, std::siz
std::string input_box_auto(std::string const &title, std::size_t max);
bool input_box_auto(std::string const &prompt, std::string *buf, std::size_t max);
void draw_box(int y, int x, int h, int w);
-void display_list(int y, int x, int h, int w, cptr title, std::vector<std::string> const &list, std::size_t begin, std::size_t sel, byte sel_color);
+void display_list(int y, int x, int h, int w, const char *title, std::vector<std::string> const &list, std::size_t begin, std::size_t sel, byte sel_color);
std::string get_player_race_name(int pr, int ps);
std::string get_day(s32b day);
s32b bst(s32b what, s32b t);
-FILE *my_fopen(cptr file, cptr mode);
-errr my_fgets(FILE *fff, char *buf, huge n);
+FILE *my_fopen(const char *file, const char *mode);
+errr my_fgets(FILE *fff, char *buf, unsigned long n);
errr my_fclose(FILE *fff);
-errr fd_kill(cptr file);
-errr fd_move(cptr file, cptr what);
-int fd_make(cptr file, int mode);
-int fd_open(cptr file, int flags);
-errr fd_seek(int fd, huge n);
-errr fd_read(int fd, char *buf, huge n);
-errr fd_write(int fd, cptr buf, huge n);
+errr fd_kill(const char *file);
+errr fd_move(const char *file, const char *what);
+int fd_make(const char *file, int mode);
+int fd_open(const char *file, int flags);
+errr fd_seek(int fd, unsigned long n);
+errr fd_read(int fd, char *buf, unsigned long n);
+errr fd_write(int fd, const char *buf, unsigned long n);
errr fd_close(int fd);
void flush();
void flush_on_failure();
-void move_cursor(int row, int col);
-void text_to_ascii(char *buf, cptr str);
-void ascii_to_text(char *buf, cptr str);
+void text_to_ascii(char *buf, const char *str);
+void ascii_to_text(char *buf, const char *str);
char inkey_scan();
-void display_message(int x, int y, int split, byte color, cptr t);
-void cmsg_print(byte color, cptr msg);
+void display_message(int x, int y, int split, byte color, const char *t);
+void cmsg_print(byte color, const char *msg);
void cmsg_print(byte color, std::string const &msg);
-void msg_print(cptr msg);
-void cmsg_format(byte color, cptr fmt, ...);
-void msg_format(cptr fmt, ...);
+void msg_print(const char *msg);
+void msg_print(std::string const &msg);
+void cmsg_format(byte color, const char *fmt, ...);
+void msg_format(const char *fmt, ...);
void screen_save();
+void screen_save_no_flush();
void screen_load();
-void c_put_str(byte attr, cptr str, int row, int col);
+void screen_load_no_flush();
+void c_put_str(byte attr, const char *str, int row, int col);
void c_put_str(byte attr, std::string const &str, int row, int col);
-void put_str(cptr str, int row, int col);
+void put_str(const char *str, int row, int col);
void put_str(std::string const &s, int row, int col);
-void c_prt(byte attr, cptr str, int row, int col);
+void c_prt(byte attr, const char *str, int row, int col);
void c_prt(byte attr, std::string const &s, int row, int col);
void prt(std::string const &s, int row, int col);
-void text_out_to_screen(byte a, cptr str);
-void text_out_to_file(byte a, cptr str);
-void text_out(cptr str);
-void text_out_c(byte a, cptr str);
+void text_out_to_screen(byte a, const char *str);
+void text_out_to_file(byte a, const char *str);
+void text_out(const char *str);
+void text_out(std::string const &str);
+void text_out_c(byte a, const char *str);
+void text_out_c(byte a, std::string const &str);
void clear_from(int row);
-int ask_menu(cptr ask, const std::vector<std::string> &items);
+int ask_menu(const char *ask, const std::vector<std::string> &items);
bool askfor_aux(std::string *buf, std::size_t max_len);
-bool_ askfor_aux(char *buf, int len);
-bool_ askfor_aux_with_completion(char *buf, int len);
-bool_ get_string(cptr prompt, char *buf, int len);
-bool_ get_check(cptr prompt);
-bool_ get_com(cptr prompt, char *command);
-s32b get_quantity(cptr prompt, s32b max);
+bool askfor_aux(char *buf, int len);
+bool askfor_aux_with_completion(char *buf, int len);
+bool get_string(const char *prompt, char *buf, int len);
+bool get_check(const char *prompt);
+bool get_check(std::string const &prompt);
+bool get_com(const char *prompt, char *command);
+s32b get_quantity(const char *prompt, s32b max);
extern char request_command_ignore_keymaps[MAX_IGNORE_KEYMAPS];
-extern bool_ request_command_inven_mode;
+extern bool request_command_inven_mode;
void request_command(int shopping);
-bool_ is_a_vowel(int ch);
+bool is_a_vowel(int ch);
int get_keymap_dir(char ch);
byte count_bits(u32b array);
void strlower(char *buf);
-int test_monster_name(cptr name);
-int test_mego_name(cptr name);
-int test_item_name(cptr name);
+int test_monster_name(const char *name);
+int test_mego_name(const char *name);
+int test_item_name(const char *name);
char msg_box_auto(std::string const &title);
timer_type *new_timer(void (*callback)(), s32b delay);
int get_keymap_mode();
void repeat_push(int what);
-bool_ repeat_pull(int *what);
-void repeat_check();
-void get_count(int number, int max);
+bool repeat_pull(int *what);
+void repeat_check(s16b *command_cmd);
+s16b get_count(int number, int max);
bool in_bounds(int y, int x);
bool in_bounds2(int y, int x);
bool panel_contains(int y, int x);
-errr path_parse(char *buf, int max, cptr file);
+errr path_parse(char *buf, int max, const char *file);
void pause_line(int row);
std::string user_name();
+errr path_build(char *buf, int max, const char *path, const char *file);
+void bell();
+errr macro_add(const char *pat, const char *act);
+int macro_find_exact(const char *pat);
+char inkey();
+void prt(const char *str, int row, int col);
diff --git a/src/variable.cc b/src/variable.cc
index ae40676f..b08145a5 100644
--- a/src/variable.cc
+++ b/src/variable.cc
@@ -7,7 +7,6 @@
*/
#include "variable.hpp"
-#include "variable.h"
#include "cli_comm_fwd.hpp"
#include "player_type.hpp"
@@ -23,22 +22,15 @@ char *macro_trigger_name[MAX_MACRO_TRIG];
char *macro_trigger_keycode[2][MAX_MACRO_TRIG];
/*
- * Run-time aruments
- */
-bool_ arg_wizard; /* Command arg -- Request wizard mode */
-bool_ arg_force_original; /* Command arg -- Request original keyset */
-bool_ arg_force_roguelike; /* Command arg -- Request roguelike keyset */
-
-/*
* Various things
*/
-bool_ character_generated; /* The character exists */
-bool_ character_dungeon; /* The character has a dungeon */
-bool_ character_loaded; /* The character was loaded from a savefile */
+bool character_generated; /* The character exists */
+bool character_dungeon; /* The character has a dungeon */
+bool character_loaded; /* The character was loaded from a savefile */
-bool_ character_icky; /* The game is in an icky full screen mode */
-bool_ character_xtra; /* The game is in an icky startup mode */
+bool character_icky = false; /* The game is in an icky full screen mode */
+bool character_xtra; /* The game is in an icky startup mode */
seed_t &seed_flavor()
{
@@ -58,17 +50,17 @@ s16b command_new; /* Command chaining from inven/equip view */
s32b energy_use; /* Energy use this turn */
-bool_ create_up_stair; /* Auto-create "up stairs" */
-bool_ create_down_stair; /* Auto-create "down stairs" */
+bool create_up_stair; /* Auto-create "up stairs" */
+bool create_down_stair; /* Auto-create "down stairs" */
-bool_ create_up_shaft; /* Auto-create "up shaft" */
-bool_ create_down_shaft; /* Auto-create "down shaft" */
+bool create_up_shaft; /* Auto-create "up shaft" */
+bool create_down_shaft; /* Auto-create "down shaft" */
-bool_ msg_flag; /* Used in msg_print() for "buffering" */
+bool msg_flag; /* Used in msg_print() for "buffering" */
-bool_ alive; /* True if game is running */
+bool alive; /* True if game is running */
-bool_ death; /* True if player has died */
+bool death; /* True if player has died */
s16b running; /* Current counter for running, if any */
s16b resting; /* Current counter for resting, if any */
@@ -84,27 +76,25 @@ s16b monster_level; /* Current monster creation level */
s32b turn; /* Current game turn */
s32b old_turn; /* Turn when level began (feelings) */
-bool_ wizard; /* Is the player currently in Wizard mode? */
+bool wizard; /* Is the player currently in Wizard mode? */
u16b total_winner; /* Semi-Hack -- Game has been won */
u16b has_won; /* Semi-Hack -- Game has been won */
u16b noscore; /* Track various "cheating" conditions */
-bool_ inkey_base; /* See the "inkey()" function */
+bool inkey_base; /* See the "inkey()" function */
s16b coin_type; /* Hack -- force coin type */
-bool_ opening_chest; /* Hack -- prevent chest generation */
+bool shimmer_monsters; /* Hack -- optimize multi-hued monsters */
+bool shimmer_objects; /* Hack -- optimize multi-hued objects */
-bool_ shimmer_monsters; /* Hack -- optimize multi-hued monsters */
-bool_ shimmer_objects; /* Hack -- optimize multi-hued objects */
+bool repair_monsters; /* Hack -- optimize detect monsters */
-bool_ repair_monsters; /* Hack -- optimize detect monsters */
-
-bool_ hack_mind;
+bool hack_mind;
int artifact_bias;
-bool_ is_autosave = FALSE;
+bool is_autosave = false;
s16b inven_cnt; /* Number of items in inventory */
s16b equip_cnt; /* Number of items in equipment */
@@ -135,7 +125,7 @@ FILE *text_out_file = NULL;
* Hack -- function hook to output (colored) text to the
* screen or to a file.
*/
-void (*text_out_hook)(byte a, cptr str) = text_out_to_screen;
+void (*text_out_hook)(byte a, const char *str) = text_out_to_screen;
/*
@@ -156,7 +146,7 @@ struct options *options = nullptr;
s16b feeling; /* Most recent feeling */
s16b rating; /* Level's current rating */
-bool_ good_item_flag; /* True if "Artifact" on this level */
+bool good_item_flag; /* True if "Artifact" on this level */
/*
* Dungeon size info
@@ -202,12 +192,6 @@ object_type *tracked_object;
/*
- * Buffer to hold the current savefile name
- */
-char savefile[1024];
-
-
-/*
* Array of grids lit by player lite (see "cave.c")
*/
s16b lite_n;
@@ -247,7 +231,7 @@ char **macro__act;
/*
* Array of macro types [MACRO_MAX]
*/
-bool_ *macro__cmd;
+bool *macro__cmd;
/*
* Current macro action [1024]
@@ -387,15 +371,15 @@ int wildc2i[256];
/*
* Default texts for feature information.
*/
-cptr DEFAULT_FEAT_TEXT = "a wall blocking your way";
-cptr DEFAULT_FEAT_TUNNEL = "You cannot tunnel through that.";
-cptr DEFAULT_FEAT_BLOCK = DEFAULT_FEAT_TEXT;
+const char *DEFAULT_FEAT_TEXT = "a wall blocking your way";
+const char *DEFAULT_FEAT_TUNNEL = "You cannot tunnel through that.";
+const char *DEFAULT_FEAT_BLOCK = DEFAULT_FEAT_TEXT;
/*
* Hack -- The special Angband "System Suffix"
* This variable is used to choose an appropriate "pref-xxx" file
*/
-cptr ANGBAND_SYS = "xxx";
+const char *ANGBAND_SYS = "xxx";
/*
* Path name: The main "lib" directory
@@ -404,18 +388,6 @@ cptr ANGBAND_SYS = "xxx";
char *ANGBAND_DIR;
/*
- * Core lua system
- * These files are portable between platforms
- */
-char *ANGBAND_DIR_CORE;
-
-/*
- * Textual dungeon level definition files
- * These files are portable between platforms
- */
-char *ANGBAND_DIR_DNGN;
-
-/*
* Binary image files for the "*_info" arrays (binary)
* These files are not portable between platforms
*/
@@ -485,14 +457,14 @@ char *ANGBAND_DIR_XTRA;
/*
* Hack -- function hooks to restrict "get_mon_num_prep()" function
*/
-bool_ (*get_mon_num_hook)(int r_idx);
-bool_ (*get_mon_num2_hook)(int r_idx);
+bool (*get_monster_hook)(monster_race const *);
+bool (*get_monster_aux_hook)(monster_race const *);
/*
* Hack -- function hook to restrict "get_obj_num_prep()" function
*/
-bool_ (*get_obj_num_hook)(int k_idx);
+bool (*get_object_hook)(object_kind const *k_ptr) = nullptr;
/*
* Devices
@@ -516,16 +488,16 @@ u16b max_m_idx;
int init_flags;
/* True if on an ambush */
-bool_ ambush_flag;
+bool ambush_flag;
/* True if on fated level */
-bool_ fate_flag;
+bool fate_flag;
/* No breeders */
s16b no_breeds;
/* Carried monsters can't take the damage if this is them which attack the player */
-bool_ carried_monster_hit = FALSE;
+bool carried_monster_hit = false;
/*
* Random artifacts.
@@ -557,14 +529,13 @@ s16b *max_dlv;
s16b doppleganger;
/* To allow wilderness encounters */
-bool_ generate_encounter = FALSE;
+bool generate_encounter = false;
/*
* Such an ugly hack ...
*/
-bool_ *m_allow_special;
-bool_ *k_allow_special;
-bool_ *a_allow_special;
+bool *m_allow_special;
+bool *a_allow_special;
/*
* Plots
@@ -577,11 +548,6 @@ s16b plots[MAX_PLOTS];
random_quest random_quests[MAX_RANDOM_QUEST];
/*
- * Dungeon flags
- */
-DECLARE_FLAG_ZERO_IMPL(dungeon_flag_set, dungeon_flags);
-
-/*
* The spell list of schools
*/
s16b schools_count = 0;
@@ -592,7 +558,6 @@ school_type schools[SCHOOLS_MAX];
*/
int project_time = 0;
s32b project_time_effect = 0;
-effect_type effects[MAX_EFFECTS];
/*
* Table of "cli" macros.
@@ -603,8 +568,7 @@ int cli_total = 0;
/*
* Automatizer enabled status
*/
-bool_ automatizer_enabled = FALSE;
-bool_ automatizer_create = FALSE;
+bool automatizer_enabled = false;
/*
* Location of the last teleportation thath affected the level
@@ -615,7 +579,7 @@ s16b last_teleportation_x = -1;
/*
* The current game module
*/
-cptr game_module;
+const char *game_module;
s32b game_module_idx;
s32b VERSION_MAJOR;
s32b VERSION_MINOR;
@@ -636,14 +600,14 @@ s32b DUNGEON_ASTRAL_WILD_Y = 19;
const char *get_version_string()
{
static char version_str[80];
- static bool_ initialized = 0;
+ static bool initialized = false;
if (!initialized) {
sprintf(version_str, "%s %ld.%ld.%ld%s",
game_module,
(long int) VERSION_MAJOR,
(long int) VERSION_MINOR,
(long int) VERSION_PATCH, IS_CVS);
- initialized = TRUE;
+ initialized = true;
}
return version_str;
}
diff --git a/src/variable.h b/src/variable.h
deleted file mode 100644
index 6d6e5775..00000000
--- a/src/variable.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#pragma once
-
-#include "angband.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern cptr ANGBAND_SYS;
-extern char *ANGBAND_DIR_SAVE;
-extern char *ANGBAND_DIR_DATA;
-extern char *ANGBAND_DIR_EDIT;
-extern char *ANGBAND_DIR_FILE;
-extern char *ANGBAND_DIR_HELP;
-extern char *ANGBAND_DIR_INFO;
-extern char *ANGBAND_DIR_NOTE;
-extern char *ANGBAND_DIR_PREF;
-extern char *ANGBAND_DIR_USER;
-extern char *ANGBAND_DIR_XTRA;
-extern term *angband_term[ANGBAND_TERM_MAX];
-extern char angband_term_name[ANGBAND_TERM_MAX][80];
-extern byte angband_color_table[256][4];
-extern bool_ character_generated;
-extern bool_ character_icky;
-extern bool_ inkey_flag;
-extern bool_ msg_flag;
-extern char savefile[1024];
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/src/variable.hpp b/src/variable.hpp
index 73d63be7..cf91137d 100644
--- a/src/variable.hpp
+++ b/src/variable.hpp
@@ -1,15 +1,17 @@
#pragma once
-#include "angband.h"
#include "alloc_entry_fwd.hpp"
#include "birther.hpp"
#include "cave_type_fwd.hpp"
+#include "defines.hpp"
#include "deity_type.hpp"
#include "dungeon_flag_set.hpp"
#include "effect_type.hpp"
#include "fate.hpp"
+#include "monster_race_fwd.hpp"
#include "monster_type_fwd.hpp"
#include "object_type_fwd.hpp"
+#include "object_kind_fwd.hpp"
#include "options.hpp"
#include "player_class_fwd.hpp"
#include "player_defs.hpp"
@@ -24,6 +26,7 @@
#include "timer_type_fwd.hpp"
#include "town_type_fwd.hpp"
#include "seed.hpp"
+#include "z-term.hpp"
extern int max_macrotrigger;
extern char *macro_template;
@@ -31,9 +34,9 @@ extern char *macro_modifier_chr;
extern char *macro_modifier_name[MAX_MACRO_MOD];
extern char *macro_trigger_name[MAX_MACRO_TRIG];
extern char *macro_trigger_keycode[2][MAX_MACRO_TRIG];
-extern bool_ character_dungeon;
-extern bool_ character_loaded;
-extern bool_ character_xtra;
+extern bool character_dungeon;
+extern bool character_loaded;
+extern bool character_xtra;
seed_t &seed_flavor();
extern s16b command_cmd;
extern s16b command_arg;
@@ -42,12 +45,12 @@ extern s16b command_dir;
extern s16b command_wrk;
extern s16b command_new;
extern s32b energy_use;
-extern bool_ create_up_stair;
-extern bool_ create_down_stair;
-extern bool_ create_up_shaft;
-extern bool_ create_down_shaft;
-extern bool_ alive;
-extern bool_ death;
+extern bool create_up_stair;
+extern bool create_down_stair;
+extern bool create_up_shaft;
+extern bool create_down_shaft;
+extern bool alive;
+extern bool death;
extern s16b running;
extern s16b resting;
extern s16b cur_hgt;
@@ -59,16 +62,15 @@ extern s16b object_level;
extern s16b monster_level;
extern s32b turn;
extern s32b old_turn;
-extern bool_ wizard;
+extern bool wizard;
extern u16b total_winner;
extern u16b has_won;
extern u16b noscore;
-extern bool_ inkey_base;
+extern bool inkey_base;
extern s16b coin_type;
-extern bool_ opening_chest;
-extern bool_ shimmer_monsters;
-extern bool_ shimmer_objects;
-extern bool_ repair_monsters;
+extern bool shimmer_monsters;
+extern bool shimmer_objects;
+extern bool repair_monsters;
extern s16b inven_cnt;
extern s16b equip_cnt;
extern s16b o_max;
@@ -80,15 +82,15 @@ extern int total_friends;
extern s32b total_friend_levels;
extern int leaving_quest;
extern char summon_kin_type;
-extern bool_ hack_mind;
-extern bool_ is_autosave;
+extern bool hack_mind;
+extern bool is_autosave;
extern int artifact_bias;
extern FILE *text_out_file;
-extern void (*text_out_hook)(byte a, cptr str);
+extern void (*text_out_hook)(byte a, const char *str);
extern int text_out_indent;
extern s16b feeling;
extern s16b rating;
-extern bool_ good_item_flag;
+extern bool good_item_flag;
extern s16b max_panel_rows, max_panel_cols;
extern s16b panel_row_min, panel_row_max;
extern s16b panel_col_min, panel_col_max;
@@ -116,7 +118,7 @@ extern byte temp_x[TEMP_MAX];
extern s16b macro__num;
extern char **macro__pat;
extern char **macro__act;
-extern bool_ *macro__cmd;
+extern bool *macro__cmd;
extern char *macro__buf;
extern u32b window_flag[ANGBAND_TERM_MAX];
extern u32b window_mask[ANGBAND_TERM_MAX];
@@ -138,23 +140,21 @@ extern player_race_mod const *rmp_ptr;
extern player_class const *cp_ptr;
extern player_spec const *spp_ptr;
extern int wildc2i[256];
-extern cptr DEFAULT_FEAT_TEXT;
-extern cptr DEFAULT_FEAT_TUNNEL;
-extern cptr DEFAULT_FEAT_BLOCK;
+extern const char *DEFAULT_FEAT_TEXT;
+extern const char *DEFAULT_FEAT_TUNNEL;
+extern const char *DEFAULT_FEAT_BLOCK;
extern char *ANGBAND_DIR;
extern char *ANGBAND_DIR_MODULES;
-extern char *ANGBAND_DIR_CORE;
-extern char *ANGBAND_DIR_DNGN;
-extern bool_ (*get_mon_num_hook)(int r_idx);
-extern bool_ (*get_mon_num2_hook)(int r_idx);
-extern bool_ (*get_obj_num_hook)(int k_idx);
+extern bool (*get_monster_hook)(monster_race const *);
+extern bool (*get_monster_aux_hook)(monster_race const *);
+extern bool (*get_object_hook)(object_kind const *k_ptr);
extern u16b max_o_idx;
extern u16b max_m_idx;
extern int init_flags;
-extern bool_ ambush_flag;
-extern bool_ fate_flag;
+extern bool ambush_flag;
+extern bool fate_flag;
extern s16b no_breeds;
-extern bool_ carried_monster_hit;
+extern bool carried_monster_hit;
extern s32b RANDART_WEAPON;
extern s32b RANDART_ARMOR;
extern s32b RANDART_JEWEL;
@@ -162,22 +162,19 @@ extern fate fates[MAX_FATES];
extern byte dungeon_type;
extern s16b *max_dlv;
extern s16b doppleganger;
-extern bool_ generate_encounter;
-extern bool_ *m_allow_special;
-extern bool_ *k_allow_special;
-extern bool_ *a_allow_special;
+extern bool generate_encounter;
+extern bool *m_allow_special;
+extern bool *a_allow_special;
extern s16b plots[MAX_PLOTS];
extern random_quest random_quests[MAX_RANDOM_QUEST];
-DECLARE_FLAG_ZERO_INTF(dungeon_flag_set, dungeon_flags);
extern s16b schools_count;
extern school_type schools[SCHOOLS_MAX];
extern int project_time;
extern s32b project_time_effect;
-extern effect_type effects[MAX_EFFECTS];
-extern bool_ automatizer_enabled;
+extern bool automatizer_enabled;
extern s16b last_teleportation_y;
extern s16b last_teleportation_x;
-extern cptr game_module;
+extern const char *game_module;
extern s32b game_module_idx;
extern s32b VERSION_MAJOR;
extern s32b VERSION_MINOR;
@@ -189,7 +186,22 @@ extern s32b DUNGEON_ASTRAL_WILD_X;
extern s32b DUNGEON_ASTRAL_WILD_Y;
extern deity_type deity_info[MAX_GODS];
const char *get_version_string();
-extern bool_ arg_wizard;
-extern bool_ arg_force_original;
-extern bool_ arg_force_roguelike;
extern struct options *options;
+extern const char *ANGBAND_SYS;
+extern char *ANGBAND_DIR_SAVE;
+extern char *ANGBAND_DIR_DATA;
+extern char *ANGBAND_DIR_EDIT;
+extern char *ANGBAND_DIR_FILE;
+extern char *ANGBAND_DIR_HELP;
+extern char *ANGBAND_DIR_INFO;
+extern char *ANGBAND_DIR_NOTE;
+extern char *ANGBAND_DIR_PREF;
+extern char *ANGBAND_DIR_USER;
+extern char *ANGBAND_DIR_XTRA;
+extern term *angband_term[ANGBAND_TERM_MAX];
+extern char angband_term_name[ANGBAND_TERM_MAX][80];
+extern byte angband_color_table[256][4];
+extern bool character_generated;
+extern bool character_icky;
+extern bool inkey_flag;
+extern bool msg_flag;
diff --git a/src/vault_type.hpp b/src/vault_type.hpp
index 9d407d8f..5c3c7644 100644
--- a/src/vault_type.hpp
+++ b/src/vault_type.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include <string>
/**
diff --git a/src/wild.cc b/src/wild.cc
index 3d86c0b7..24ffe4d0 100644
--- a/src/wild.cc
+++ b/src/wild.cc
@@ -154,7 +154,7 @@ static void plasma_recursive(int x1, int y1, int x2, int y2,
*
* Return the number of floor grids
*/
-static int generate_area(int y, int x, bool_ border, bool_ corner)
+static int generate_area(int y, int x, bool corner)
{
auto const &wilderness = game->wilderness;
auto const &wf_info = game->edit_data.wf_info;
@@ -245,7 +245,7 @@ static int generate_area(int y, int x, bool_ border, bool_ corner)
/* Initialize the town */
init_flags = INIT_CREATE_DUNGEON;
- process_dungeon_file("t_info.txt", &ystart, &xstart, cur_hgt, cur_wid, TRUE, FALSE);
+ process_dungeon_file("t_info.txt", &ystart, &xstart, cur_hgt, cur_wid, true, false);
}
else
{
@@ -379,25 +379,25 @@ void wilderness_gen()
auto const &f_info = game->edit_data.f_info;
int i, y, x, hack_floor;
- bool_ daytime;
+ bool daytime;
int xstart = 0;
int ystart = 0;
cave_type *c_ptr;
/* Init the wilderness */
- process_dungeon_file("w_info.txt", &ystart, &xstart, cur_hgt, cur_wid, TRUE, FALSE);
+ process_dungeon_file("w_info.txt", &ystart, &xstart, cur_hgt, cur_wid, true, false);
x = p_ptr->wilderness_x;
y = p_ptr->wilderness_y;
/* Set the correct monster hook */
- set_mon_num_hook();
+ reset_get_monster_hook();
/* Prepare allocation table */
get_mon_num_prep();
/* North border */
- generate_area(y - 1, x, TRUE, FALSE);
+ generate_area(y - 1, x, false);
for (i = 1; i < MAX_WID - 1; i++)
{
@@ -405,7 +405,7 @@ void wilderness_gen()
}
/* South border */
- generate_area(y + 1, x, TRUE, FALSE);
+ generate_area(y + 1, x, false);
for (i = 1; i < MAX_WID - 1; i++)
{
@@ -413,7 +413,7 @@ void wilderness_gen()
}
/* West border */
- generate_area(y, x - 1, TRUE, FALSE);
+ generate_area(y, x - 1, false);
for (i = 1; i < MAX_HGT - 1; i++)
{
@@ -421,7 +421,7 @@ void wilderness_gen()
}
/* East border */
- generate_area(y, x + 1, TRUE, FALSE);
+ generate_area(y, x + 1, false);
for (i = 1; i < MAX_HGT - 1; i++)
{
@@ -429,24 +429,24 @@ void wilderness_gen()
}
/* North west corner */
- generate_area(y - 1, x - 1, FALSE, TRUE);
+ generate_area(y - 1, x - 1, true);
border.north_west = cave[MAX_HGT - 2][MAX_WID - 2].feat;
/* North east corner */
- generate_area(y - 1, x + 1, FALSE, TRUE);
+ generate_area(y - 1, x + 1, true);
border.north_east = cave[MAX_HGT - 2][1].feat;
/* South west corner */
- generate_area(y + 1, x - 1, FALSE, TRUE);
+ generate_area(y + 1, x - 1, true);
border.south_west = cave[1][MAX_WID - 2].feat;
/* South east corner */
- generate_area(y + 1, x + 1, FALSE, TRUE);
+ generate_area(y + 1, x + 1, true);
border.south_east = cave[1][1].feat;
/* Create terrain of the current area */
- hack_floor = generate_area(y, x, FALSE, FALSE);
+ hack_floor = generate_area(y, x, false);
/* Special boundary walls -- North */
@@ -504,9 +504,9 @@ void wilderness_gen()
/* Day time */
if ((turn % (10L * DAY)) < ((10L * DAY) / 2))
- daytime = TRUE;
+ daytime = true;
else
- daytime = FALSE;
+ daytime = false;
/* Light up or darken the area */
for (y = 0; y < cur_hgt; y++)
@@ -542,7 +542,7 @@ void wilderness_gen()
player_place(p_ptr->oldpy, p_ptr->oldpx);
{
- int lim = (generate_encounter == TRUE) ? 60 : MIN_M_ALLOC_TN;
+ int lim = (generate_encounter == true) ? 60 : MIN_M_ALLOC_TN;
/*
* Can't have more monsters than floor grids -1(for the player,
@@ -554,11 +554,11 @@ void wilderness_gen()
for (i = 0; i < lim; i++)
{
/* Make a resident */
- alloc_monster((generate_encounter == TRUE) ? 0 : 3, (generate_encounter == TRUE) ? FALSE : TRUE);
+ alloc_monster((generate_encounter == true) ? 0 : 3, (generate_encounter == true) ? false : true);
}
- if (generate_encounter) ambush_flag = TRUE;
- generate_encounter = FALSE;
+ if (generate_encounter) ambush_flag = true;
+ generate_encounter = false;
}
/* Set rewarded quests to finished */
@@ -570,7 +570,7 @@ void wilderness_gen()
}
}
- struct hook_wild_gen_in in = { FALSE };
+ struct hook_wild_gen_in in = { false };
process_hooks_new(HOOK_WILD_GEN, &in, NULL);
}
@@ -596,7 +596,7 @@ void wilderness_gen_small()
}
/* Init the wilderness */
- process_dungeon_file("w_info.txt", &ystart, &xstart, cur_hgt, cur_wid, TRUE, FALSE);
+ process_dungeon_file("w_info.txt", &ystart, &xstart, cur_hgt, cur_wid, true, false);
/* Fill the map */
for (std::size_t x = 0; x < wilderness.width(); x++)
@@ -645,7 +645,7 @@ void wilderness_gen_small()
}
}
- struct hook_wild_gen_in in = { TRUE };
+ struct hook_wild_gen_in in = { true };
process_hooks_new(HOOK_WILD_GEN, &in, NULL);
}
@@ -675,7 +675,7 @@ void reveal_wilderness_around_player(int y, int x, int h, int w)
if (distance(y, x, j, i) >= w) continue;
/* New we know here */
- wilderness(i, j).known = TRUE;
+ wilderness(i, j).known = true;
/* Only if we are in overview */
if (p_ptr->wild_mode)
@@ -698,7 +698,7 @@ void reveal_wilderness_around_player(int y, int x, int h, int w)
if (!in_bounds(j, i)) continue;
/* New we know here */
- wilderness(i, j).known = TRUE;
+ wilderness(i, j).known = true;
/* Only if we are in overview */
if (p_ptr->wild_mode)
@@ -1004,13 +1004,62 @@ static void town_borders(int qy, int qx)
}
}
-static bool_ create_townpeople_hook(int r_idx)
+static bool create_townpeople_hook(monster_race const *r_ptr)
{
- auto const &r_info = game->edit_data.r_info;
+ return (r_ptr->d_char == 't');
+}
- auto r_ptr = &r_info[r_idx];
- return (r_ptr->d_char == 't');
+static void place_townspeople(int qy, int qx)
+{
+ bool (*old_get_monster_hook)(monster_race const *);
+ int y;
+ int x;
+
+ /* Backup the old hook */
+ old_get_monster_hook = get_monster_hook;
+
+ /* Require "okay" monsters */
+ get_monster_hook = create_townpeople_hook;
+
+ /* Prepare allocation table */
+ get_mon_num_prep();
+
+ for (x = qx; x < qx + SCREEN_WID; x++)
+ {
+ for (y = qy; y < qy + SCREEN_HGT; y++)
+ {
+ int m_idx, r_idx;
+
+ /* Only in town */
+ if (!in_bounds(y, x)) continue;
+ if (!(cave[y][x].info & CAVE_FREE)) continue;
+ if (!cave_empty_bold(y, x)) continue;
+
+ if (rand_int(100)) continue;
+
+ r_idx = get_mon_num(0);
+ m_allow_special[r_idx] = true;
+ m_idx = place_monster_one(y, x, r_idx, 0, true, MSTATUS_ENEMY);
+ m_allow_special[r_idx] = false;
+
+ if (m_idx)
+ {
+ monster_type *m_ptr = &m_list[m_idx];
+ if (m_ptr->level < (dun_level / 2))
+ {
+ m_ptr->exp = monster_exp(m_ptr->level + (dun_level / 2) + randint(dun_level / 2));
+ monster_check_experience(m_idx, true);
+ }
+ }
+ }
+ }
+
+ /* Reset restriction */
+ get_monster_hook = old_get_monster_hook;
+
+ /* Prepare allocation table */
+ get_mon_num_prep();
}
@@ -1024,7 +1073,6 @@ static bool_ create_townpeople_hook(int r_idx)
static void town_gen_hack(int qy, int qx)
{
int y, x, floor;
- bool_ (*old_get_mon_num_hook)(int r_idx);
/* Do we use dungeon floor or normal one */
if (magik(TOWN_NORMAL_FLOOR)) floor = FEAT_FLOOR;
@@ -1065,57 +1113,13 @@ static void town_gen_hack(int qy, int qx)
/* Generates the town's borders */
if (magik(TOWN_NORMAL_FLOOR)) town_borders(qy, qx);
-
- /* Some inhabitants(leveled .. hehe :) */
-
- /* Backup the old hook */
- old_get_mon_num_hook = get_mon_num_hook;
-
- /* Require "okay" monsters */
- get_mon_num_hook = create_townpeople_hook;
-
- /* Prepare allocation table */
- get_mon_num_prep();
-
- for (x = qx; x < qx + SCREEN_WID; x++)
- for (y = qy; y < qy + SCREEN_HGT; y++)
- {
- int m_idx, r_idx;
-
- /* Only in town */
- if (!in_bounds(y, x)) continue;
- if (!(cave[y][x].info & CAVE_FREE)) continue;
- if (!cave_empty_bold(y, x)) continue;
-
- if (rand_int(100)) continue;
-
- r_idx = get_mon_num(0);
- m_allow_special[r_idx] = TRUE;
- m_idx = place_monster_one(y, x, r_idx, 0, TRUE, MSTATUS_ENEMY);
- m_allow_special[r_idx] = FALSE;
-
- if (m_idx)
- {
- monster_type *m_ptr = &m_list[m_idx];
- if (m_ptr->level < (dun_level / 2))
- {
- m_ptr->exp = monster_exp(m_ptr->level + (dun_level / 2) + randint(dun_level / 2));
- monster_check_experience(m_idx, TRUE);
- }
- }
- }
-
- /* Reset restriction */
- get_mon_num_hook = old_get_mon_num_hook;
-
- /* Prepare allocation table */
- get_mon_num_prep();
+ /* Generate inhabitants */
+ place_townspeople(qy, qx);
}
static void town_gen_circle(int qy, int qx)
{
int y, x, cy, cx, rad, floor;
- bool_ (*old_get_mon_num_hook)(int r_idx);
/* Do we use dungeon floor or normal one */
if (magik(TOWN_NORMAL_FLOOR)) floor = FEAT_FLOOR;
@@ -1198,49 +1202,8 @@ static void town_gen_circle(int qy, int qx)
}
}
- /* Some inhabitants(leveled .. hehe :) */
-
- /* Backup the old hook */
- old_get_mon_num_hook = get_mon_num_hook;
-
- /* Require "okay" monsters */
- get_mon_num_hook = create_townpeople_hook;
-
- /* Prepare allocation table */
- get_mon_num_prep();
-
- for (x = qx; x < qx + SCREEN_WID; x++)
- for (y = qy; y < qy + SCREEN_HGT; y++)
- {
- int m_idx, r_idx;
-
- /* Only in town */
- if (!in_bounds(y, x)) continue;
- if (!(cave[y][x].info & CAVE_FREE)) continue;
- if (!cave_empty_bold(y, x)) continue;
-
- if (rand_int(100)) continue;
-
- r_idx = get_mon_num(0);
- m_allow_special[r_idx] = TRUE;
- m_idx = place_monster_one(y, x, r_idx, 0, TRUE, MSTATUS_ENEMY);
- m_allow_special[r_idx] = FALSE;
- if (m_idx)
- {
- monster_type *m_ptr = &m_list[m_idx];
- if (m_ptr->level < (dun_level / 2))
- {
- m_ptr->exp = monster_exp(m_ptr->level + (dun_level / 2) + randint(dun_level / 2));
- monster_check_experience(m_idx, TRUE);
- }
- }
- }
-
- /* Reset restriction */
- get_mon_num_hook = old_get_mon_num_hook;
-
- /* Prepare allocation table */
- get_mon_num_prep();
+ /* Generate inhabitants */
+ place_townspeople(qy, qx);
}
@@ -1258,7 +1221,7 @@ static void town_gen_hidden()
/* Find a good spot */
int x;
int y;
- while (TRUE)
+ while (true)
{
y = rand_range(1, cur_hgt - 2);
x = rand_range(1, cur_wid - 2);
diff --git a/src/wilderness_map.hpp b/src/wilderness_map.hpp
index 3db36101..27f6d10b 100644
--- a/src/wilderness_map.hpp
+++ b/src/wilderness_map.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "seed.hpp"
/**
@@ -11,5 +11,5 @@ struct wilderness_map
int feat = 0; /* Wilderness feature */
seed_t seed = seed_t::system(); /* Seed for the RNG when building tile */
u16b entrance = 0; /* Entrance for dungeons */
- bool_ known = FALSE; /* Is it seen by the player ? */
+ bool known = false; /* Is it seen by the player ? */
};
diff --git a/src/wilderness_type_info.hpp b/src/wilderness_type_info.hpp
index fa834e09..e15a83f0 100644
--- a/src/wilderness_type_info.hpp
+++ b/src/wilderness_type_info.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "terrain.hpp"
/**
diff --git a/src/wizard2.cc b/src/wizard2.cc
index 890c6fbe..c86b9766 100644
--- a/src/wizard2.cc
+++ b/src/wizard2.cc
@@ -33,13 +33,12 @@
#include "stats.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "wilderness_map.hpp"
#include "wilderness_type_info.hpp"
#include "xtra1.hpp"
#include "xtra2.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
/*
@@ -57,7 +56,7 @@ static void wiz_inc_monster_level(int level)
m_ptr = &m_list[cave[jj][ii].m_idx];
m_ptr->exp = monster_exp(m_ptr->level + level);
- monster_check_experience(cave[jj][ii].m_idx, FALSE);
+ monster_check_experience(cave[jj][ii].m_idx, false);
}
}
@@ -103,7 +102,7 @@ static void teleport_player_town(int town)
p_ptr->inside_quest = 0;
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
// Done
return;
@@ -154,7 +153,7 @@ static void wiz_create_named_art()
object_type forge;
object_type *q_ptr;
int i, a_idx;
- cptr p = "Number of the artifact: ";
+ const char *p = "Number of the artifact: ";
char out_val[80] = "";
if (!get_string(p, out_val, 4)) return;
@@ -189,18 +188,11 @@ static void wiz_create_named_art()
/* Save the name */
q_ptr->name1 = a_idx;
- apply_magic(q_ptr, -1, TRUE, TRUE, TRUE);
+ apply_magic(q_ptr, -1, true, true, true);
/* Apply any random resistances/powers */
random_artifact_resistance(q_ptr);
- /* Identify it fully */
- object_aware(q_ptr);
- object_known(q_ptr);
-
- /* Mark the item as fully known */
- q_ptr->ident |= (IDENT_MENTAL);
-
/* Drop the artifact from heaven */
drop_near(q_ptr, -1, p_ptr->py, p_ptr->px);
@@ -416,8 +408,6 @@ static void do_cmd_wiz_change()
*/
static void wiz_display_item(object_type *o_ptr)
{
- auto const &k_info = game->edit_data.k_info;
-
int i, j = 13;
char buf[256];
@@ -428,13 +418,15 @@ static void wiz_display_item(object_type *o_ptr)
for (i = 1; i <= 23; i++) prt("", i, j - 2);
/* Describe fully */
- object_desc_store(buf, o_ptr, TRUE, 3);
+ object_desc_store(buf, o_ptr, true, 3);
prt(buf, 2, j);
prt(format("kind = %-5d level = %-4d tval = %-5d sval = %-5d",
- o_ptr->k_idx, k_info[o_ptr->k_idx].level,
- o_ptr->tval, o_ptr->sval), 4, j);
+ o_ptr->k_ptr->idx,
+ o_ptr->k_ptr->level,
+ o_ptr->tval,
+ o_ptr->sval), 4, j);
prt(format("number = %-3d wgt = %-6d ac = %-5d damage = %dd%d",
o_ptr->number, o_ptr->weight,
@@ -446,8 +438,8 @@ static void wiz_display_item(object_type *o_ptr)
prt(format("name1 = %-4d name2 = %-4d cost = %ld pval2 = %-5d",
o_ptr->name1, o_ptr->name2, (long)object_value(o_ptr), o_ptr->pval2), 7, j);
- prt(format("ident = %04x timeout = %-d",
- o_ptr->ident, o_ptr->timeout), 8, j);
+ prt(format("ident = %1d timeout = %-d",
+ int(o_ptr->identified), o_ptr->timeout), 8, j);
/* Print all the flags which are set */
prt("Flags:", 10, j);
@@ -477,23 +469,27 @@ static void wiz_display_item(object_type *o_ptr)
/*
* Strip an "object name" into a buffer
*/
-static void strip_name(char *buf, const object_kind *k_ptr)
+static std::string strip_name(std::string const &str)
{
- cptr str = k_ptr->name;
-
-
/* Skip past leading characters */
- while ((*str == ' ') || (*str == '&')) str++;
+ std::size_t i = 0;
+ while ((str[i] == ' ') || (str[i] == '&'))
+ {
+ i++;
+ }
/* Copy useful chars */
- char *t;
- for (t = buf; *str; str++)
+ std::string buf;
+ buf.reserve(str.size() - i);
+ for (; i < str.size(); i++)
{
- if (*str != '~') *t++ = *str;
+ if (str[i] != '~')
+ {
+ buf += str[i];
+ }
}
- /* Terminate the new name */
- *t = '\0';
+ return buf;
}
@@ -510,7 +506,7 @@ static char head[4] = { 'a', 'A', '0', ':' };
* Trims characters from the beginning until it fits in the space
* before the next row or the edge of the screen.
*/
-static void wci_string(cptr string, int num)
+static void wci_string(const char *string, int num)
{
int row = 2 + (num % 20), col = 30 * (num / 20);
int ch = head[num / 20] + (num % 20), max_len = 0;
@@ -541,12 +537,9 @@ static int wiz_create_itemtype()
int num, max_num;
int tval;
- cptr tval_desc2;
+ const char *tval_desc2;
char ch;
- char buf[160];
-
-
/* Clear screen */
Term_clear();
@@ -584,25 +577,31 @@ static int wiz_create_itemtype()
/* We have to search the whole itemlist. */
std::vector<std::size_t> choice;
choice.reserve(60);
- std::size_t i;
- for (i = 1; (choice.size() < 60) && (i < k_info.size()); i++)
+ for (auto &k_entry: k_info)
{
- auto k_ptr = &k_info[i];
+ auto const &k_ptr = k_entry.second;
/* Analyze matching items */
if (k_ptr->tval == tval)
{
/* Hack -- Skip instant artifacts */
- if (k_ptr->flags & TR_INSTA_ART) continue;
+ if (k_ptr->flags & TR_INSTA_ART)
+ {
+ continue;
+ }
/* Acquire the "name" of object */
- strip_name(buf, k_ptr);
+ auto buf = strip_name(k_ptr->name);
/* Print it */
- wci_string(buf, choice.size());
+ wci_string(buf.c_str(), choice.size());
/* Remember the object index */
- choice.push_back(i);
+ choice.push_back(k_entry.first);
+ if (choice.size() >= 60)
+ {
+ break;
+ }
}
}
@@ -631,7 +630,7 @@ static int wiz_create_itemtype()
*/
static void wiz_tweak_item(object_type *o_ptr)
{
- cptr p;
+ const char *p;
char tmp_val[80];
/* Extract the flags */
@@ -717,12 +716,14 @@ static void wiz_reroll_item(object_type *o_ptr)
char ch;
- bool_ changed = FALSE;
+ bool changed = false;
/* Hack -- leave artifacts alone */
if (artifact_p(o_ptr)) return;
+ /* Get the kind index */
+ auto const k_idx = o_ptr->k_ptr->idx;
/* Get local object */
q_ptr = &forge;
@@ -732,7 +733,7 @@ static void wiz_reroll_item(object_type *o_ptr)
/* Main loop. Ask for magification and artifactification */
- while (TRUE)
+ while (true)
{
/* Display full item debug information */
wiz_display_item(q_ptr);
@@ -740,50 +741,50 @@ static void wiz_reroll_item(object_type *o_ptr)
/* Ask wizard what to do. */
if (!get_com("[a]ccept, [b]ad, [n]ormal, [g]ood, [e]xcellent, [r]andart? ", &ch))
{
- changed = FALSE;
+ changed = false;
break;
}
/* Create/change it! */
if (ch == 'A' || ch == 'a')
{
- changed = TRUE;
+ changed = true;
break;
}
/* Apply bad magic, but first clear object */
else if (ch == 'b' || ch == 'B')
{
- object_prep(q_ptr, o_ptr->k_idx);
- apply_magic(q_ptr, dun_level, FALSE, FALSE, FALSE, boost::make_optional(-2));
+ object_prep(q_ptr, k_idx);
+ apply_magic(q_ptr, dun_level, false, false, false, boost::make_optional(-2));
}
/* Apply normal magic, but first clear object */
else if (ch == 'n' || ch == 'N')
{
- object_prep(q_ptr, o_ptr->k_idx);
- apply_magic(q_ptr, dun_level, FALSE, FALSE, FALSE);
+ object_prep(q_ptr, k_idx);
+ apply_magic(q_ptr, dun_level, false, false, false);
}
/* Apply good magic, but first clear object */
else if (ch == 'g' || ch == 'g')
{
- object_prep(q_ptr, o_ptr->k_idx);
- apply_magic(q_ptr, dun_level, FALSE, TRUE, FALSE);
+ object_prep(q_ptr, k_idx);
+ apply_magic(q_ptr, dun_level, false, true, false);
}
/* Apply great magic, but first clear object */
else if (ch == 'e' || ch == 'e')
{
- object_prep(q_ptr, o_ptr->k_idx);
- apply_magic(q_ptr, dun_level, FALSE, TRUE, TRUE);
+ object_prep(q_ptr, k_idx);
+ apply_magic(q_ptr, dun_level, false, true, true);
}
/* Apply great magic, but first clear object */
else if (ch == 'r' || ch == 'r')
{
- object_prep(q_ptr, o_ptr->k_idx);
- create_artifact(q_ptr, FALSE, TRUE);
+ object_prep(q_ptr, k_idx);
+ create_artifact(q_ptr, false, true);
}
}
@@ -832,19 +833,19 @@ static void wiz_statistics(object_type *o_ptr)
char ch;
const char *quality;
- bool_ good, great;
+ bool good, great;
object_type forge;
object_type *q_ptr;
- cptr q = "Rolls: %ld, Matches: %ld, Better: %ld, Worse: %ld, Other: %ld";
+ const char *q = "Rolls: %ld, Matches: %ld, Better: %ld, Worse: %ld, Other: %ld";
/* XXX XXX XXX Mega-Hack -- allow multiple artifacts */
if (artifact_p(o_ptr))
{
if (o_ptr->tval == TV_RANDART)
{
- random_artifacts[o_ptr->sval].generated = FALSE;
+ random_artifacts[o_ptr->sval].generated = false;
}
else
{
@@ -854,9 +855,9 @@ static void wiz_statistics(object_type *o_ptr)
/* Interact */
- while (TRUE)
+ while (true)
{
- cptr pmt = "Roll for [n]ormal, [g]ood, or [e]xcellent treasure? ";
+ const char *pmt = "Roll for [n]ormal, [g]ood, or [e]xcellent treasure? ";
/* Display item */
wiz_display_item(o_ptr);
@@ -866,26 +867,26 @@ static void wiz_statistics(object_type *o_ptr)
if (ch == 'n' || ch == 'N')
{
- good = FALSE;
- great = FALSE;
+ good = false;
+ great = false;
quality = "normal";
}
else if (ch == 'g' || ch == 'G')
{
- good = TRUE;
- great = FALSE;
+ good = true;
+ great = false;
quality = "good";
}
else if (ch == 'e' || ch == 'E')
{
- good = TRUE;
- great = TRUE;
+ good = true;
+ great = true;
quality = "excellent";
}
else
{
- good = FALSE;
- great = FALSE;
+ good = false;
+ great = false;
break;
}
@@ -934,7 +935,7 @@ static void wiz_statistics(object_type *o_ptr)
{
if (q_ptr->tval == TV_RANDART)
{
- random_artifacts[q_ptr->sval].generated = FALSE;
+ random_artifacts[q_ptr->sval].generated = false;
}
else
{
@@ -992,7 +993,7 @@ static void wiz_statistics(object_type *o_ptr)
{
if (o_ptr->tval == TV_RANDART)
{
- random_artifacts[o_ptr->sval].generated = TRUE;
+ random_artifacts[o_ptr->sval].generated = true;
}
else
{
@@ -1054,11 +1055,11 @@ static void do_cmd_wiz_play()
/* The item was not changed */
- bool_ changed = FALSE;
+ bool changed = false;
/* Icky */
- character_icky = TRUE;
+ character_icky = true;
/* Save the screen */
Term_save();
@@ -1073,7 +1074,7 @@ static void do_cmd_wiz_play()
/* The main loop */
- while (TRUE)
+ while (true)
{
char ch;
@@ -1083,13 +1084,13 @@ static void do_cmd_wiz_play()
/* Get choice */
if (!get_com("[a]ccept [s]tatistics [r]eroll [t]weak [q]uantity apply[m]agic? ", &ch))
{
- changed = FALSE;
+ changed = false;
break;
}
if (ch == 'A' || ch == 'a')
{
- changed = TRUE;
+ changed = true;
break;
}
@@ -1117,10 +1118,10 @@ static void do_cmd_wiz_play()
{
int e = q_ptr->name2, eb = q_ptr->name2b;
- object_prep(q_ptr, q_ptr->k_idx);
+ object_prep(q_ptr, q_ptr->k_ptr->idx);
q_ptr->name2 = e;
q_ptr->name2b = eb;
- apply_magic(q_ptr, dun_level, FALSE, FALSE, FALSE);
+ apply_magic(q_ptr, dun_level, false, false, false);
}
}
@@ -1129,7 +1130,7 @@ static void do_cmd_wiz_play()
Term_load();
/* Not Icky */
- character_icky = FALSE;
+ character_icky = false;
/* Accept change */
@@ -1177,7 +1178,7 @@ static void wiz_create_item()
/* Icky */
- character_icky = TRUE;
+ character_icky = true;
/* Save the screen */
Term_save();
@@ -1189,7 +1190,7 @@ static void wiz_create_item()
Term_load();
/* Not Icky */
- character_icky = FALSE;
+ character_icky = false;
/* Return if failed */
@@ -1202,7 +1203,7 @@ static void wiz_create_item()
object_prep(q_ptr, k_idx);
/* Apply magic (no messages, no artifacts) */
- apply_magic(q_ptr, dun_level, FALSE, FALSE, FALSE);
+ apply_magic(q_ptr, dun_level, false, false, false);
/* Drop the object from heaven */
drop_near(q_ptr, -1, p_ptr->py, p_ptr->px);
@@ -1218,14 +1219,14 @@ static void wiz_create_item_2()
{
auto const &k_info = game->edit_data.k_info;
- cptr p = "Number of the object :";
+ const char *p = "Number of the object :";
char out_val[80] = "";
if (!get_string(p, out_val, 4)) return;
int k_idx = atoi(out_val);
/* Return if failed or out-of-bounds */
- if ((k_idx <= 0) || (k_idx >= static_cast<int>(k_info.size())))
+ if (!k_info.count(k_idx))
{
return;
}
@@ -1238,7 +1239,7 @@ static void wiz_create_item_2()
object_prep(q_ptr, k_idx);
/* Apply magic (no messages, no artifacts) */
- apply_magic(q_ptr, dun_level, FALSE, FALSE, FALSE);
+ apply_magic(q_ptr, dun_level, false, false, false);
/* Drop the object from heaven */
drop_near(q_ptr, -1, p_ptr->py, p_ptr->px);
@@ -1259,12 +1260,12 @@ void do_cmd_wiz_cure_all()
remove_all_curse();
/* Restore stats */
- res_stat(A_STR, TRUE);
- res_stat(A_INT, TRUE);
- res_stat(A_WIS, TRUE);
- res_stat(A_CON, TRUE);
- res_stat(A_DEX, TRUE);
- res_stat(A_CHR, TRUE);
+ res_stat(A_STR, true);
+ res_stat(A_INT, true);
+ res_stat(A_WIS, true);
+ res_stat(A_CON, true);
+ res_stat(A_DEX, true);
+ res_stat(A_CHR, true);
/* Restore the level */
restore_level();
@@ -1280,7 +1281,7 @@ void do_cmd_wiz_cure_all()
/* Heal the player monster */
/* Get the carried monster */
o_ptr = &p_ptr->inventory[INVEN_CARRY];
- if (o_ptr->k_idx)
+ if (o_ptr->k_ptr)
{
o_ptr->pval2 = o_ptr->pval3;
}
@@ -1299,7 +1300,7 @@ void do_cmd_wiz_cure_all()
set_stun(0);
set_cut(0);
set_slow(0);
- p_ptr->black_breath = FALSE;
+ p_ptr->black_breath = false;
/* No longer hungry */
set_food(PY_FOOD_MAX - 1);
@@ -1356,36 +1357,7 @@ static void do_cmd_wiz_jump()
p_ptr->inside_quest = 0;
/* Leaving */
- p_ptr->leaving = TRUE;
-}
-
-
-/*
- * Become aware of a lot of objects
- */
-static void do_cmd_wiz_learn()
-{
- auto const &k_info = game->edit_data.k_info;
-
- /* Scan every object */
- for (std::size_t i = 0; i < k_info.size(); i++)
- {
- auto k_ptr = &k_info[i];
-
- /* Induce awareness */
- if (k_ptr->level <= command_arg)
- {
- /* Get local object */
- object_type forge;
- auto q_ptr = &forge;
-
- /* Prepare object */
- object_prep(q_ptr, i);
-
- /* Awareness */
- object_aware(q_ptr);
- }
- }
+ p_ptr->leaving = true;
}
@@ -1408,7 +1380,7 @@ static void do_cmd_wiz_summon(int num)
*
* XXX XXX XXX This function is rather dangerous
*/
-static void do_cmd_wiz_named(std::size_t r_idx, bool_ slp)
+static void do_cmd_wiz_named(std::size_t r_idx, bool slp)
{
auto const &r_info = game->edit_data.r_info;
@@ -1432,9 +1404,9 @@ static void do_cmd_wiz_named(std::size_t r_idx, bool_ slp)
if (!cave_empty_bold(y, x)) continue;
/* Place it (allow groups) */
- m_allow_special[r_idx] = TRUE;
- int m_idx = place_monster_aux(y, x, r_idx, slp, TRUE, MSTATUS_ENEMY);
- m_allow_special[r_idx] = FALSE;
+ m_allow_special[r_idx] = true;
+ int m_idx = place_monster_aux(y, x, r_idx, slp, true, MSTATUS_ENEMY);
+ m_allow_special[r_idx] = false;
// If summoning succeeded, we stop.
if (m_idx)
@@ -1450,7 +1422,7 @@ static void do_cmd_wiz_named(std::size_t r_idx, bool_ slp)
*
* XXX XXX XXX This function is rather dangerous
*/
-void do_cmd_wiz_named_friendly(std::size_t r_idx, bool_ slp)
+void do_cmd_wiz_named_friendly(std::size_t r_idx, bool slp)
{
auto const &r_info = game->edit_data.r_info;
@@ -1474,9 +1446,9 @@ void do_cmd_wiz_named_friendly(std::size_t r_idx, bool_ slp)
if (!cave_empty_bold(y, x)) continue;
/* Place it (allow groups) */
- m_allow_special[r_idx] = TRUE;
- int m_idx = place_monster_aux(y, x, r_idx, slp, TRUE, MSTATUS_PET);
- m_allow_special[r_idx] = FALSE;
+ m_allow_special[r_idx] = true;
+ int m_idx = place_monster_aux(y, x, r_idx, slp, true, MSTATUS_PET);
+ m_allow_special[r_idx] = false;
// Stop if we succeeded
if (m_idx)
@@ -1516,7 +1488,7 @@ static void do_cmd_wiz_body(s16b bidx)
auto const &r_info = game->edit_data.r_info;
p_ptr->body_monster = bidx;
- p_ptr->disembodied = FALSE;
+ p_ptr->disembodied = false;
p_ptr->chp = maxroll( (&r_info[bidx])->hdice, (&r_info[bidx])->hside);
do_cmd_redraw();
}
@@ -1597,7 +1569,7 @@ void do_cmd_debug()
msg_format("You go into %s", d_info[dungeon_type].text.c_str());
/* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->leaving = true;
}
break;
@@ -1611,15 +1583,10 @@ void do_cmd_debug()
cave[p_ptr->py][p_ptr->px].mana = command_arg;
break;
- /* View item info */
- case 'f':
- identify_fully();
- break;
-
/* Good Objects */
case 'g':
if (command_arg <= 0) command_arg = 1;
- acquirement(p_ptr->py, p_ptr->px, command_arg, FALSE, TRUE);
+ acquirement(p_ptr->py, p_ptr->px, command_arg, false);
break;
/* Hitpoint rerating */
@@ -1629,21 +1596,11 @@ void do_cmd_debug()
case 'H':
do_cmd_summon_horde(); break;
- /* Identify */
- case 'i':
- ident_spell();
- break;
-
/* Go up or down in the dungeon */
case 'j':
do_cmd_wiz_jump();
break;
- /* Learn about objects */
- case 'l':
- do_cmd_wiz_learn();
- break;
-
/* Magic Mapping */
case 'm':
map_area();
@@ -1656,12 +1613,12 @@ void do_cmd_debug()
/* Summon _friendly_ named monster */
case 'N':
- do_cmd_wiz_named_friendly(command_arg, TRUE);
+ do_cmd_wiz_named_friendly(command_arg, true);
break;
/* Summon Named Monster */
case 'n':
- do_cmd_wiz_named(command_arg, TRUE);
+ do_cmd_wiz_named(command_arg, true);
break;
/* Object playing routines */
@@ -1705,7 +1662,7 @@ void do_cmd_debug()
case 'U':
{
p_ptr->necro_extra |= CLASS_UNDEAD;
- do_cmd_wiz_named(5, TRUE);
+ do_cmd_wiz_named(5, true);
p_ptr->necro_extra2 = 1;
@@ -1731,9 +1688,9 @@ void do_cmd_debug()
/* Teleport */
case 't':
- teleport_player_bypass = TRUE;
+ teleport_player_bypass = true;
teleport_player(100);
- teleport_player_bypass = FALSE;
+ teleport_player_bypass = false;
break;
/* Teleport to a town */
@@ -1745,7 +1702,7 @@ void do_cmd_debug()
/* Very Good Objects */
case 'v':
if (command_arg <= 0) command_arg = 1;
- acquirement(p_ptr->py, p_ptr->px, command_arg, TRUE, TRUE);
+ acquirement(p_ptr->py, p_ptr->px, command_arg, true);
break;
/* Wizard Light the Level */
@@ -1791,7 +1748,7 @@ void do_cmd_debug()
int i;
gain_fate(command_arg);
for (i = 0; i < MAX_FATES; i++)
- fates[i].know = TRUE;
+ fates[i].know = true;
break;
}
diff --git a/src/wizard2.hpp b/src/wizard2.hpp
index 9bad7f92..cd477d1f 100644
--- a/src/wizard2.hpp
+++ b/src/wizard2.hpp
@@ -1,10 +1,10 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include <cstddef>
void do_cmd_rerate();
void do_cmd_wiz_cure_all();
-void do_cmd_wiz_named_friendly(std::size_t r_idx, bool_ slp);
+void do_cmd_wiz_named_friendly(std::size_t r_idx, bool slp);
void do_cmd_debug();
diff --git a/src/xtra1.cc b/src/xtra1.cc
index ae797aa8..41e2462e 100644
--- a/src/xtra1.cc
+++ b/src/xtra1.cc
@@ -48,12 +48,11 @@
#include "stats.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "wilderness_map.hpp"
#include "wilderness_type_info.hpp"
#include "xtra2.hpp"
+#include "z-form.hpp"
#include "z-rand.hpp"
#include <cassert>
@@ -177,7 +176,7 @@ s16b modify_stat_value(int value, int amount)
/*
* Print character info at given row, column in a 13 char field
*/
-static void prt_field(cptr info, int row, int col)
+static void prt_field(const char *info, int row, int col)
{
/* Dump 13 spaces to clear */
c_put_str(TERM_WHITE, " ", row, col);
@@ -296,7 +295,7 @@ static void prt_stat(int stat)
*/
static void prt_title()
{
- cptr p = "";
+ std::string p;
/* Mimic shape */
if (p_ptr->mimic_form)
@@ -329,7 +328,7 @@ static void prt_title()
}
- prt_field(p, ROW_TITLE, COL_TITLE);
+ prt_field(p.c_str(), ROW_TITLE, COL_TITLE);
}
@@ -541,6 +540,7 @@ static void prt_depth(int row, int col)
{
auto const &d_info = game->edit_data.d_info;
auto const &wf_info = game->edit_data.wf_info;
+ auto const &dungeon_flags = game->dungeon_flags;
char depths[32];
auto d_ptr = &d_info[dungeon_type];
@@ -549,9 +549,9 @@ static void prt_depth(int row, int col)
{
strcpy(depths, " ");
}
- else if (get_dungeon_name(depths))
+ else if (auto s = get_dungeon_name())
{
- /* Empty */
+ strcpy(depths, s->c_str());
}
else if (dungeon_flags & DF_SPECIAL)
{
@@ -1090,25 +1090,17 @@ static void fixup_display(u32b mask, F callback)
{
for (int j = 0; j < ANGBAND_TERM_MAX; j++)
{
- term *old = Term;
-
/* No window */
if (!angband_term[j]) continue;
/* No relevant flags */
if (!(window_flag[j] & mask)) continue;
- /* Activate */
- Term_activate(angband_term[j]);
-
- /* Apply fixup callback */
- callback();
-
- /* Fresh */
- Term_fresh();
-
- /* Restore */
- Term_activate(old);
+ /* Apply callback */
+ Term_with_active(angband_term[j], [&callback]() {
+ callback();
+ Term_fresh();
+ });
}
}
@@ -1217,7 +1209,7 @@ static void fix_object()
/* Display object info */
if (tracked_object &&
- !object_out_desc(tracked_object, NULL, FALSE, FALSE))
+ !object_out_desc(tracked_object, NULL, false, false))
{
text_out("You see nothing special.");
}
@@ -1367,10 +1359,9 @@ static void calc_powers_corruption()
{
if (player_has_corruption(i))
{
- int p = get_corruption_power(i);
- if (p >= 0)
+ if (auto p = get_corruption_power(i))
{
- p_ptr->powers[p] = TRUE;
+ p_ptr->powers.insert(*p);
}
}
}
@@ -1378,23 +1369,20 @@ static void calc_powers_corruption()
/* Ugly hack */
-bool_ calc_powers_silent = FALSE;
+bool calc_powers_silent = false;
/* Add in powers */
static void add_powers(std::vector<s16b> const &powers)
{
- for (auto const &p: powers)
+ for (auto power_idx: powers)
{
- p_ptr->powers[p] = TRUE;
+ p_ptr->powers.insert(power_idx);
}
}
/* Calc the player powers */
static void calc_powers()
{
- int i, p = 0;
- bool_ old_powers[POWER_MAX];
-
/* Hack -- wait for creation */
if (!character_generated) return;
@@ -1402,26 +1390,34 @@ static void calc_powers()
if (character_xtra) return;
/* Save old powers */
- for (i = 0; i < POWER_MAX; i++) old_powers[i] = p_ptr->powers[i];
+ std::vector<std::size_t> old_powers;
+ std::copy(
+ std::begin(p_ptr->powers),
+ std::end(p_ptr->powers),
+ std::back_inserter(old_powers));
+ std::sort(
+ std::begin(old_powers),
+ std::end(old_powers));
/* Get intrinsincs */
- for (i = 0; i < POWER_MAX; i++) p_ptr->powers[i] = p_ptr->powers_mod[i];
- for (; i < POWER_MAX; i++) p_ptr->powers[i] = 0;
+ p_ptr->powers = p_ptr->powers_mod;
/* Calculate powers granted by corruptions */
calc_powers_corruption();
/* Add objects powers */
- for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
+ for (int i = INVEN_WIELD; i < INVEN_TOTAL; i++)
{
- object_type *o_ptr = &p_ptr->inventory[i];
+ auto o_ptr = &p_ptr->inventory[i];
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
- p = object_power(o_ptr);
- if (p != -1)
+ if (auto p = object_power(o_ptr))
{
- p_ptr->powers[p] = TRUE;
+ p_ptr->powers.insert(*p);
}
}
@@ -1439,27 +1435,53 @@ static void calc_powers()
if (p_ptr->disembodied)
{
- p = PWR_INCARNATE;
- p_ptr->powers[p] = TRUE;
+ p_ptr->powers.insert(PWR_INCARNATE);
}
- /* Now lets warn the player */
- for (i = 0; i < POWER_MAX; i++)
- {
- s32b old = old_powers[i];
- s32b new_ = p_ptr->powers[i];
+ // Notify player of lost/gained powers.
+ std::vector<int> new_powers;
+ std::copy(
+ std::begin(p_ptr->powers),
+ std::end(p_ptr->powers),
+ std::back_inserter(new_powers));
+ std::sort(
+ std::begin(new_powers),
+ std::end(new_powers));
- if (new_ > old)
+ if (!calc_powers_silent)
+ {
+ // Show removed powers
{
- if (!calc_powers_silent) cmsg_print(TERM_GREEN, powers_type[i].gain_text);
+ std::vector<int> removed_powers;
+ std::set_difference(
+ std::begin(old_powers), std::end(old_powers),
+ std::begin(new_powers), std::end(new_powers),
+ std::back_inserter(removed_powers)
+ );
+
+ for (auto power_idx: removed_powers)
+ {
+ cmsg_print(TERM_RED, game->powers.at(power_idx)->lose_text);
+ }
}
- else if (new_ < old)
+
+ // Show added powers
{
- if (!calc_powers_silent) cmsg_print(TERM_RED, powers_type[i].lose_text);
+ std::vector<int> added_powers;
+ std::set_difference(
+ std::begin(new_powers), std::end(new_powers),
+ std::begin(old_powers), std::end(old_powers),
+ std::back_inserter(added_powers)
+ );
+
+ for (auto power_idx: added_powers)
+ {
+ cmsg_print(TERM_GREEN, game->powers.at(power_idx)->gain_text);
+ }
}
}
- calc_powers_silent = FALSE;
+ calc_powers_silent = false;
}
@@ -1556,7 +1578,7 @@ static void calc_mana()
if (forbid_gloves())
{
/* Assume player is not encumbered by gloves */
- p_ptr->cumber_glove = FALSE;
+ p_ptr->cumber_glove = false;
/* Get the gloves */
object_type *o_ptr = &p_ptr->inventory[INVEN_HANDS];
@@ -1565,13 +1587,13 @@ static void calc_mana()
auto const flags = object_flags(o_ptr);
/* Normal gloves hurt mage-type spells */
- if (o_ptr->k_idx &&
- !(flags & TR_FREE_ACT) &&
- !((flags & TR_DEX) && (o_ptr->pval > 0)) &&
- !(flags & TR_SPELL_CONTAIN))
+ if (o_ptr->k_ptr &&
+ !(flags & TR_FREE_ACT) &&
+ !((flags & TR_DEX) && (o_ptr->pval > 0)) &&
+ !(flags & TR_SPELL_CONTAIN))
{
/* Encumbered */
- p_ptr->cumber_glove = TRUE;
+ p_ptr->cumber_glove = true;
/* Reduce mana */
msp = (3 * msp) / 4;
@@ -1585,7 +1607,7 @@ static void calc_mana()
}
/* Assume player not encumbered by armor */
- p_ptr->cumber_armor = FALSE;
+ p_ptr->cumber_armor = false;
/* Weigh the armor */
cur_wgt = 0;
@@ -1603,7 +1625,7 @@ static void calc_mana()
if (((cur_wgt - max_wgt) / 10) > 0)
{
/* Encumbered */
- p_ptr->cumber_armor = TRUE;
+ p_ptr->cumber_armor = true;
/* Reduce mana */
msp -= ((cur_wgt - max_wgt) / 10);
@@ -1821,7 +1843,10 @@ static void calc_torch()
o_ptr = &p_ptr->inventory[i];
/* Skip empty slots */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Extract the flags */
auto const flags = object_flags(o_ptr);
@@ -1908,18 +1933,29 @@ void calc_wield_monster()
/* Get the carried monster */
auto o_ptr = &p_ptr->inventory[INVEN_CARRY];
- if (o_ptr->k_idx)
+ if (o_ptr->k_ptr)
{
auto r_ptr = &r_info[o_ptr->pval];
if (r_ptr->flags & RF_INVISIBLE)
+ {
p_ptr->invis += 20;
+ }
+
if (r_ptr->flags & RF_REFLECTING)
- p_ptr->reflect = TRUE;
+ {
+ p_ptr->reflect = true;
+ }
+
if (r_ptr->flags & RF_CAN_FLY)
- p_ptr->ffall = TRUE;
+ {
+ p_ptr->ffall = true;
+ }
+
if (r_ptr->flags & RF_AQUATIC)
- p_ptr->water_breath = TRUE;
+ {
+ p_ptr->water_breath = true;
+ }
}
}
@@ -2041,10 +2077,10 @@ void calc_body()
/* Ok now if the player lost a body part, he must drop the object he had on it */
for (i = 0; i < INVEN_TOTAL - INVEN_WIELD; i++)
{
- if ((!p_ptr->body_parts[i]) && (p_ptr->inventory[i + INVEN_WIELD].k_idx))
+ if ((!p_ptr->body_parts[i]) && p_ptr->inventory[i + INVEN_WIELD].k_ptr)
{
/* Drop it NOW ! */
- inven_takeoff(i + INVEN_WIELD, 255, TRUE);
+ inven_takeoff(i + INVEN_WIELD, 255, true);
}
}
}
@@ -2064,36 +2100,36 @@ void calc_body_bonus()
if (p_ptr->disembodied)
{
- p_ptr->wraith_form = TRUE;
+ p_ptr->wraith_form = true;
return;
}
p_ptr->ac += r_ptr->ac;
p_ptr->pspeed = r_ptr->speed;
- if (r_ptr->flags & RF_NEVER_MOVE) p_ptr->immovable = TRUE;
+ if (r_ptr->flags & RF_NEVER_MOVE) p_ptr->immovable = true;
if (r_ptr->flags & RF_STUPID) p_ptr->stat_add[A_INT] -= 1;
if (r_ptr->flags & RF_SMART) p_ptr->stat_add[A_INT] += 1;
- if (r_ptr->flags & RF_REFLECTING) p_ptr->reflect = TRUE;
+ if (r_ptr->flags & RF_REFLECTING) p_ptr->reflect = true;
if (r_ptr->flags & RF_INVISIBLE) p_ptr->invis += 20;
- if (r_ptr->flags & RF_REGENERATE) p_ptr->regenerate = TRUE;
- if (r_ptr->flags & RF_AURA_FIRE) p_ptr->sh_fire = TRUE;
- if (r_ptr->flags & RF_AURA_ELEC) p_ptr->sh_elec = TRUE;
- if (r_ptr->flags & RF_PASS_WALL) p_ptr->wraith_form = TRUE;
- if (r_ptr->flags & RF_SUSCEP_FIRE) p_ptr->sensible_fire = TRUE;
- if (r_ptr->flags & RF_IM_ACID) p_ptr->resist_acid = TRUE;
- if (r_ptr->flags & RF_IM_ELEC) p_ptr->resist_elec = TRUE;
- if (r_ptr->flags & RF_IM_FIRE) p_ptr->resist_fire = TRUE;
- if (r_ptr->flags & RF_IM_POIS) p_ptr->resist_pois = TRUE;
- if (r_ptr->flags & RF_IM_COLD) p_ptr->resist_cold = TRUE;
- if (r_ptr->flags & RF_RES_NETH) p_ptr->resist_neth = TRUE;
- if (r_ptr->flags & RF_RES_NEXU) p_ptr->resist_nexus = TRUE;
- if (r_ptr->flags & RF_RES_DISE) p_ptr->resist_disen = TRUE;
- if (r_ptr->flags & RF_NO_FEAR) p_ptr->resist_fear = TRUE;
- if (r_ptr->flags & RF_NO_SLEEP) p_ptr->free_act = TRUE;
- if (r_ptr->flags & RF_NO_CONF) p_ptr->resist_conf = TRUE;
- if (r_ptr->flags & RF_CAN_FLY) p_ptr->ffall = TRUE;
- if (r_ptr->flags & RF_AQUATIC) p_ptr->water_breath = TRUE;
+ if (r_ptr->flags & RF_REGENERATE) p_ptr->regenerate = true;
+ if (r_ptr->flags & RF_AURA_FIRE) p_ptr->sh_fire = true;
+ if (r_ptr->flags & RF_AURA_ELEC) p_ptr->sh_elec = true;
+ if (r_ptr->flags & RF_PASS_WALL) p_ptr->wraith_form = true;
+ if (r_ptr->flags & RF_SUSCEP_FIRE) p_ptr->sensible_fire = true;
+ if (r_ptr->flags & RF_IM_ACID) p_ptr->resist_acid = true;
+ if (r_ptr->flags & RF_IM_ELEC) p_ptr->resist_elec = true;
+ if (r_ptr->flags & RF_IM_FIRE) p_ptr->resist_fire = true;
+ if (r_ptr->flags & RF_IM_POIS) p_ptr->resist_pois = true;
+ if (r_ptr->flags & RF_IM_COLD) p_ptr->resist_cold = true;
+ if (r_ptr->flags & RF_RES_NETH) p_ptr->resist_neth = true;
+ if (r_ptr->flags & RF_RES_NEXU) p_ptr->resist_nexus = true;
+ if (r_ptr->flags & RF_RES_DISE) p_ptr->resist_disen = true;
+ if (r_ptr->flags & RF_NO_FEAR) p_ptr->resist_fear = true;
+ if (r_ptr->flags & RF_NO_SLEEP) p_ptr->free_act = true;
+ if (r_ptr->flags & RF_NO_CONF) p_ptr->resist_conf = true;
+ if (r_ptr->flags & RF_CAN_FLY) p_ptr->ffall = true;
+ if (r_ptr->flags & RF_AQUATIC) p_ptr->water_breath = true;
}
@@ -2129,7 +2165,7 @@ int get_weaponmastery_skill()
{
o_ptr = &p_ptr->inventory[INVEN_WIELD + i];
- if (!o_ptr->k_idx)
+ if (!o_ptr->k_ptr)
{
i++;
continue;
@@ -2238,9 +2274,9 @@ static void calc_gods()
if (praying_to(GOD_MELKOR))
{
if (p_ptr->grace > 5000) p_ptr->invis += 30;
- if (p_ptr->grace > 15000) p_ptr->immune_fire = TRUE;
+ if (p_ptr->grace > 15000) p_ptr->immune_fire = true;
}
- p_ptr->resist_fire = TRUE;
+ p_ptr->resist_fire = true;
}
/* Gifts of Manwe if the player is praying to Manwe */
@@ -2254,14 +2290,14 @@ static void calc_gods()
p_ptr->pspeed += add;
/* Provides fly & FA */
- if (p_ptr->grace >= 7000) p_ptr->free_act = TRUE;
- if (p_ptr->grace >= 15000) p_ptr->fly = TRUE;
+ if (p_ptr->grace >= 7000) p_ptr->free_act = true;
+ if (p_ptr->grace >= 15000) p_ptr->fly = true;
}
/* Manwe bonus not requiring the praying status */
if (p_ptr->pgod == GOD_MANWE)
{
- if (p_ptr->grace >= 2000) p_ptr->ffall = TRUE;
+ if (p_ptr->grace >= 2000) p_ptr->ffall = true;
}
/* Boost Str and Con if the player is following Tulkas */
@@ -2285,7 +2321,7 @@ static void calc_gods()
/* Resist fire*/
if (p_ptr->grace > 5000)
{
- p_ptr->resist_fire = TRUE;
+ p_ptr->resist_fire = true;
}
bonus = p_ptr->grace / 5000;
@@ -2305,18 +2341,16 @@ static void calc_gods()
nether immunity and prevents teleportation. */
if (p_ptr->pgod == GOD_MANDOS)
{
- p_ptr->resist_neth = TRUE;
+ p_ptr->resist_neth = true;
- if ((p_ptr->grace > 10000) &&
- (p_ptr->praying == TRUE))
+ if (p_ptr->praying && (p_ptr->grace > 10000))
{
- p_ptr->resist_continuum = TRUE;
+ p_ptr->resist_continuum = true;
}
- if ((p_ptr->grace > 20000) &&
- (p_ptr->praying == TRUE))
+ if (p_ptr->praying && (p_ptr->grace > 20000))
{
- p_ptr->immune_neth = TRUE;
+ p_ptr->immune_neth = true;
}
}
@@ -2324,18 +2358,16 @@ static void calc_gods()
provide poison resistance and magic breath. */
if (p_ptr->pgod == GOD_ULMO)
{
- p_ptr->water_breath = TRUE;
+ p_ptr->water_breath = true;
- if ((p_ptr->grace > 1000) &&
- (p_ptr->praying == TRUE))
+ if (p_ptr->praying && (p_ptr->grace > 1000))
{
- p_ptr->resist_pois = TRUE;
+ p_ptr->resist_pois = true;
}
- if ((p_ptr->grace > 15000) &&
- (p_ptr->praying == TRUE))
+ if (p_ptr->praying && (p_ptr->grace > 15000))
{
- p_ptr->magical_breath = TRUE;
+ p_ptr->magical_breath = true;
}
}
}
@@ -2345,12 +2377,12 @@ static void calc_schools()
{
if (get_skill(SKILL_AIR) >= 50)
{
- p_ptr->magical_breath = TRUE;
+ p_ptr->magical_breath = true;
}
if (get_skill(SKILL_WATER) >= 30)
{
- p_ptr->water_breath = TRUE;
+ p_ptr->water_breath = true;
}
}
@@ -2415,9 +2447,9 @@ static void calc_corruptions()
if (player_has_corruption(CORRUPT_ANTI_TELEPORT))
{
- if (p_ptr->corrupt_anti_teleport_stopped == FALSE)
+ if (!p_ptr->corrupt_anti_teleport_stopped)
{
- p_ptr->resist_continuum = TRUE;
+ p_ptr->resist_continuum = true;
}
}
@@ -2472,10 +2504,10 @@ void apply_flags(object_flag_set const &f, s16b pval, s16b tval, s16b to_h, s16b
if (f & TR_CRIT) p_ptr->xtra_crit += pval;
/* Hack -- Sensible fire */
- if (f & TR_SENS_FIRE) p_ptr->sensible_fire = TRUE;
+ if (f & TR_SENS_FIRE) p_ptr->sensible_fire = true;
/* Hack -- cause earthquakes */
- if (f & TR_IMPACT) p_ptr->impact = TRUE;
+ if (f & TR_IMPACT) p_ptr->impact = true;
/* Affect invisibility */
if (f & TR_INVIS) p_ptr->invis += (pval * 10);
@@ -2484,66 +2516,66 @@ void apply_flags(object_flag_set const &f, s16b pval, s16b tval, s16b to_h, s16b
if (f & TR_XTRA_SHOTS) extra_shots++;
/* Various flags */
- if (f & TR_AGGRAVATE) p_ptr->aggravate = TRUE;
- if (f & TR_TELEPORT) p_ptr->teleport = TRUE;
+ if (f & TR_AGGRAVATE) p_ptr->aggravate = true;
+ if (f & TR_TELEPORT) p_ptr->teleport = true;
if (f & TR_DRAIN_MANA) p_ptr->drain_mana++;
if (f & TR_DRAIN_HP) p_ptr->drain_life++;
- if (f & TR_DRAIN_EXP) p_ptr->exp_drain = TRUE;
- if (f & TR_BLESSED) p_ptr->bless_blade = TRUE;
+ if (f & TR_DRAIN_EXP) p_ptr->exp_drain = true;
+ if (f & TR_BLESSED) p_ptr->bless_blade = true;
if (f & TR_XTRA_MIGHT) p_ptr->xtra_might += pval;
- if (f & TR_SLOW_DIGEST) p_ptr->slow_digest = TRUE;
- if (f & TR_REGEN) p_ptr->regenerate = TRUE;
- if ((tval != TV_LITE) && (f & TR_LITE1)) p_ptr->lite = TRUE;
- if ((tval != TV_LITE) && (f & TR_LITE2)) p_ptr->lite = TRUE;
- if ((tval != TV_LITE) && (f & TR_LITE3)) p_ptr->lite = TRUE;
- if (f & TR_SEE_INVIS) p_ptr->see_inv = TRUE;
- if (f & TR_FREE_ACT) p_ptr->free_act = TRUE;
- if (f & TR_HOLD_LIFE) p_ptr->hold_life = TRUE;
- if (f & TR_WRAITH) p_ptr->wraith_form = TRUE;
- if (f & TR_FEATHER) p_ptr->ffall = TRUE;
- if (f & TR_FLY) p_ptr->fly = TRUE;
- if (f & TR_CLIMB) p_ptr->climb = TRUE;
+ if (f & TR_SLOW_DIGEST) p_ptr->slow_digest = true;
+ if (f & TR_REGEN) p_ptr->regenerate = true;
+ if ((tval != TV_LITE) && (f & TR_LITE1)) p_ptr->lite = true;
+ if ((tval != TV_LITE) && (f & TR_LITE2)) p_ptr->lite = true;
+ if ((tval != TV_LITE) && (f & TR_LITE3)) p_ptr->lite = true;
+ if (f & TR_SEE_INVIS) p_ptr->see_inv = true;
+ if (f & TR_FREE_ACT) p_ptr->free_act = true;
+ if (f & TR_HOLD_LIFE) p_ptr->hold_life = true;
+ if (f & TR_WRAITH) p_ptr->wraith_form = true;
+ if (f & TR_FEATHER) p_ptr->ffall = true;
+ if (f & TR_FLY) p_ptr->fly = true;
+ if (f & TR_CLIMB) p_ptr->climb = true;
/* Immunity flags */
- if (f & TR_IM_FIRE) p_ptr->immune_fire = TRUE;
- if (f & TR_IM_ACID) p_ptr->immune_acid = TRUE;
- if (f & TR_IM_COLD) p_ptr->immune_cold = TRUE;
- if (f & TR_IM_ELEC) p_ptr->immune_elec = TRUE;
+ if (f & TR_IM_FIRE) p_ptr->immune_fire = true;
+ if (f & TR_IM_ACID) p_ptr->immune_acid = true;
+ if (f & TR_IM_COLD) p_ptr->immune_cold = true;
+ if (f & TR_IM_ELEC) p_ptr->immune_elec = true;
+ if (f & TR_IM_NETHER) p_ptr->immune_neth = true;
/* Resistance flags */
- if (f & TR_RES_ACID) p_ptr->resist_acid = TRUE;
- if (f & TR_RES_ELEC) p_ptr->resist_elec = TRUE;
- if (f & TR_RES_FIRE) p_ptr->resist_fire = TRUE;
- if (f & TR_RES_COLD) p_ptr->resist_cold = TRUE;
- if (f & TR_RES_POIS) p_ptr->resist_pois = TRUE;
- if (f & TR_RES_FEAR) p_ptr->resist_fear = TRUE;
- if (f & TR_RES_CONF) p_ptr->resist_conf = TRUE;
- if (f & TR_RES_SOUND) p_ptr->resist_sound = TRUE;
- if (f & TR_RES_LITE) p_ptr->resist_lite = TRUE;
- if (f & TR_RES_DARK) p_ptr->resist_dark = TRUE;
- if (f & TR_RES_CHAOS) p_ptr->resist_chaos = TRUE;
- if (f & TR_RES_DISEN) p_ptr->resist_disen = TRUE;
- if (f & TR_RES_SHARDS) p_ptr->resist_shard = TRUE;
- if (f & TR_RES_NEXUS) p_ptr->resist_nexus = TRUE;
- if (f & TR_RES_BLIND) p_ptr->resist_blind = TRUE;
- if (f & TR_RES_NETHER) p_ptr->resist_neth = TRUE;
- if (f & TR_IM_NETHER) p_ptr->immune_neth = TRUE;
-
- if (f & TR_REFLECT) p_ptr->reflect = TRUE;
- if (f & TR_SH_FIRE) p_ptr->sh_fire = TRUE;
- if (f & TR_SH_ELEC) p_ptr->sh_elec = TRUE;
- if (f & TR_NO_MAGIC) p_ptr->anti_magic = TRUE;
- if (f & TR_NO_TELE) p_ptr->anti_tele = TRUE;
+ if (f & TR_RES_ACID) p_ptr->resist_acid = true;
+ if (f & TR_RES_ELEC) p_ptr->resist_elec = true;
+ if (f & TR_RES_FIRE) p_ptr->resist_fire = true;
+ if (f & TR_RES_COLD) p_ptr->resist_cold = true;
+ if (f & TR_RES_POIS) p_ptr->resist_pois = true;
+ if (f & TR_RES_FEAR) p_ptr->resist_fear = true;
+ if (f & TR_RES_CONF) p_ptr->resist_conf = true;
+ if (f & TR_RES_SOUND) p_ptr->resist_sound = true;
+ if (f & TR_RES_LITE) p_ptr->resist_lite = true;
+ if (f & TR_RES_DARK) p_ptr->resist_dark = true;
+ if (f & TR_RES_CHAOS) p_ptr->resist_chaos = true;
+ if (f & TR_RES_DISEN) p_ptr->resist_disen = true;
+ if (f & TR_RES_SHARDS) p_ptr->resist_shard = true;
+ if (f & TR_RES_NEXUS) p_ptr->resist_nexus = true;
+ if (f & TR_RES_BLIND) p_ptr->resist_blind = true;
+ if (f & TR_RES_NETHER) p_ptr->resist_neth = true;
+
+ if (f & TR_REFLECT) p_ptr->reflect = true;
+ if (f & TR_SH_FIRE) p_ptr->sh_fire = true;
+ if (f & TR_SH_ELEC) p_ptr->sh_elec = true;
+ if (f & TR_NO_MAGIC) p_ptr->anti_magic = true;
+ if (f & TR_NO_TELE) p_ptr->anti_tele = true;
/* Sustain flags */
- if (f & TR_SUST_STR) p_ptr->sustain_str = TRUE;
- if (f & TR_SUST_INT) p_ptr->sustain_int = TRUE;
- if (f & TR_SUST_WIS) p_ptr->sustain_wis = TRUE;
- if (f & TR_SUST_DEX) p_ptr->sustain_dex = TRUE;
- if (f & TR_SUST_CON) p_ptr->sustain_con = TRUE;
- if (f & TR_SUST_CHR) p_ptr->sustain_chr = TRUE;
+ if (f & TR_SUST_STR) p_ptr->sustain_str = true;
+ if (f & TR_SUST_INT) p_ptr->sustain_int = true;
+ if (f & TR_SUST_WIS) p_ptr->sustain_wis = true;
+ if (f & TR_SUST_DEX) p_ptr->sustain_dex = true;
+ if (f & TR_SUST_CON) p_ptr->sustain_con = true;
+ if (f & TR_SUST_CHR) p_ptr->sustain_chr = true;
- if (f & TR_PRECOGNITION) p_ptr->precognition = TRUE;
+ if (f & TR_PRECOGNITION) p_ptr->precognition = true;
antimagic_mod = to_h + to_d + to_a;
@@ -2558,30 +2590,25 @@ void apply_flags(object_flag_set const &f, s16b pval, s16b tval, s16b to_h, s16b
if (tmp > 0) p_ptr->antimagic_dis += tmp;
}
- if (f & TR_AUTO_ID)
- {
- p_ptr->auto_id = TRUE;
- }
-
/* The new code implementing Tolkien's concept of "Black Breath"
* takes advantage of the existing drain_exp character flag, renamed
* "black_breath". This flag can also be set by a unlucky blow from
* an undead. -LM-
*/
- if (f & TR_BLACK_BREATH) p_ptr->black_breath = TRUE;
+ if (f & TR_BLACK_BREATH) p_ptr->black_breath = true;
- if (f & TR_IMMOVABLE) p_ptr->immovable = TRUE;
+ if (f & TR_IMMOVABLE) p_ptr->immovable = true;
/* Breaths */
if (f & TR_WATER_BREATH)
{
- p_ptr->water_breath = TRUE;
+ p_ptr->water_breath = true;
}
if (f & TR_MAGIC_BREATH)
{
- p_ptr->magical_breath = TRUE;
- p_ptr->water_breath = TRUE;
+ p_ptr->magical_breath = true;
+ p_ptr->water_breath = true;
}
}
@@ -2602,24 +2629,24 @@ static void apply_lflags(LF const &lflags)
/**
* Are barehand fighter's hands empty?
*/
-static bool_ monk_empty_hands()
+static bool monk_empty_hands()
{
- int i;
- object_type *o_ptr;
-
- if (p_ptr->melee_style != SKILL_HAND) return FALSE;
-
- i = 0;
- while (p_ptr->body_parts[i] == INVEN_WIELD)
+ if (p_ptr->melee_style != SKILL_HAND)
{
- o_ptr = &p_ptr->inventory[INVEN_WIELD + i];
+ return false;
+ }
- if (o_ptr->k_idx) return FALSE;
+ for (int i = 0; p_ptr->body_parts[i] == INVEN_WIELD; i++)
+ {
+ auto o_ptr = &p_ptr->inventory[INVEN_WIELD + i];
- i++;
+ if (o_ptr->k_ptr)
+ {
+ return false;
+ }
}
- return TRUE;
+ return true;
}
@@ -2643,23 +2670,23 @@ static bool_ monk_empty_hands()
* are actually added in later, at the appropriate place.
*
* This function induces various "status" messages, unless silent is
- * TRUE.
+ * true.
*/
-void calc_bonuses(bool_ silent)
+void calc_bonuses(bool silent)
{
auto const &s_descriptors = game->edit_data.s_descriptors;
auto const &r_info = game->edit_data.r_info;
auto &s_info = game->s_info;
auto const &a_info = game->edit_data.a_info;
- static bool_ monk_notify_aux = FALSE;
+ static bool monk_notify_aux = false;
int i, j, hold;
int old_speed;
- int old_see_inv;
+ bool old_see_inv;
int old_dis_ac;
int old_dis_to_a;
object_type *o_ptr;
- bool_ monk_armour_aux;
+ bool monk_armour_aux;
/* Save the old computed_flags */
@@ -2718,69 +2745,69 @@ void calc_bonuses(bool_ silent)
/* Clear all the flags */
p_ptr->invis = 0;
- p_ptr->immovable = FALSE;
- p_ptr->aggravate = FALSE;
- p_ptr->teleport = FALSE;
- p_ptr->exp_drain = FALSE;
+ p_ptr->immovable = false;
+ p_ptr->aggravate = false;
+ p_ptr->teleport = false;
+ p_ptr->exp_drain = false;
p_ptr->drain_mana = 0;
p_ptr->drain_life = 0;
- p_ptr->bless_blade = FALSE;
+ p_ptr->bless_blade = false;
p_ptr->xtra_might = 0;
- p_ptr->auto_id = FALSE;
- p_ptr->impact = FALSE;
- p_ptr->see_inv = FALSE;
- p_ptr->free_act = FALSE;
- p_ptr->slow_digest = FALSE;
- p_ptr->regenerate = FALSE;
- p_ptr->fly = FALSE;
- p_ptr->climb = FALSE;
- p_ptr->ffall = FALSE;
- p_ptr->hold_life = FALSE;
+ p_ptr->impact = false;
+ p_ptr->see_inv = false;
+ p_ptr->free_act = false;
+ p_ptr->slow_digest = false;
+ p_ptr->regenerate = false;
+ p_ptr->fly = false;
+ p_ptr->climb = false;
+ p_ptr->ffall = false;
+ p_ptr->hold_life = false;
p_ptr->computed_flags = object_flag_set();
- p_ptr->lite = FALSE;
- p_ptr->sustain_str = FALSE;
- p_ptr->sustain_int = FALSE;
- p_ptr->sustain_wis = FALSE;
- p_ptr->sustain_con = FALSE;
- p_ptr->sustain_dex = FALSE;
- p_ptr->sustain_chr = FALSE;
- p_ptr->resist_acid = FALSE;
- p_ptr->resist_elec = FALSE;
- p_ptr->resist_fire = FALSE;
- p_ptr->resist_cold = FALSE;
- p_ptr->resist_pois = FALSE;
- p_ptr->resist_conf = FALSE;
- p_ptr->resist_sound = FALSE;
- p_ptr->resist_lite = FALSE;
- p_ptr->resist_dark = FALSE;
- p_ptr->resist_chaos = FALSE;
- p_ptr->resist_disen = FALSE;
- p_ptr->resist_shard = FALSE;
- p_ptr->resist_nexus = FALSE;
- p_ptr->resist_blind = FALSE;
- p_ptr->resist_neth = FALSE;
- p_ptr->immune_neth = FALSE;
- p_ptr->resist_fear = FALSE;
- p_ptr->resist_continuum = FALSE;
- p_ptr->reflect = FALSE;
- p_ptr->sh_fire = FALSE;
- p_ptr->sh_elec = FALSE;
- p_ptr->anti_magic = FALSE;
- p_ptr->anti_tele = FALSE;
- p_ptr->water_breath = FALSE;
- p_ptr->magical_breath = FALSE;
-
- p_ptr->sensible_fire = FALSE;
- p_ptr->sensible_lite = FALSE;
-
- p_ptr->immune_acid = FALSE;
- p_ptr->immune_elec = FALSE;
- p_ptr->immune_fire = FALSE;
- p_ptr->immune_cold = FALSE;
-
- p_ptr->precognition = FALSE;
-
- p_ptr->wraith_form = FALSE;
+ p_ptr->lite = false;
+ p_ptr->sustain_str = false;
+ p_ptr->sustain_int = false;
+ p_ptr->sustain_wis = false;
+ p_ptr->sustain_con = false;
+ p_ptr->sustain_dex = false;
+ p_ptr->sustain_chr = false;
+ p_ptr->resist_acid = false;
+ p_ptr->resist_elec = false;
+ p_ptr->resist_fire = false;
+ p_ptr->resist_cold = false;
+ p_ptr->resist_pois = false;
+ p_ptr->resist_conf = false;
+ p_ptr->resist_sound = false;
+ p_ptr->resist_lite = false;
+ p_ptr->resist_dark = false;
+ p_ptr->resist_chaos = false;
+ p_ptr->resist_disen = false;
+ p_ptr->resist_shard = false;
+ p_ptr->resist_nexus = false;
+ p_ptr->resist_blind = false;
+ p_ptr->resist_neth = false;
+ p_ptr->resist_fear = false;
+ p_ptr->resist_continuum = false;
+ p_ptr->reflect = false;
+ p_ptr->sh_fire = false;
+ p_ptr->sh_elec = false;
+ p_ptr->anti_magic = false;
+ p_ptr->anti_tele = false;
+
+ p_ptr->water_breath = false;
+ p_ptr->magical_breath = false;
+
+ p_ptr->sensible_fire = false;
+ p_ptr->sensible_lite = false;
+
+ p_ptr->immune_acid = false;
+ p_ptr->immune_elec = false;
+ p_ptr->immune_fire = false;
+ p_ptr->immune_cold = false;
+ p_ptr->immune_neth = false;
+
+ p_ptr->precognition = false;
+
+ p_ptr->wraith_form = false;
/* The anti magic field surrounding the player */
p_ptr->antimagic = 0;
@@ -2857,7 +2884,7 @@ void calc_bonuses(bool_ silent)
/* Free action if unencumbered at level 25 */
if ((get_skill(SKILL_HAND) > 24) && !(monk_heavy_armor()))
- p_ptr->free_act = TRUE;
+ p_ptr->free_act = true;
}
if (get_skill(SKILL_ANTIMAGIC))
@@ -2867,13 +2894,13 @@ void calc_bonuses(bool_ silent)
if (p_ptr->antimagic_extra & CLASS_ANTIMAGIC)
{
- p_ptr->anti_tele = TRUE;
- p_ptr->resist_continuum = TRUE;
+ p_ptr->anti_tele = true;
+ p_ptr->resist_continuum = true;
}
}
- if (get_skill(SKILL_DAEMON) > 20) p_ptr->resist_conf = TRUE;
- if (get_skill(SKILL_DAEMON) > 30) p_ptr->resist_fear = TRUE;
+ if (get_skill(SKILL_DAEMON) > 20) p_ptr->resist_conf = true;
+ if (get_skill(SKILL_DAEMON) > 30) p_ptr->resist_fear = true;
if ( get_skill(SKILL_MINDCRAFT) >= 40 )
{
@@ -2882,7 +2909,7 @@ void calc_bonuses(bool_ silent)
if (p_ptr->astral)
{
- p_ptr->wraith_form = TRUE;
+ p_ptr->wraith_form = true;
}
/***** Races ****/
@@ -2894,7 +2921,9 @@ void calc_bonuses(bool_ silent)
/* Is the player's race hurt by light? */
if (race_flags_p(PR_HURT_LITE))
- p_ptr->sensible_lite = TRUE;
+ {
+ p_ptr->sensible_lite = true;
+ }
}
/* The extra flags */
@@ -2914,17 +2943,20 @@ void calc_bonuses(bool_ silent)
o_ptr = &p_ptr->inventory[i];
/* Skip non-objects */
- if (!o_ptr->k_idx) continue;
+ if (!o_ptr->k_ptr)
+ {
+ continue;
+ }
/* Extract the item flags */
- object_flags_no_set = TRUE;
+ object_flags_no_set = true;
auto flags = object_flags(o_ptr);
- object_flags_no_set = FALSE;
+ object_flags_no_set = false;
/* MEGA ugly hack -- set spacetime distortion resistance */
if (o_ptr->name1 == ART_ANCHOR)
{
- p_ptr->resist_continuum = TRUE;
+ p_ptr->resist_continuum = true;
}
/* Hack - don't give the Black Breath when merely inspecting a weapon */
@@ -2950,7 +2982,7 @@ void calc_bonuses(bool_ silent)
p_ptr->to_a += o_ptr->to_a;
/* Apply the mental bonuses to armor class, if known */
- if (object_known_p(o_ptr)) p_ptr->dis_to_a += o_ptr->to_a;
+ p_ptr->dis_to_a += o_ptr->to_a;
/* Hack -- do not apply "weapon" bonuses */
if (p_ptr->body_parts[i - INVEN_WIELD] == INVEN_WIELD) continue;
@@ -2969,39 +3001,39 @@ void calc_bonuses(bool_ silent)
p_ptr->to_d += o_ptr->to_d;
/* Apply the mental bonuses tp hit/damage, if known */
- if (object_known_p(o_ptr)) p_ptr->dis_to_h += o_ptr->to_h;
- if (object_known_p(o_ptr)) p_ptr->dis_to_d += o_ptr->to_d;
+ p_ptr->dis_to_h += o_ptr->to_h;
+ p_ptr->dis_to_d += o_ptr->to_d;
}
/* Monks get extra ac for armour _not worn_ */
if ((p_ptr->melee_style == SKILL_HAND) && !(monk_heavy_armor()))
{
- if (!(p_ptr->inventory[INVEN_BODY].k_idx))
+ if (!(p_ptr->inventory[INVEN_BODY].k_ptr))
{
p_ptr->to_a += get_skill_scale(SKILL_HAND, 75);
p_ptr->dis_to_a += get_skill_scale(SKILL_HAND, 75);
}
- if (!(p_ptr->inventory[INVEN_OUTER].k_idx) && (get_skill(SKILL_HAND) > 15))
+ if (!(p_ptr->inventory[INVEN_OUTER].k_ptr) && (get_skill(SKILL_HAND) > 15))
{
p_ptr->to_a += ((get_skill(SKILL_HAND) - 13) / 3);
p_ptr->dis_to_a += ((get_skill(SKILL_HAND) - 13) / 3);
}
- if (!(p_ptr->inventory[INVEN_ARM].k_idx) && (get_skill(SKILL_HAND) > 10))
+ if (!(p_ptr->inventory[INVEN_ARM].k_ptr) && (get_skill(SKILL_HAND) > 10))
{
p_ptr->to_a += ((get_skill(SKILL_HAND) - 8) / 3);
p_ptr->dis_to_a += ((get_skill(SKILL_HAND) - 8) / 3);
}
- if (!(p_ptr->inventory[INVEN_HEAD].k_idx) && (get_skill(SKILL_HAND) > 4))
+ if (!(p_ptr->inventory[INVEN_HEAD].k_ptr) && (get_skill(SKILL_HAND) > 4))
{
p_ptr->to_a += (get_skill(SKILL_HAND) - 2) / 3;
p_ptr->dis_to_a += (get_skill(SKILL_HAND) - 2) / 3;
}
- if (!(p_ptr->inventory[INVEN_HANDS].k_idx))
+ if (!(p_ptr->inventory[INVEN_HANDS].k_ptr))
{
p_ptr->to_a += (get_skill(SKILL_HAND) / 2);
p_ptr->dis_to_a += (get_skill(SKILL_HAND) / 2);
}
- if (!(p_ptr->inventory[INVEN_FEET].k_idx))
+ if (!(p_ptr->inventory[INVEN_FEET].k_ptr))
{
p_ptr->to_a += (get_skill(SKILL_HAND) / 3);
p_ptr->dis_to_a += (get_skill(SKILL_HAND) / 3);
@@ -3009,7 +3041,10 @@ void calc_bonuses(bool_ silent)
}
/* Hack -- aura of fire also provides light */
- if (p_ptr->sh_fire) p_ptr->lite = TRUE;
+ if (p_ptr->sh_fire)
+ {
+ p_ptr->lite = true;
+ }
if (race_flags_p(PR_AC_LEVEL))
{
@@ -3154,11 +3189,11 @@ void calc_bonuses(bool_ silent)
/* Breath */
if (p_ptr->tim_water_breath)
{
- p_ptr->water_breath = TRUE;
+ p_ptr->water_breath = true;
}
if (p_ptr->tim_magic_breath)
{
- p_ptr->magical_breath = TRUE;
+ p_ptr->magical_breath = true;
}
/* wraith_form */
@@ -3173,15 +3208,15 @@ void calc_bonuses(bool_ silent)
{
p_ptr->to_a += 50;
p_ptr->dis_to_a += 50;
- p_ptr->reflect = TRUE;
+ p_ptr->reflect = true;
}
- p_ptr->wraith_form = TRUE;
+ p_ptr->wraith_form = true;
}
/* Temporary holy aura */
if (p_ptr->holy)
{
- p_ptr->hold_life = TRUE;
+ p_ptr->hold_life = true;
p_ptr->luck_cur += 5;
}
@@ -3244,24 +3279,24 @@ void calc_bonuses(bool_ silent)
/* Temporary "Reflection" */
if (p_ptr->tim_reflect)
{
- p_ptr->reflect = TRUE;
+ p_ptr->reflect = true;
}
/* Temporary "Levitation" and "Flying" */
if (p_ptr->tim_ffall)
{
- p_ptr->ffall = TRUE;
+ p_ptr->ffall = true;
}
if (p_ptr->tim_fly)
{
- p_ptr->fly = TRUE;
+ p_ptr->fly = true;
}
/* Oppose Chaos & Confusion */
if (p_ptr->oppose_cc)
{
- p_ptr->resist_chaos = TRUE;
- p_ptr->resist_conf = TRUE;
+ p_ptr->resist_chaos = true;
+ p_ptr->resist_conf = true;
}
/* Temporary "fast" */
@@ -3290,7 +3325,7 @@ void calc_bonuses(bool_ silent)
/* Temporary see invisible */
if (p_ptr->tim_invis)
{
- p_ptr->see_inv = TRUE;
+ p_ptr->see_inv = true;
}
/* Temporary infravision boost */
@@ -3302,25 +3337,25 @@ void calc_bonuses(bool_ silent)
/* Hack -- Magic breath -> Water breath */
if (p_ptr->magical_breath)
{
- p_ptr->water_breath = TRUE;
+ p_ptr->water_breath = true;
}
/* Hack -- Can Fly -> Can Levitate */
if (p_ptr->fly)
{
- p_ptr->ffall = TRUE;
+ p_ptr->ffall = true;
}
/* Hack -- Res Chaos -> Res Conf */
if (p_ptr->resist_chaos)
{
- p_ptr->resist_conf = TRUE;
+ p_ptr->resist_conf = true;
}
/* Hack -- Hero/Shero -> Res fear */
if (p_ptr->hero || p_ptr->shero)
{
- p_ptr->resist_fear = TRUE;
+ p_ptr->resist_fear = true;
}
@@ -3388,7 +3423,7 @@ void calc_bonuses(bool_ silent)
/* Assume not heavy */
- p_ptr->heavy_shoot = FALSE;
+ p_ptr->heavy_shoot = false;
/* It is hard to carholdry a heavy bow */
if (hold < o_ptr->weight / 10)
@@ -3398,7 +3433,7 @@ void calc_bonuses(bool_ silent)
p_ptr->dis_to_h += 2 * (hold - o_ptr->weight / 10);
/* Heavy Bow */
- p_ptr->heavy_shoot = TRUE;
+ p_ptr->heavy_shoot = true;
}
/* Take note of required "tval" for missiles */
@@ -3426,7 +3461,7 @@ void calc_bonuses(bool_ silent)
}
/* Compute "extra shots" if needed */
- if (o_ptr->k_idx && !p_ptr->heavy_shoot)
+ if (o_ptr->k_ptr && !p_ptr->heavy_shoot)
{
int archery = get_archery_skill();
@@ -3469,7 +3504,7 @@ void calc_bonuses(bool_ silent)
o_ptr = &p_ptr->inventory[INVEN_TOOL];
/* Boost digging skill by tool weight */
- if (o_ptr->k_idx && (o_ptr->tval == TV_DIGGING))
+ if (o_ptr->k_ptr && (o_ptr->tval == TV_DIGGING))
{
p_ptr->skill_dig += (o_ptr->weight / 10);
}
@@ -3478,10 +3513,10 @@ void calc_bonuses(bool_ silent)
o_ptr = &p_ptr->inventory[INVEN_WIELD];
/* Assume not heavy */
- p_ptr->heavy_wield = FALSE;
+ p_ptr->heavy_wield = false;
/* Normal weapons */
- if (o_ptr->k_idx && !p_ptr->heavy_wield)
+ if (o_ptr->k_ptr && !p_ptr->heavy_wield)
{
int str_index, dex_index;
@@ -3612,8 +3647,8 @@ void calc_bonuses(bool_ silent)
}
/* Assume okay */
- p_ptr->icky_wield = FALSE;
- monk_armour_aux = FALSE;
+ p_ptr->icky_wield = false;
+ monk_armour_aux = false;
if (get_weaponmastery_skill() != -1)
{
@@ -3667,7 +3702,7 @@ void calc_bonuses(bool_ silent)
o_ptr = &p_ptr->inventory[INVEN_WIELD + i];
/* 2handed weapon and shield = less damage */
- if (p_ptr->inventory[INVEN_WIELD + i].k_idx && p_ptr->inventory[INVEN_ARM + i].k_idx)
+ if (o_ptr->k_ptr && p_ptr->inventory[INVEN_ARM + i].k_ptr)
{
auto const flags = object_flags(&p_ptr->inventory[INVEN_WIELD + i]);
if (flags & TR_COULD2H)
@@ -3687,8 +3722,10 @@ void calc_bonuses(bool_ silent)
}
/* Priest weapon penalty for non-blessed edged weapons */
- if (((forbid_non_blessed()) && (!p_ptr->bless_blade) &&
- ((o_ptr->tval == TV_AXE) || (o_ptr->tval == TV_SWORD) || (o_ptr->tval == TV_POLEARM))) && (o_ptr->k_idx))
+ if (((forbid_non_blessed()) &&
+ (!p_ptr->bless_blade) &&
+ ((o_ptr->tval == TV_AXE) || (o_ptr->tval == TV_SWORD) || (o_ptr->tval == TV_POLEARM))) &&
+ o_ptr->k_ptr)
{
/* Reduce the real bonuses */
p_ptr->to_h -= 15;
@@ -3699,7 +3736,7 @@ void calc_bonuses(bool_ silent)
p_ptr->dis_to_d -= 15;
/* Icky weapon */
- p_ptr->icky_wield = TRUE;
+ p_ptr->icky_wield = true;
}
/* Sorcerer can't wield a weapon unless it's a mage staff */
@@ -3707,7 +3744,8 @@ void calc_bonuses(bool_ silent)
{
int malus = get_skill_scale(SKILL_SORCERY, 100);
- if ((o_ptr->tval != TV_MSTAFF) && (o_ptr->k_idx))
+ if ((o_ptr->tval != TV_MSTAFF) &&
+ o_ptr->k_ptr)
{
/* Reduce the real bonuses */
p_ptr->to_h -= malus;
@@ -3718,7 +3756,7 @@ void calc_bonuses(bool_ silent)
p_ptr->dis_to_d -= malus;
/* Icky weapon */
- p_ptr->icky_wield = TRUE;
+ p_ptr->icky_wield = true;
}
else
{
@@ -3738,7 +3776,7 @@ void calc_bonuses(bool_ silent)
if (monk_heavy_armor())
{
- monk_armour_aux = TRUE;
+ monk_armour_aux = true;
}
/* Affect Skill -- stealth (bonus one) */
@@ -3793,7 +3831,7 @@ void calc_bonuses(bool_ silent)
{
msg_print("You have trouble wielding such a heavy bow.");
}
- else if (p_ptr->inventory[INVEN_BOW].k_idx)
+ else if (p_ptr->inventory[INVEN_BOW].k_ptr)
{
msg_print("You have no trouble wielding your bow.");
}
@@ -3819,7 +3857,7 @@ void calc_bonuses(bool_ silent)
{
msg_print("You have trouble wielding such a heavy weapon.");
}
- else if (p_ptr->inventory[INVEN_WIELD].k_idx)
+ else if (p_ptr->inventory[INVEN_WIELD].k_ptr)
{
msg_print("You have no trouble wielding your weapon.");
}
@@ -3845,7 +3883,7 @@ void calc_bonuses(bool_ silent)
{
msg_print("You do not feel comfortable with your weapon.");
}
- else if (p_ptr->inventory[INVEN_WIELD].k_idx)
+ else if (p_ptr->inventory[INVEN_WIELD].k_ptr)
{
msg_print("You feel comfortable with your weapon.");
}
@@ -3874,12 +3912,12 @@ void calc_bonuses(bool_ silent)
/* Resist lite & senseible lite negates one an other */
if (p_ptr->resist_lite && p_ptr->sensible_lite)
{
- p_ptr->resist_lite = p_ptr->sensible_lite = FALSE;
+ p_ptr->resist_lite = p_ptr->sensible_lite = false;
}
/* resistance to fire cancel sensibility to fire */
if (p_ptr->resist_fire || p_ptr->oppose_fire || p_ptr->immune_fire)
- p_ptr->sensible_fire = FALSE;
+ p_ptr->sensible_fire = false;
/* Minimum saving throw */
if(p_ptr->skill_sav <= 10)
@@ -3937,7 +3975,7 @@ void update_stuff()
calc_powers();
p_ptr->update &= ~(PU_BONUS);
- calc_bonuses(FALSE);
+ calc_bonuses(false);
}
if (p_ptr->update & (PU_TORCH))
@@ -4005,13 +4043,13 @@ void update_stuff()
{
p_ptr->update &= ~(PU_DISTANCE);
p_ptr->update &= ~(PU_MONSTERS);
- update_monsters(TRUE);
+ update_monsters(true);
}
if (p_ptr->update & (PU_MONSTERS))
{
p_ptr->update &= ~(PU_MONSTERS);
- update_monsters(FALSE);
+ update_monsters(false);
}
if (p_ptr->update & (PU_MON_LITE))
@@ -4164,11 +4202,14 @@ void handle_stuff()
}
-bool_ monk_heavy_armor()
+bool monk_heavy_armor()
{
u16b monk_arm_wgt = 0;
- if (p_ptr->melee_style != SKILL_HAND) return FALSE;
+ if (p_ptr->melee_style != SKILL_HAND)
+ {
+ return false;
+ }
/* Weight the armor */
monk_arm_wgt += p_ptr->inventory[INVEN_BODY].weight;
@@ -4178,7 +4219,7 @@ bool_ monk_heavy_armor()
monk_arm_wgt += p_ptr->inventory[INVEN_HANDS].weight;
monk_arm_wgt += p_ptr->inventory[INVEN_FEET].weight;
- return (monk_arm_wgt > (100 + (get_skill(SKILL_HAND) * 4))) ;
+ return monk_arm_wgt > (100 + (get_skill(SKILL_HAND) * 4));
}
static int get_artifact_idx(int level)
@@ -4287,7 +4328,7 @@ void gain_fate(byte fate)
{
case FATE_FIND_O:
{
- while (TRUE)
+ while (true)
{
obj_theme theme;
@@ -4299,7 +4340,7 @@ void gain_fate(byte fate)
init_match_theme(theme);
/* Apply restriction */
- get_obj_num_hook = kind_is_legal;
+ get_object_hook = kind_is_legal;
/* Rebuild allocation table */
get_obj_num_prep();
@@ -4309,14 +4350,18 @@ void gain_fate(byte fate)
/* Invalidate the cached allocation table */
alloc.kind_table_valid = false;
- auto k_ptr = &k_info[fates[i].o_idx];
+ auto const &k_ptr = k_info.at(fates[i].o_idx);
- if (!(k_ptr->flags & TR_INSTA_ART) && !(k_ptr->flags & TR_NORM_ART)) break;
+ if (!(k_ptr->flags & TR_INSTA_ART)
+ && !(k_ptr->flags & TR_NORM_ART))
+ {
+ break;
+ }
}
level = rand_range(max_dlv[dungeon_type] - 20, max_dlv[dungeon_type] + 20);
fates[i].level = (level < 1) ? 1 : (level > 98) ? 98 : level;
fates[i].serious = rand_int(2);
- fates[i].know = FALSE;
+ fates[i].know = false;
if (wizard) msg_format("New fate : Find object %d on level %d", fates[i].o_idx, fates[i].level);
break;
}
@@ -4328,7 +4373,7 @@ void gain_fate(byte fate)
level = rand_range(max_dlv[dungeon_type] - 20, max_dlv[dungeon_type] + 20);
fates[i].level = (level < 1) ? 1 : (level > 98) ? 98 : level;
fates[i].serious = rand_int(2);
- fates[i].know = FALSE;
+ fates[i].know = false;
if (wizard) msg_format("New fate : Meet monster %d on level %d", fates[i].r_idx, fates[i].level);
break;
@@ -4336,22 +4381,22 @@ void gain_fate(byte fate)
fates[i].a_idx = get_artifact_idx(max_dlv[dungeon_type] + randint(10));
level = rand_range(max_dlv[dungeon_type] - 20, max_dlv[dungeon_type] + 20);
fates[i].level = (level < 1) ? 1 : (level > 98) ? 98 : level;
- fates[i].serious = TRUE;
- fates[i].know = FALSE;
+ fates[i].serious = true;
+ fates[i].know = false;
if (wizard) msg_format("New fate : Find artifact %d on level %d", fates[i].a_idx, fates[i].level);
break;
case FATE_DIE:
level = rand_range(max_dlv[dungeon_type] - 20, max_dlv[dungeon_type] + 20);
fates[i].level = (level < 1) ? 1 : (level > 98) ? 98 : level;
- fates[i].serious = TRUE;
- fates[i].know = FALSE;
+ fates[i].serious = true;
+ fates[i].know = false;
if ((wizard) || (p_ptr->precognition)) msg_format("New fate : Death on level %d", fates[i].level);
break;
case FATE_NO_DIE_MORTAL:
- fates[i].serious = TRUE;
- p_ptr->no_mortal = TRUE;
+ fates[i].serious = true;
+ p_ptr->no_mortal = true;
if ((wizard) || (p_ptr->precognition)) msg_format("New fate : Never to die by the hand of a mortal being.");
break;
}
@@ -4432,7 +4477,10 @@ std::string fate_desc(int fate)
q_ptr->weight = a_ptr->weight;
/* Hack -- acquire "cursed" flag */
- if (a_ptr->flags & (TR_CURSED)) q_ptr->ident |= (IDENT_CURSED);
+ if (a_ptr->flags & TR_CURSED)
+ {
+ q_ptr->art_flags |= TR_CURSED;
+ }
random_artifact_resistance(q_ptr);
@@ -4467,7 +4515,7 @@ std::string fate_desc(int fate)
std::string dump_fates()
{
- bool_ pending = FALSE;
+ bool pending = false;
fmt::MemoryWriter w;
diff --git a/src/xtra1.hpp b/src/xtra1.hpp
index 4fde1619..32eeea05 100644
--- a/src/xtra1.hpp
+++ b/src/xtra1.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "object_flag_set.hpp"
#include "player_race_flag_set.hpp"
@@ -10,7 +10,7 @@ void fix_message();
void apply_flags(object_flag_set const &f, s16b pval, s16b tval, s16b to_h, s16b to_d, s16b to_a);
int luck(int min, int max);
int weight_limit();
-extern bool_ calc_powers_silent;
+extern bool calc_powers_silent;
void cnv_stat(int i, char *out_val);
s16b modify_stat_value(int value, int amount);
void calc_hitpoints();
@@ -19,8 +19,8 @@ void update_stuff();
void redraw_stuff();
void window_stuff();
void handle_stuff();
-bool_ monk_heavy_armor();
-void calc_bonuses(bool_ silent);
+bool monk_heavy_armor();
+void calc_bonuses(bool silent);
void gain_fate(byte fate);
std::string fate_desc(int fate);
std::string dump_fates();
diff --git a/src/xtra2.cc b/src/xtra2.cc
index d8b87f51..d251298a 100644
--- a/src/xtra2.cc
+++ b/src/xtra2.cc
@@ -52,8 +52,6 @@
#include "store_info_type.hpp"
#include "tables.hpp"
#include "util.hpp"
-#include "util.h"
-#include "variable.h"
#include "variable.hpp"
#include "wilderness_map.hpp"
#include "wilderness_type_info.hpp"
@@ -66,9 +64,8 @@
#include <fmt/format.h>
#include <type_traits>
-
-
using boost::algorithm::iequals;
+using boost::algorithm::starts_with;
static void corrupt_corrupted();
@@ -76,9 +73,9 @@ static void corrupt_corrupted();
* Set "p_ptr->parasite" and "p_ptr->parasite_r_idx"
* notice observable changes
*/
-bool_ set_parasite(int v, int r)
+bool set_parasite(int v, int r)
{
- bool_ notice = FALSE;
+ bool notice = false;
/* Hack -- Force good values */
v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
@@ -89,7 +86,7 @@ bool_ set_parasite(int v, int r)
if (!p_ptr->parasite)
{
msg_print("You feel something growing in you.");
- notice = TRUE;
+ notice = true;
}
}
@@ -112,7 +109,7 @@ bool_ set_parasite(int v, int r)
}
while (!(in_bounds(wy, wx) && cave_floor_bold(wy, wx)) && --attempts);
- if (place_monster_one(wy, wx, p_ptr->parasite_r_idx, 0, FALSE, MSTATUS_ENEMY))
+ if (place_monster_one(wy, wx, p_ptr->parasite_r_idx, 0, false, MSTATUS_ENEMY))
{
cmsg_format(TERM_L_BLUE, "Your body convulses and spawns %s.", r_name);
p_ptr->food -= 750;
@@ -123,7 +120,7 @@ bool_ set_parasite(int v, int r)
{
cmsg_print(TERM_L_BLUE, "The hideous thing growing in you seems to die.");
}
- notice = TRUE;
+ notice = true;
}
}
@@ -132,7 +129,7 @@ bool_ set_parasite(int v, int r)
p_ptr->parasite_r_idx = r;
/* Nothing to notice */
- if (!notice) return (FALSE);
+ if (!notice) return false;
/* Disturb */
disturb_on_state();
@@ -141,21 +138,21 @@ bool_ set_parasite(int v, int r)
p_ptr->update |= (PU_BONUS);
/* Result */
- return (TRUE);
+ return true;
}
/*
* Set a simple player field.
*/
-static bool_ set_simple_field(
+static bool set_simple_field(
s16b *p_field,
s16b v,
byte activate_color,
- cptr activate_msg,
+ const char *activate_msg,
byte deactivate_color,
- cptr deactivate_msg)
+ const char *deactivate_msg)
{
- bool_ notice = FALSE;
+ bool notice = false;
/* Hack -- Force good values */
v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
@@ -166,7 +163,7 @@ static bool_ set_simple_field(
if (!*p_field)
{
cmsg_print(activate_color, activate_msg);
- notice = TRUE;
+ notice = true;
}
}
@@ -176,7 +173,7 @@ static bool_ set_simple_field(
if (*p_field)
{
cmsg_print(deactivate_color, deactivate_msg);
- notice = TRUE;
+ notice = true;
}
}
@@ -185,7 +182,7 @@ static bool_ set_simple_field(
/* Nothing to notice */
if (!notice)
- return (FALSE);
+ return false;
/* Disturb */
disturb_on_state();
@@ -194,16 +191,16 @@ static bool_ set_simple_field(
p_ptr->update |= (PU_BONUS);
/* Result */
- return (TRUE);
+ return true;
}
/*
* Set "p_ptr->tim_project" and others
* notice observable changes
*/
-bool_ set_project(int v, s16b gf, s16b dam, s16b rad, s16b flag)
+bool set_project(int v, s16b gf, s16b dam, s16b rad, s16b flag)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->tim_project, v,
TERM_WHITE, "Your weapon starts glowing.",
TERM_WHITE, "Your weapon stops glowing.");
@@ -222,9 +219,9 @@ bool_ set_project(int v, s16b gf, s16b dam, s16b rad, s16b flag)
* Set "p_ptr->tim_roots" and others
* notice observable changes
*/
-bool_ set_roots(int v, s16b ac, s16b dam)
+bool set_roots(int v, s16b ac, s16b dam)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->tim_roots, v,
TERM_WHITE, "Roots dive into the floor from your feet.",
TERM_WHITE, "The roots of your feet suddenly vanish.");
@@ -241,7 +238,7 @@ bool_ set_roots(int v, s16b ac, s16b dam)
* Set "p_ptr->tim_(magic|water)_breath" and others
* notice observable changes
*/
-bool_ set_tim_breath(int v, bool_ magical)
+bool set_tim_breath(int v, bool magical)
{
if (magical)
{
@@ -262,7 +259,7 @@ bool_ set_tim_breath(int v, bool_ magical)
/*
* Set timered precognition
*/
-bool_ set_tim_precognition(int v)
+bool set_tim_precognition(int v)
{
return set_simple_field(
&p_ptr->tim_precognition, v,
@@ -274,7 +271,7 @@ bool_ set_tim_precognition(int v)
* Set "p_ptr->absorb_soul"
* notice observable changes
*/
-bool_ set_absorb_soul(int v)
+bool set_absorb_soul(int v)
{
return set_simple_field(
&p_ptr->absorb_soul, v,
@@ -286,7 +283,7 @@ bool_ set_absorb_soul(int v)
* Set "p_ptr->disrupt_shield"
* notice observable changes
*/
-bool_ set_disrupt_shield(int v)
+bool set_disrupt_shield(int v)
{
return set_simple_field(
&p_ptr->disrupt_shield, v,
@@ -298,7 +295,7 @@ bool_ set_disrupt_shield(int v)
* Set "p_ptr->prob_travel"
* notice observable changes
*/
-bool_ set_prob_travel(int v)
+bool set_prob_travel(int v)
{
return set_simple_field(
&p_ptr->prob_travel, v,
@@ -310,9 +307,9 @@ bool_ set_prob_travel(int v)
* Set "p_ptr->tim_invis", and "p_ptr->tim_inv_pow",
* notice observable changes
*/
-bool_ set_invis(int v, int p)
+bool set_invis(int v, int p)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->tim_invisible, v,
TERM_WHITE, "You feel your body fade away.",
TERM_WHITE, "You are no longer invisible.");
@@ -328,7 +325,7 @@ bool_ set_invis(int v, int p)
* Set "p_ptr->tim_poison",
* notice observable changes
*/
-bool_ set_poison(int v)
+bool set_poison(int v)
{
return set_simple_field(
&p_ptr->tim_poison, v,
@@ -339,7 +336,7 @@ bool_ set_poison(int v)
/*
* Set "no_breeds"
*/
-bool_ set_no_breeders(int v)
+bool set_no_breeders(int v)
{
return set_simple_field(
&no_breeds, v,
@@ -350,7 +347,7 @@ bool_ set_no_breeders(int v)
/*
* Set "p_ptr->tim_deadly"
*/
-bool_ set_tim_deadly(int v)
+bool set_tim_deadly(int v)
{
return set_simple_field(
&p_ptr->tim_deadly, v,
@@ -361,7 +358,7 @@ bool_ set_tim_deadly(int v)
/*
* Set "p_ptr->tim_ffall"
*/
-bool_ set_tim_ffall(int v)
+bool set_tim_ffall(int v)
{
return set_simple_field(
&p_ptr->tim_ffall, v,
@@ -372,7 +369,7 @@ bool_ set_tim_ffall(int v)
/*
* Set "p_ptr->tim_fly"
*/
-bool_ set_tim_fly(int v)
+bool set_tim_fly(int v)
{
return set_simple_field(
&p_ptr->tim_fly, v,
@@ -383,7 +380,7 @@ bool_ set_tim_fly(int v)
/*
* Set "p_ptr->tim_reflect"
*/
-bool_ set_tim_reflect(int v)
+bool set_tim_reflect(int v)
{
return set_simple_field(
&p_ptr->tim_reflect, v,
@@ -394,7 +391,7 @@ bool_ set_tim_reflect(int v)
/*
* Set "p_ptr->strike"
*/
-bool_ set_strike(int v)
+bool set_strike(int v)
{
return set_simple_field(
&p_ptr->strike, v,
@@ -405,7 +402,7 @@ bool_ set_strike(int v)
/*
* Set "p_ptr->oppose_cc"
*/
-bool_ set_oppose_cc(int v)
+bool set_oppose_cc(int v)
{
return set_simple_field(
&p_ptr->oppose_cc, v,
@@ -417,11 +414,11 @@ bool_ set_oppose_cc(int v)
* Set "p_ptr->tim_mimic", and "p_ptr->mimic_form",
* notice observable changes
*/
-bool_ set_mimic(int v, int p, int level)
+bool set_mimic(int v, int p, int level)
{
auto &s_info = game->s_info;
- bool_ notice = FALSE;
+ bool notice = false;
/* Hack -- Force good values */
v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
@@ -433,7 +430,7 @@ bool_ set_mimic(int v, int p, int level)
{
msg_print("You feel your body change.");
p_ptr->mimic_form = p;
- notice = TRUE;
+ notice = true;
}
}
@@ -444,7 +441,7 @@ bool_ set_mimic(int v, int p, int level)
{
msg_print("You are no longer transformed.");
p_ptr->mimic_form = 0;
- notice = TRUE;
+ notice = true;
if (p == resolve_mimic_name("Bear"))
{
s_info[SKILL_BEAR].hidden = true;
@@ -459,7 +456,7 @@ bool_ set_mimic(int v, int p, int level)
p_ptr->mimic_level = level;
/* Nothing to notice */
- if (!notice) return (FALSE);
+ if (!notice) return false;
/* Disturb */
disturb_on_state();
@@ -471,7 +468,7 @@ bool_ set_mimic(int v, int p, int level)
p_ptr->update |= (PU_BODY | PU_BONUS | PU_SANITY);
/* Result */
- return (TRUE);
+ return true;
}
/*
@@ -482,9 +479,9 @@ bool_ set_mimic(int v, int p, int level)
* Note that blindness is currently the only thing which can affect
* "player_can_see_bold()".
*/
-bool_ set_blind(int v)
+bool set_blind(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->blind, v,
TERM_WHITE, "You are blind!",
TERM_WHITE, "You can see again.");
@@ -519,9 +516,9 @@ bool_ set_blind(int v)
* Note that blindness is currently the only thing which can affect
* "player_can_see_bold()".
*/
-bool_ set_lite(int v)
+bool set_lite(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->tim_lite, v,
TERM_WHITE, "You suddenly seem brighter!",
TERM_WHITE, "You are no longer bright.");
@@ -548,9 +545,9 @@ bool_ set_lite(int v)
/*
* Set "p_ptr->confused", notice observable changes
*/
-bool_ set_confused(int v)
+bool set_confused(int v)
{
- bool_ notice =
+ bool notice =
set_simple_field(
&p_ptr->confused, v,
TERM_WHITE, "You are confused!",
@@ -573,9 +570,9 @@ bool_ set_confused(int v)
/*
* Set "p_ptr->poisoned", notice observable changes
*/
-bool_ set_poisoned(int v)
+bool set_poisoned(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->poisoned, v,
TERM_WHITE, "You are poisoned!",
TERM_WHITE, "You are no longer poisoned.");
@@ -597,9 +594,9 @@ bool_ set_poisoned(int v)
/*
* Set "p_ptr->afraid", notice observable changes
*/
-bool_ set_afraid(int v)
+bool set_afraid(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->afraid, v,
TERM_WHITE, "You are terrified!",
TERM_WHITE, "You feel bolder now.");
@@ -621,9 +618,9 @@ bool_ set_afraid(int v)
/*
* Mechanics for setting the "paralyzed" field.
*/
-static bool_ set_paralyzed_aux(int v)
+static bool set_paralyzed_aux(int v)
{
- bool_ notice;
+ bool notice;
/* Normal processing */
notice = set_simple_field(
@@ -647,7 +644,7 @@ static bool_ set_paralyzed_aux(int v)
/*
* Set "p_ptr->paralyzed", notice observable changes
*/
-bool_ set_paralyzed(int v)
+bool set_paralyzed(int v)
{
/* Paralysis effects do not accumulate -- this is to
prevent the uninteresting insta-death effect, but
@@ -655,7 +652,7 @@ bool_ set_paralyzed(int v)
faster than the player. */
if (p_ptr->paralyzed > 0) {
- return FALSE;
+ return false;
}
/* Normal processing */
@@ -676,9 +673,9 @@ void dec_paralyzed()
*
* Note that we must redraw the map when hallucination changes.
*/
-bool_ set_image(int v)
+bool set_image(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->image, v,
TERM_WHITE, "Oh, wow! Everything looks so cosmic now!",
TERM_WHITE, "You can see clearly again.");
@@ -705,9 +702,9 @@ bool_ set_image(int v)
/*
* Set "p_ptr->lightspeed", notice observable changes
*/
-bool_ set_light_speed(int v)
+bool set_light_speed(int v)
{
- bool_ notice =
+ bool notice =
set_simple_field(
&p_ptr->lightspeed, v,
TERM_WHITE, "You feel as if time has stopped!",
@@ -723,9 +720,9 @@ bool_ set_light_speed(int v)
return notice;
}
-bool_ set_fast(int v, int p)
+bool set_fast(int v, int p)
{
- bool_ notice = FALSE;
+ bool notice = false;
/* Hack -- Force good values */
v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
@@ -736,7 +733,7 @@ bool_ set_fast(int v, int p)
if (!p_ptr->fast)
{
msg_print("You feel yourself moving faster!");
- notice = TRUE;
+ notice = true;
}
}
@@ -747,7 +744,7 @@ bool_ set_fast(int v, int p)
{
msg_print("You feel yourself slow down.");
p = 0;
- notice = TRUE;
+ notice = true;
}
}
@@ -756,7 +753,7 @@ bool_ set_fast(int v, int p)
p_ptr->speed_factor = p;
/* Nothing to notice */
- if (!notice) return (FALSE);
+ if (!notice) return false;
/* Disturb */
disturb_on_state();
@@ -768,16 +765,16 @@ bool_ set_fast(int v, int p)
handle_stuff();
/* Result */
- return (TRUE);
+ return true;
}
/*
* Set "p_ptr->slow", notice observable changes
*/
-bool_ set_slow(int v)
+bool set_slow(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->slow, v,
TERM_WHITE, "You feel yourself moving slower!",
TERM_WHITE, "You feel yourself speed up.");
@@ -796,9 +793,9 @@ bool_ set_slow(int v)
/*
* Set "p_ptr->shield", notice observable changes
*/
-bool_ set_shield(int v, int p, s16b o, s16b d1, s16b d2)
+bool set_shield(int v, int p, s16b o, s16b d1, s16b d2)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->shield, v,
TERM_WHITE, "A mystic shield forms around your body!",
TERM_WHITE, "Your mystic shield crumbles away.");
@@ -825,9 +822,9 @@ bool_ set_shield(int v, int p, s16b o, s16b d1, s16b d2)
/*
* Set "p_ptr->blessed", notice observable changes
*/
-bool_ set_blessed(int v)
+bool set_blessed(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->blessed, v,
TERM_WHITE, "You feel righteous!",
TERM_WHITE, "The prayer has expired.");
@@ -846,9 +843,9 @@ bool_ set_blessed(int v)
/*
* Set "p_ptr->hero", notice observable changes
*/
-bool_ set_hero(int v)
+bool set_hero(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->hero, v,
TERM_WHITE, "You feel like a hero!",
TERM_WHITE, "The heroism wears off.");
@@ -869,9 +866,9 @@ bool_ set_hero(int v)
/*
* Set "p_ptr->holy", notice observable changes
*/
-bool_ set_holy(int v)
+bool set_holy(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->holy, v,
TERM_WHITE, "You feel a holy aura around you!",
TERM_WHITE, "The holy aura vanishes.");
@@ -889,9 +886,9 @@ bool_ set_holy(int v)
/*
* Set "p_ptr->shero", notice observable changes
*/
-bool_ set_shero(int v)
+bool set_shero(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->shero, v,
TERM_WHITE, "You feel like a killing machine!",
TERM_WHITE, "You feel less berserk.");
@@ -919,9 +916,9 @@ bool_ set_shero(int v)
/*
* Set "p_ptr->protevil", notice observable changes
*/
-bool_ set_protevil(int v)
+bool set_protevil(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->protevil, v,
TERM_WHITE, "You feel safe from evil!",
TERM_WHITE, "You no longer feel safe from evil.");
@@ -939,9 +936,9 @@ bool_ set_protevil(int v)
/*
* Set "p_ptr->set_shadow", notice observable changes
*/
-bool_ set_shadow(int v)
+bool set_shadow(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->tim_wraith, v,
TERM_WHITE, "You leave the physical world and turn into a wraith-being!",
TERM_WHITE, "You feel opaque.");
@@ -971,9 +968,9 @@ bool_ set_shadow(int v)
/*
* Set "p_ptr->invuln", notice observable changes
*/
-bool_ set_invuln(int v)
+bool set_invuln(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->invuln, v,
TERM_L_BLUE, "Invulnerability!",
TERM_L_RED, "The invulnerability wears off.");
@@ -1002,9 +999,9 @@ bool_ set_invuln(int v)
/*
* Set "p_ptr->tim_esp", notice observable changes
*/
-bool_ set_tim_esp(int v)
+bool set_tim_esp(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->tim_esp, v,
TERM_WHITE, "You feel your consciousness expand!",
TERM_WHITE, "Your consciousness contracts again.");
@@ -1025,9 +1022,9 @@ bool_ set_tim_esp(int v)
/*
* Set "p_ptr->tim_thunder", notice observable changes
*/
-bool_ set_tim_thunder(int v, int p1, int p2)
+bool set_tim_thunder(int v, int p1, int p2)
{
- bool_ notice = FALSE;
+ bool notice = false;
/* Hack -- Force good values */
v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
@@ -1038,7 +1035,7 @@ bool_ set_tim_thunder(int v, int p1, int p2)
if (!p_ptr->tim_thunder)
{
msg_print("The air around you charges with lightning!");
- notice = TRUE;
+ notice = true;
}
}
@@ -1048,7 +1045,7 @@ bool_ set_tim_thunder(int v, int p1, int p2)
if (p_ptr->tim_thunder)
{
msg_print("The air around you discharges.");
- notice = TRUE;
+ notice = true;
p1 = p2 = 0;
}
}
@@ -1059,7 +1056,7 @@ bool_ set_tim_thunder(int v, int p1, int p2)
p_ptr->tim_thunder_p2 = p2;
/* Nothing to notice */
- if (!notice) return (FALSE);
+ if (!notice) return false;
/* Disturb */
disturb_on_state();
@@ -1074,15 +1071,15 @@ bool_ set_tim_thunder(int v, int p1, int p2)
handle_stuff();
/* Result */
- return (TRUE);
+ return true;
}
/*
* Set "p_ptr->tim_invis", notice observable changes
*/
-bool_ set_tim_invis(int v)
+bool set_tim_invis(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->tim_invis, v,
TERM_WHITE, "Your eyes feel very sensitive!",
TERM_WHITE, "Your eyes feel less sensitive.");
@@ -1104,9 +1101,9 @@ bool_ set_tim_invis(int v)
/*
* Set "p_ptr->tim_infra", notice observable changes
*/
-bool_ set_tim_infra(int v)
+bool set_tim_infra(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->tim_infra, v,
TERM_WHITE, "Your eyes begin to tingle!",
TERM_WHITE, "Your eyes stop tingling.");
@@ -1128,9 +1125,9 @@ bool_ set_tim_infra(int v)
/*
* Set "p_ptr->oppose_acid", notice observable changes
*/
-bool_ set_oppose_acid(int v)
+bool set_oppose_acid(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->oppose_acid, v,
TERM_WHITE, "You feel resistant to acid!",
TERM_WHITE, "You feel less resistant to acid.");
@@ -1149,9 +1146,9 @@ bool_ set_oppose_acid(int v)
/*
* Set "p_ptr->oppose_elec", notice observable changes
*/
-bool_ set_oppose_elec(int v)
+bool set_oppose_elec(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->oppose_elec, v,
TERM_WHITE, "You feel resistant to electricity!",
TERM_WHITE, "You feel less resistant to electricity.");
@@ -1170,9 +1167,9 @@ bool_ set_oppose_elec(int v)
/*
* Set "p_ptr->oppose_fire", notice observable changes
*/
-bool_ set_oppose_fire(int v)
+bool set_oppose_fire(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->oppose_fire, v,
TERM_WHITE, "You feel resistant to fire!",
TERM_WHITE, "You feel less resistant to fire.");
@@ -1191,9 +1188,9 @@ bool_ set_oppose_fire(int v)
/*
* Set "p_ptr->oppose_cold", notice observable changes
*/
-bool_ set_oppose_cold(int v)
+bool set_oppose_cold(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->oppose_cold, v,
TERM_WHITE, "You feel resistant to cold!",
TERM_WHITE, "You feel less resistant to cold.");
@@ -1212,9 +1209,9 @@ bool_ set_oppose_cold(int v)
/*
* Set "p_ptr->oppose_pois", notice observable changes
*/
-bool_ set_oppose_pois(int v)
+bool set_oppose_pois(int v)
{
- bool_ notice = set_simple_field(
+ bool notice = set_simple_field(
&p_ptr->oppose_pois, v,
TERM_WHITE, "You feel resistant to poison!",
TERM_WHITE, "You feel less resistant to poison.");
@@ -1233,9 +1230,9 @@ bool_ set_oppose_pois(int v)
/*
* Set "p_ptr->tim_regen", notice observable changes
*/
-bool_ set_tim_regen(int v, int p)
+bool set_tim_regen(int v, int p)
{
- bool_ notice = FALSE;
+ bool notice = false;
/* Hack -- Force good values */
v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
@@ -1246,7 +1243,7 @@ bool_ set_tim_regen(int v, int p)
if (!p_ptr->tim_regen)
{
msg_print("Your body regenerates much more quickly!");
- notice = TRUE;
+ notice = true;
}
}
@@ -1257,7 +1254,7 @@ bool_ set_tim_regen(int v, int p)
{
p = 0;
msg_print("Your body regenerates much more slowly.");
- notice = TRUE;
+ notice = true;
}
}
@@ -1266,7 +1263,7 @@ bool_ set_tim_regen(int v, int p)
p_ptr->tim_regen_pow = p;
/* Nothing to notice */
- if (!notice) return (FALSE);
+ if (!notice) return false;
/* Disturb */
disturb_on_state();
@@ -1275,7 +1272,7 @@ bool_ set_tim_regen(int v, int p)
handle_stuff();
/* Result */
- return (TRUE);
+ return true;
}
@@ -1284,10 +1281,10 @@ bool_ set_tim_regen(int v, int p)
*
* Note the special code to only notice "range" changes.
*/
-bool_ set_stun(int v)
+bool set_stun(int v)
{
int old_aux, new_aux;
- bool_ notice = FALSE;
+ bool notice = false;
/* Hack -- Force good values */
@@ -1397,7 +1394,7 @@ bool_ set_stun(int v)
}
/* Notice */
- notice = TRUE;
+ notice = true;
}
/* Decrease cut */
@@ -1414,14 +1411,14 @@ bool_ set_stun(int v)
}
/* Notice */
- notice = TRUE;
+ notice = true;
}
/* Use the value */
p_ptr->stun = v;
/* No change */
- if (!notice) return (FALSE);
+ if (!notice) return false;
/* Disturb */
disturb_on_state();
@@ -1436,7 +1433,7 @@ bool_ set_stun(int v)
handle_stuff();
/* Result */
- return (TRUE);
+ return true;
}
@@ -1445,11 +1442,11 @@ bool_ set_stun(int v)
*
* Note the special code to only notice "range" changes.
*/
-bool_ set_cut(int v)
+bool set_cut(int v)
{
int old_aux, new_aux;
- bool_ notice = FALSE;
+ bool notice = false;
/* Hack -- Force good values */
v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
@@ -1595,7 +1592,7 @@ bool_ set_cut(int v)
}
/* Notice */
- notice = TRUE;
+ notice = true;
if (randint(1000) < v || randint(16) == 1)
{
@@ -1622,14 +1619,14 @@ bool_ set_cut(int v)
}
/* Notice */
- notice = TRUE;
+ notice = true;
}
/* Use the value */
p_ptr->cut = v;
/* No change */
- if (!notice) return (FALSE);
+ if (!notice) return false;
/* Disturb */
disturb_on_state();
@@ -1644,7 +1641,7 @@ bool_ set_cut(int v)
handle_stuff();
/* Result */
- return (TRUE);
+ return true;
}
void drop_from_wild()
@@ -1684,11 +1681,11 @@ void drop_from_wild()
* game turns, or 500/(100/5) = 25 player turns (if nothing else is
* affecting the player speed).
*/
-bool_ set_food(int v)
+bool set_food(int v)
{
int old_aux, new_aux;
- bool_ notice = FALSE;
+ bool notice = false;
/* Hack -- Force good values */
v = (v > 20000) ? 20000 : (v < 0) ? 0 : v;
@@ -1798,7 +1795,7 @@ bool_ set_food(int v)
}
/* Change */
- notice = TRUE;
+ notice = true;
}
/* Food decrease */
@@ -1836,14 +1833,14 @@ bool_ set_food(int v)
}
/* Change */
- notice = TRUE;
+ notice = true;
}
/* Use the value */
p_ptr->food = v;
/* Nothing to notice */
- if (!notice) return (FALSE);
+ if (!notice) return false;
/* Disturb */
disturb_on_state();
@@ -1858,7 +1855,7 @@ bool_ set_food(int v)
handle_stuff();
/* Result */
- return (TRUE);
+ return true;
}
@@ -1868,7 +1865,7 @@ bool_ set_food(int v)
void check_experience()
{
int gained = 0;
- bool_ level_corruption = FALSE;
+ bool level_corruption = false;
/* Hack -- lower limit */
@@ -1932,7 +1929,7 @@ void check_experience()
if ((race_flags_p(PR_CORRUPT)) &&
(randint(3) == 1))
{
- level_corruption = TRUE;
+ level_corruption = true;
}
}
@@ -1975,7 +1972,7 @@ void check_experience()
{
msg_print("You feel different...");
corrupt_corrupted();
- level_corruption = FALSE;
+ level_corruption = false;
}
}
@@ -2072,7 +2069,7 @@ void lose_exp(s32b amount)
*/
int get_coin_type(std::shared_ptr<monster_race const> r_ptr)
{
- cptr name = r_ptr->name;
+ const char *name = r_ptr->name;
/* Analyze "coin" monsters */
if (r_ptr->d_char == '$')
@@ -2186,29 +2183,29 @@ void place_corpse(monster_type *m_ptr)
* Check if monster race is in a given list. The list
* must be NULL-terminated.
*/
-static bool_ monster_race_in_list_p(monster_type *m_ptr, cptr races[])
+static bool monster_race_in_list_p(monster_type *m_ptr, const char *races[])
{
int i=0;
for (i=0; races[i] != NULL; i++)
{
if (m_ptr->r_idx == test_monster_name(races[i])) {
- return TRUE;
+ return true;
}
}
/* Not found */
- return FALSE;
+ return false;
}
/*
* Handle the "death" of a monster (Gods)
*/
-static void monster_death_gods(int m_idx, monster_type *m_ptr)
+static void monster_death_gods(monster_type *m_ptr)
{
if (p_ptr->pgod == GOD_AULE)
{
/* TODO: This should really be a racial flag
which can be added to the r_info file. */
- cptr DWARVES[] = {
+ const char *DWARVES[] = {
"Petty-dwarf",
"Petty-dwarf mage",
"Dark dwarven warrior",
@@ -2218,7 +2215,7 @@ static void monster_death_gods(int m_idx, monster_type *m_ptr)
"Dwarven warrior",
NULL,
};
- cptr UNIQUE_DWARVES[] = {
+ const char *UNIQUE_DWARVES[] = {
"Nar, the Dwarf",
"Naugladur, Lord of Nogrod",
"Telchar the Smith",
@@ -2245,7 +2242,7 @@ static void monster_death_gods(int m_idx, monster_type *m_ptr)
if (p_ptr->pgod == GOD_ULMO)
{
/* He doesn't like it if you kill these monsters */
- cptr MINOR_RACES[] = {
+ const char *MINOR_RACES[] = {
"Swordfish",
"Barracuda",
"Globefish",
@@ -2276,7 +2273,7 @@ static void monster_death_gods(int m_idx, monster_type *m_ptr)
NULL,
};
/* These monsters earn higher penalties */
- cptr MAJOR_RACES[] = {
+ const char *MAJOR_RACES[] = {
"Seahorse",
"Aquatic elven warrior",
"Aquatic elven mage",
@@ -2298,7 +2295,7 @@ static void monster_death_gods(int m_idx, monster_type *m_ptr)
if (p_ptr->pgod == GOD_MANDOS)
{
- cptr MINOR_BONUS_RACES[] = {
+ const char *MINOR_BONUS_RACES[] = {
"Vampire",
"Master vampire",
"Oriental vampire",
@@ -2312,12 +2309,12 @@ static void monster_death_gods(int m_idx, monster_type *m_ptr)
"Elder vampire",
NULL,
};
- cptr MAJOR_BONUS_RACES[] = {
+ const char *MAJOR_BONUS_RACES[] = {
"Vampire elf",
"Thuringwethil, the Vampire Messenger",
NULL,
};
- cptr MINOR_PENALTY[] = {
+ const char *MINOR_PENALTY[] = {
"Dark elf",
"Dark elven druid",
"Eol, the Dark Elf",
@@ -2330,7 +2327,7 @@ static void monster_death_gods(int m_idx, monster_type *m_ptr)
"Dark elven sorcerer",
NULL,
};
- cptr MEDIUM_PENALTY[] = {
+ const char *MEDIUM_PENALTY[] = {
"Glorfindel of Rivendell",
"Finrod Felagund",
"Thranduil, King of the Wood Elves",
@@ -2340,7 +2337,7 @@ static void monster_death_gods(int m_idx, monster_type *m_ptr)
"Elven archer",
NULL,
};
- cptr MAJOR_PENALTY[] = {
+ const char *MAJOR_PENALTY[] = {
"Child spirit",
"Young spirit",
"Mature spirit",
@@ -2409,7 +2406,7 @@ void monster_death(int m_idx)
auto const r_ptr = m_ptr->race();
- bool_ create_stairs = FALSE;
+ bool create_stairs = false;
int force_coin = get_coin_type(r_ptr);
object_type forge;
@@ -2426,7 +2423,7 @@ void monster_death(int m_idx)
}
/* Per-god processing */
- monster_death_gods(m_idx, m_ptr);
+ monster_death_gods(m_ptr);
/* If companion dies, take note */
if (m_ptr->status == MSTATUS_COMPANION) p_ptr->companion_killed++;
@@ -2525,7 +2522,6 @@ void monster_death(int m_idx)
TR_CURSED |
TR_HEAVY_CURSE;
- q_ptr->ident |= IDENT_CURSED;
if (randint(2) == 1)
{
q_ptr->art_flags |= TR_DRAIN_EXP;
@@ -2566,7 +2562,7 @@ void monster_death(int m_idx)
{
if (is_friend(m_ptr) > 0)
{
- if (summon_specific_friendly(wy, wx, 100, SUMMON_DAWN, FALSE))
+ if (summon_specific_friendly(wy, wx, 100, SUMMON_DAWN, false))
{
if (player_can_see_bold(wy, wx))
msg_print ("A new warrior steps forth!");
@@ -2630,7 +2626,7 @@ void monster_death(int m_idx)
q_ptr->name1 = ART_GROND;
/* Mega-Hack -- Actually create "Grond" */
- apply_magic(q_ptr, -1, TRUE, TRUE, TRUE);
+ apply_magic(q_ptr, -1, true, true, true);
/* Drop it in the dungeon */
drop_near(q_ptr, -1, y, x);
@@ -2645,7 +2641,7 @@ void monster_death(int m_idx)
q_ptr->name1 = ART_MORGOTH;
/* Mega-Hack -- Actually create "Morgoth" */
- apply_magic(q_ptr, -1, TRUE, TRUE, TRUE);
+ apply_magic(q_ptr, -1, true, true, true);
q_ptr->found = OBJ_FOUND_MONSTER;
q_ptr->found_aux1 = m_ptr->r_idx;
@@ -2667,7 +2663,7 @@ void monster_death(int m_idx)
object_prep(q_ptr, lookup_kind(TV_RING, SV_RING_INVIS));
q_ptr->number = 1;
- apply_magic(q_ptr, -1, TRUE, TRUE, FALSE);
+ apply_magic(q_ptr, -1, true, true, false);
q_ptr->found = OBJ_FOUND_MONSTER;
q_ptr->found_aux1 = m_ptr->r_idx;
@@ -2689,10 +2685,10 @@ void monster_death(int m_idx)
object_prep(q_ptr, lookup_kind(TV_RING, SV_RING_SPECIAL));
q_ptr->number = 1;
- apply_magic(q_ptr, -1, TRUE, TRUE, FALSE);
+ apply_magic(q_ptr, -1, true, true, false);
/* Create a random artifact */
- create_artifact(q_ptr, TRUE, FALSE);
+ create_artifact(q_ptr, true, false);
/* Save the inscription */
q_ptr->artifact_name = fmt::format("of {}", r_ptr->name);
@@ -2743,7 +2739,10 @@ void monster_death(int m_idx)
q_ptr->weight = a_ptr->weight;
/* Hack -- acquire "cursed" flag */
- if (a_ptr->flags & TR_CURSED) q_ptr->ident |= (IDENT_CURSED);
+ if (a_ptr->flags & TR_CURSED)
+ {
+ q_ptr->art_flags |= TR_CURSED;
+ }
random_artifact_resistance(q_ptr);
@@ -2776,7 +2775,7 @@ void monster_death(int m_idx)
}
while (!(in_bounds(yy, xx) && cave_floor_bold(yy, xx)) && --attempts);
- place_monster_aux(yy, xx, test_monster_name("Great Wyrm of Power"), FALSE, FALSE, m_ptr->status);
+ place_monster_aux(yy, xx, test_monster_name("Great Wyrm of Power"), false, false, m_ptr->status);
}
/* Let monsters explode! */
@@ -2947,7 +2946,7 @@ void monster_death(int m_idx)
/*
* Decreases monsters hit points, handling monster death.
*
- * We return TRUE if the monster has been killed (and deleted).
+ * We return true if the monster has been killed (and deleted).
*
* We announce monster death (using an optional "death message"
* if given, and a otherwise a generic killed/destroyed message).
@@ -2971,17 +2970,23 @@ void monster_death(int m_idx)
* monster worth more than subsequent monsters. This would also need
* to induce changes in the monster recall code.
*/
-bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note)
+bool mon_take_hit(int m_idx, int dam, bool *fear, const char *note)
{
monster_type *m_ptr = &m_list[m_idx];
auto const r_idx = m_ptr->r_idx;
auto const r_ptr = m_ptr->race();
/* Redraw (later) if needed */
- if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME);
+ if (health_who == m_idx)
+ {
+ p_ptr->redraw |= (PR_FRAME);
+ }
- /* Some mosnters are immune to death */
- if (r_ptr->flags & RF_NO_DEATH) return FALSE;
+ /* Some monsters are immune to death */
+ if (r_ptr->flags & RF_NO_DEATH)
+ {
+ return false;
+ }
/* Wake it up */
m_ptr->csleep = 0;
@@ -2999,7 +3004,7 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note)
{
ai_deincarnate(m_idx);
- return FALSE;
+ return false;
}
/* Extract monster name */
@@ -3090,7 +3095,7 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note)
auto const flags = object_flags(o_ptr);
/* Can the weapon gain levels ? */
- if ((o_ptr->k_idx) && (flags & TR_LEVELS))
+ if (o_ptr->k_ptr && (flags & TR_LEVELS))
{
/* Give some experience for the kill */
const int new_exp = ((long)r_ptr->mexp * m_ptr->level) / (div * 2);
@@ -3227,17 +3232,20 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note)
delete_monster_idx(m_idx);
/* Not afraid */
- (*fear) = FALSE;
+ if (fear != nullptr)
+ {
+ (*fear) = false;
+ }
/* Monster is dead */
- return (TRUE);
+ return true;
}
/* Apply fear */
mon_handle_fear(m_ptr, dam, fear);
/* Not dead yet */
- return (FALSE);
+ return false;
}
@@ -3280,11 +3288,11 @@ static void panel_bounds()
/*
* Handle a request to change the current panel
*
- * Return TRUE if the panel was changed.
+ * Return true if the panel was changed.
*
* Also used in do_cmd_locate()
*/
-bool_ change_panel(int dy, int dx)
+bool change_panel(int dy, int dx)
{
int y, x;
int wid, hgt;
@@ -3322,11 +3330,11 @@ bool_ change_panel(int dy, int dx)
handle_stuff();
/* Success */
- return (TRUE);
+ return true;
}
/* No changes */
- return (FALSE);
+ return false;
}
@@ -3336,7 +3344,7 @@ bool_ change_panel(int dy, int dx)
*
* "Update" forces a "full update" to take place.
*
- * The map is reprinted if necessary, and "TRUE" is returned.
+ * The map is reprinted if necessary, and "true" is returned.
*/
void verify_panel()
{
@@ -3476,7 +3484,10 @@ void verify_panel()
void resize_map()
{
/* Only if the dungeon exists */
- if (!character_dungeon) return;
+ if (!character_dungeon)
+ {
+ return;
+ }
/* Mega-Hack -- No panel yet, assume illegal panel */
panel_row_min = cur_hgt;
@@ -3525,13 +3536,16 @@ void resize_map()
void resize_window()
{
/* Only if the dungeon exists */
- if (!character_dungeon) return;
+ if (!character_dungeon)
+ {
+ return;
+ }
/* Hack -- Activate the Angband window for the redraw */
- Term_activate(&term_screen[0]);
+ Term_activate(angband_term[0]);
/* Hack -- react to changes */
- Term_xtra(TERM_XTRA_REACT, 0);
+ Term_xtra_react();
/* Window stuff */
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
@@ -3554,17 +3568,17 @@ void resize_window()
/*
* Monster health description
*/
-static cptr look_mon_desc(int m_idx)
+static const char *look_mon_desc(int m_idx)
{
- bool_ living = TRUE;
+ bool living = true;
/* Determine if the monster is "living" (vs "undead") */
monster_type *m_ptr = &m_list[m_idx];
auto const r_ptr = m_ptr->race();
- if (r_ptr->flags & RF_UNDEAD) living = FALSE;
- if (r_ptr->flags & RF_DEMON) living = FALSE;
- if (r_ptr->flags & RF_NONLIVING) living = FALSE;
- if (strchr("Egv", r_ptr->d_char)) living = FALSE;
+ if (r_ptr->flags & RF_UNDEAD) living = false;
+ if (r_ptr->flags & RF_DEMON) living = false;
+ if (r_ptr->flags & RF_NONLIVING) living = false;
+ if (strchr("Egv", r_ptr->d_char)) living = false;
/* Healthy monsters */
@@ -3624,28 +3638,28 @@ static bool target_able(int m_idx)
monster_type *m_ptr = &m_list[m_idx];
/* Monster must be alive */
- if (!m_ptr->r_idx) return (FALSE);
+ if (!m_ptr->r_idx) return false;
/* Monster must be visible */
- if (!m_ptr->ml) return (FALSE);
+ if (!m_ptr->ml) return false;
/* Monster must be projectable */
- if (!projectable(p_ptr->py, p_ptr->px, m_ptr->fy, m_ptr->fx)) return (FALSE);
+ if (!projectable(p_ptr->py, p_ptr->px, m_ptr->fy, m_ptr->fx)) return false;
/* Hack -- no targeting hallucinations */
- if (p_ptr->image) return (FALSE);
+ if (p_ptr->image) return false;
/* Dont target pets */
- if (is_friend(m_ptr) > 0) return (FALSE);
+ if (is_friend(m_ptr) > 0) return false;
/* Honor flag */
- if (r_info[m_ptr->r_idx].flags & RF_NO_TARGET) return (FALSE);
+ if (r_info[m_ptr->r_idx].flags & RF_NO_TARGET) return false;
/* XXX XXX XXX Hack -- Never target trappers */
- /* if (CLEAR_ATTR && (CLEAR_CHAR)) return (FALSE); */
+ /* if (CLEAR_ATTR && (CLEAR_CHAR)) return false; */
/* Assume okay */
- return (TRUE);
+ return true;
}
@@ -3654,12 +3668,12 @@ static bool target_able(int m_idx)
/*
* Update (if necessary) and verify (if possible) the target.
*
- * We return TRUE if the target is "okay" and FALSE otherwise.
+ * We return true if the target is "okay" and false otherwise.
*/
-bool_ target_okay()
+bool target_okay()
{
/* Accept stationary targets */
- if (target_who < 0) return (TRUE);
+ if (target_who < 0) return true;
/* Check moving targets */
if (target_who > 0)
@@ -3674,12 +3688,12 @@ bool_ target_okay()
target_col = m_ptr->fx;
/* Good target */
- return (TRUE);
+ return true;
}
}
/* Assume no target */
- return (FALSE);
+ return false;
}
@@ -3735,17 +3749,17 @@ static s16b target_pick(point p, int dy, int dx, std::vector<point> const &point
/*
* Hack -- determine if a given location is "interesting"
*/
-static bool_ target_set_accept(int y, int x)
+static bool target_set_accept(int y, int x)
{
auto const &r_info = game->edit_data.r_info;
auto const &f_info = game->edit_data.f_info;
/* Player grid is always interesting */
- if ((y == p_ptr->py) && (x == p_ptr->px)) return (TRUE);
+ if ((y == p_ptr->py) && (x == p_ptr->px)) return true;
/* Handle hallucination */
- if (p_ptr->image) return (FALSE);
+ if (p_ptr->image) return false;
/* Examine the grid */
@@ -3757,7 +3771,7 @@ static bool_ target_set_accept(int y, int x)
monster_type *m_ptr = &m_list[c_ptr->m_idx];
/* Visible monsters */
- if (m_ptr->ml) return (TRUE);
+ if (m_ptr->ml) return true;
}
/* Scan all objects in the grid */
@@ -3769,7 +3783,7 @@ static bool_ target_set_accept(int y, int x)
/* Memorized object */
if (o_ptr->marked)
{
- return (TRUE);
+ return true;
}
}
@@ -3777,17 +3791,17 @@ static bool_ target_set_accept(int y, int x)
if (c_ptr->info & (CAVE_MARK))
{
/* Hack -- Doors are boring */
- if (c_ptr->feat == FEAT_OPEN) return (FALSE);
- if (c_ptr->feat == FEAT_BROKEN) return (FALSE);
+ if (c_ptr->feat == FEAT_OPEN) return false;
+ if (c_ptr->feat == FEAT_BROKEN) return false;
if ((c_ptr->feat >= FEAT_DOOR_HEAD) &&
- (c_ptr->feat <= FEAT_DOOR_TAIL)) return (FALSE);
+ (c_ptr->feat <= FEAT_DOOR_TAIL)) return false;
/* Accept 'naturally' interesting features */
- if (f_info[c_ptr->feat].flags & FF_NOTICE) return (TRUE);
+ if (f_info[c_ptr->feat].flags & FF_NOTICE) return true;
}
/* Nope */
- return (FALSE);
+ return false;
}
@@ -3835,17 +3849,17 @@ static std::vector<point> target_set_prepare(int mode)
}
-bool_ target_object(int y, int x, int mode, cptr info, bool_ *boring,
- object_type *o_ptr, char *out_val, cptr *s1, cptr *s2, cptr *s3,
+bool target_object(int y, int x, int mode, const char *info, bool *boring,
+ object_type *o_ptr, char *out_val, const char **s1, const char **s2, const char **s3,
int *query)
{
char o_name[80];
/* Not boring */
- *boring = FALSE;
+ *boring = false;
/* Obtain an object description */
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Describe the object */
sprintf(out_val, "%s%s%s%s [%s]", *s1, *s2, *s3, o_name, info);
@@ -3854,10 +3868,10 @@ bool_ target_object(int y, int x, int mode, cptr info, bool_ *boring,
*query = inkey();
/* Always stop at "normal" keys */
- if ((*query != '\r') && (*query != '\n') && (*query != ' ')) return (TRUE);
+ if ((*query != '\r') && (*query != '\n') && (*query != ' ')) return true;
/* Sometimes stop at "space" key */
- if ((*query == ' ') && !(mode & (TARGET_LOOK))) return (TRUE);
+ if ((*query == ' ') && !(mode & (TARGET_LOOK))) return true;
/* Change the intro */
*s1 = "It is ";
@@ -3867,7 +3881,7 @@ bool_ target_object(int y, int x, int mode, cptr info, bool_ *boring,
/* Preposition */
*s2 = "on ";
- return (FALSE);
+ return false;
}
/*
@@ -3891,7 +3905,7 @@ bool_ target_object(int y, int x, int mode, cptr info, bool_ *boring,
*
* This function must handle blindness/hallucination.
*/
-static int target_set_aux(int y, int x, int mode, cptr info)
+static int target_set_aux(int y, int x, int mode, const char *info_)
{
auto const &d_info = game->edit_data.d_info;
auto const &st_info = game->edit_data.st_info;
@@ -3899,11 +3913,15 @@ static int target_set_aux(int y, int x, int mode, cptr info)
auto const &f_info = game->edit_data.f_info;
auto const &k_info = game->edit_data.k_info;
+ std::string info(info_);
+
cave_type *c_ptr = &cave[y][x];
- cptr s1, s2, s3;
+ const char *s1;
+ const char *s2;
+ const char *s3;
- bool_ boring;
+ bool boring;
int feat;
@@ -3913,13 +3931,13 @@ static int target_set_aux(int y, int x, int mode, cptr info)
/* Repeat forever */
- while (1)
+ while (true)
{
/* Paranoia */
query = ' ';
/* Assume boring */
- boring = TRUE;
+ boring = true;
/* Default */
s1 = "You see ";
@@ -3940,10 +3958,10 @@ static int target_set_aux(int y, int x, int mode, cptr info)
/* Hack -- hallucination */
if (p_ptr->image)
{
- cptr name = "something strange";
+ const char *name = "something strange";
/* Display a message */
- sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, info);
+ sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, info.c_str());
prt(out_val, 0, 0);
move_cursor_relative(y, x);
query = inkey();
@@ -3970,7 +3988,7 @@ static int target_set_aux(int y, int x, int mode, cptr info)
if (o_ptr->marked)
{
- if (target_object(y, x, mode, info, &boring, o_ptr, out_val, &s1, &s2, &s3, &query))
+ if (target_object(y, x, mode, info.c_str(), &boring, o_ptr, out_val, &s1, &s2, &s3, &query))
{
break;
}
@@ -3981,12 +3999,12 @@ static int target_set_aux(int y, int x, int mode, cptr info)
/* Visible */
if (m_ptr->ml)
{
- bool_ recall = FALSE;
+ bool recall = false;
char m_name[80];
/* Not boring */
- boring = FALSE;
+ boring = false;
/* Get the monster name ("a kobold") */
monster_desc(m_name, m_ptr, 0x08);
@@ -4001,33 +4019,31 @@ static int target_set_aux(int y, int x, int mode, cptr info)
handle_stuff();
/* Interact */
- while (1)
+ while (true)
{
/* Recall */
if (recall)
{
/* Save */
- character_icky = TRUE;
- Term_save();
+ screen_save_no_flush();
/* Recall on screen */
screen_roff(m_ptr->r_idx, m_ptr->ego);
/* Hack -- Complete the prompt (again) */
- Term_addstr( -1, TERM_WHITE, format(" [r,%s]", info));
+ Term_addstr( -1, TERM_WHITE, fmt::format(" [r,{}]", info).c_str());
/* Command */
query = inkey();
/* Restore */
- Term_load();
- character_icky = FALSE;
+ screen_load_no_flush();
}
/* Normal */
else
{
- cptr mstat;
+ const char *mstat;
switch (m_ptr->status)
{
@@ -4058,7 +4074,8 @@ static int target_set_aux(int y, int x, int mode, cptr info)
(m_ptr->csleep) ? ", asleep" : "",
(m_ptr->mflag & MFLAG_QUEST) ? ", quest" : "",
(m_ptr->smart & SM_CLONED ? " (clone)" : ""),
- (mstat), info);
+ (mstat),
+ info.c_str());
prt(out_val, 0, 0);
@@ -4102,10 +4119,10 @@ static int target_set_aux(int y, int x, int mode, cptr info)
/* Obtain an object description */
char o_name[80];
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, true, 3);
/* Describe the object */
- sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, o_name, info);
+ sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, o_name, info.c_str());
prt(out_val, 0, 0);
move_cursor_relative(y, x);
query = inkey();
@@ -4148,7 +4165,7 @@ static int target_set_aux(int y, int x, int mode, cptr info)
object_type *o_ptr = &o_list[this_o_idx];
/* Describe it */
- if (o_ptr->marked && target_object(y, x, mode, info, &boring, o_ptr, out_val, &s1, &s2, &s3, &query))
+ if (o_ptr->marked && target_object(y, x, mode, info.c_str(), &boring, o_ptr, out_val, &s1, &s2, &s3, &query))
{
break;
}
@@ -4199,7 +4216,7 @@ static int target_set_aux(int y, int x, int mode, cptr info)
/* Pick a prefix */
if (*s2 &&
(((feat >= FEAT_MINOR_GLYPH) &&
- (feat <= FEAT_PATTERN_XTRA2)) ||
+ (feat < FEAT_SHOP)) ||
(feat == FEAT_DIRT) ||
(feat == FEAT_GRASS) ||
(feat == FEAT_FLOWER))) s2 = "on ";
@@ -4230,7 +4247,7 @@ static int target_set_aux(int y, int x, int mode, cptr info)
name = fmt::format("{}({})", wf.name, wf.text);
}
- if ((feat == FEAT_FOUNTAIN) && (c_ptr->info & CAVE_IDNT))
+ if (feat == FEAT_FOUNTAIN)
{
int tv, sv;
@@ -4245,18 +4262,18 @@ static int target_set_aux(int y, int x, int mode, cptr info)
sv = c_ptr->special - SV_POTION_LAST;
}
- info = k_info[lookup_kind(tv, sv)].name;
+ info = k_info.at(lookup_kind(tv, sv))->name;
}
/* Display a message */
if (!wizard)
{
- sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name.c_str(), info);
+ sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name.c_str(), info.c_str());
}
else
{
sprintf(out_val, "%s%s%s%s [%s] (%d:%d:%d)",
- s1, s2, s3, name.c_str(), info,
+ s1, s2, s3, name.c_str(), info.c_str(),
c_ptr->feat, c_ptr->mimic, c_ptr->special);
}
prt(out_val, 0, 0);
@@ -4319,15 +4336,15 @@ static int target_set_aux(int y, int x, int mode, cptr info)
* This command will cancel any old target, even if used from
* inside the "look" command.
*/
-bool_ target_set(int mode)
+bool target_set(int mode)
{
int i, d, m;
int y = p_ptr->py;
int x = p_ptr->px;
- bool_ done = FALSE;
+ bool done = false;
- bool_ flag = TRUE;
+ bool flag = true;
char query;
@@ -4396,7 +4413,7 @@ bool_ target_set(int mode)
case ESCAPE:
case 'q':
{
- done = TRUE;
+ done = true;
break;
}
@@ -4411,7 +4428,7 @@ bool_ target_set(int mode)
target_who = c_ptr->m_idx;
target_row = y;
target_col = x;
- done = TRUE;
+ done = true;
}
else
{
@@ -4468,7 +4485,7 @@ bool_ target_set(int mode)
case 'o':
{
- flag = FALSE;
+ flag = false;
break;
}
@@ -4551,7 +4568,7 @@ bool_ target_set(int mode)
case ESCAPE:
case 'q':
{
- done = TRUE;
+ done = true;
break;
}
@@ -4563,7 +4580,7 @@ bool_ target_set(int mode)
target_who = -1;
target_row = y;
target_col = x;
- done = TRUE;
+ done = true;
break;
}
@@ -4588,7 +4605,7 @@ bool_ target_set(int mode)
case 'm':
{
- flag = TRUE;
+ flag = true;
break;
}
@@ -4679,10 +4696,10 @@ bool_ target_set(int mode)
handle_stuff();
/* Failure to set target */
- if (!target_who) return (FALSE);
+ if (!target_who) return false;
/* Success */
- return (TRUE);
+ return true;
}
@@ -4698,13 +4715,13 @@ bool_ target_set(int mode)
*
* Note that confusion over-rides any (explicit?) user choice.
*/
-bool_ get_aim_dir(int *dp)
+bool get_aim_dir(int *dp)
{
int dir;
char command;
- cptr p;
+ const char *p;
if (repeat_pull(dp))
{
@@ -4713,7 +4730,7 @@ bool_ get_aim_dir(int *dp)
/* Verify */
if (!(*dp == 5 && !target_okay()))
{
- return (TRUE);
+ return true;
}
}
@@ -4783,7 +4800,7 @@ bool_ get_aim_dir(int *dp)
}
/* No direction */
- if (!dir) return (FALSE);
+ if (!dir) return false;
/* Save the direction */
command_dir = dir;
@@ -4810,7 +4827,7 @@ bool_ get_aim_dir(int *dp)
repeat_push(dir);
/* A "valid" direction was entered */
- return (TRUE);
+ return true;
}
@@ -4831,13 +4848,13 @@ bool_ get_aim_dir(int *dp)
* This function tracks and uses the "global direction", and uses
* that as the "desired direction", to which "confusion" is applied.
*/
-bool_ get_rep_dir(int *dp)
+bool get_rep_dir(int *dp)
{
int dir;
if (repeat_pull(dp))
{
- return (TRUE);
+ return true;
}
/* Initialize */
@@ -4865,7 +4882,7 @@ bool_ get_rep_dir(int *dp)
if (dir == 5) dir = 0;
/* Aborted */
- if (!dir) return (FALSE);
+ if (!dir) return false;
/* Save desired direction */
command_dir = dir;
@@ -4895,66 +4912,70 @@ bool_ get_rep_dir(int *dp)
repeat_push(dir);
/* Success */
- return (TRUE);
+ return true;
}
/*
* old -- from PsiAngband.
*/
-bool_ tgt_pt(int *x, int *y)
+bool tgt_pt(int *x, int *y)
{
- char ch = 0;
- int d, cu, cv;
- int screen_wid, screen_hgt;
- bool_ success = FALSE;
+ bool success = false;
- *x = p_ptr->px;
- *y = p_ptr->py;
+ // Make the cursor visible
+ Term_with_saved_cursor_flags([&success, &x, &y]() {
- /* Get size */
- get_screen_size(&screen_wid, &screen_hgt);
+ *x = p_ptr->px;
+ *y = p_ptr->py;
- cu = Term->scr->cu;
- cv = Term->scr->cv;
- Term->scr->cu = 0;
- Term->scr->cv = 1;
- msg_print("Select a point and press space.");
+ /* Get size */
+ int screen_wid;
+ int screen_hgt;
+ get_screen_size(&screen_wid, &screen_hgt);
- while ((ch != 27) && (ch != ' '))
- {
- move_cursor_relative(*y, *x);
- ch = inkey();
- switch (ch)
+ // Make cursor visible
+ Term_show_cursor();
+
+ // Prompt
+ msg_print("Select a point and press space.");
+
+ char ch = '\0';
+ while ((ch != 27) && (ch != ' '))
{
- case 27:
- break;
- case ' ':
- success = TRUE;
- break;
- default:
- /* Look up the direction */
- d = get_keymap_dir(ch);
+ move_cursor_relative(*y, *x);
+ ch = inkey();
+ switch (ch)
+ {
+ case 27:
+ break;
+ case ' ':
+ success = true;
+ break;
+ default:
+ /* Look up the direction */
+ int d;
+ d = get_keymap_dir(ch);
- if (!d) break;
+ if (!d) break;
- *x += ddx[d];
- *y += ddy[d];
+ *x += ddx[d];
+ *y += ddy[d];
- /* Hack -- Verify x */
- if ((*x >= cur_wid - 1) || (*x >= panel_col_min + screen_wid)) (*x)--;
- else if ((*x <= 0) || (*x <= panel_col_min)) (*x)++;
+ /* Hack -- Verify x */
+ if ((*x >= cur_wid - 1) || (*x >= panel_col_min + screen_wid)) (*x)--;
+ else if ((*x <= 0) || (*x <= panel_col_min)) (*x)++;
- /* Hack -- Verify y */
- if ((*y >= cur_hgt - 1) || (*y >= panel_row_min + screen_hgt)) (*y)--;
- else if ((*y <= 0) || (*y <= panel_row_min)) (*y)++;
+ /* Hack -- Verify y */
+ if ((*y >= cur_hgt - 1) || (*y >= panel_row_min + screen_hgt)) (*y)--;
+ else if ((*y <= 0) || (*y <= panel_row_min)) (*y)++;
- break;
+ break;
+ }
}
- }
+ });
- Term->scr->cu = cu;
- Term->scr->cv = cv;
+ // Refresh
Term_fresh();
return success;
}
@@ -4972,7 +4993,7 @@ void set_grace(s32b v)
handle_stuff();
}
-static bool_ test_object_wish(char *name, object_type *o_ptr, object_type *forge, const char *what)
+static bool test_object_wish(char *name, object_type *o_ptr, object_type *forge)
{
auto &k_info = game->edit_data.k_info;
auto const &e_info = game->edit_data.e_info;
@@ -4980,41 +5001,48 @@ static bool_ test_object_wish(char *name, object_type *o_ptr, object_type *forge
int save_aware;
char buf[200];
- /* try all objects, this *IS* a very ugly and slow method :( */
- for (std::size_t i = 0; i < k_info.size(); i++)
+ for (auto &k_entry: k_info)
{
- auto k_ptr = &k_info[i];
+ auto k_ptr = k_entry.second;
o_ptr = forge;
- if (!k_ptr->name) continue;
if (k_ptr->flags & TR_NORM_ART) continue;
if (k_ptr->flags & TR_INSTA_ART) continue;
if (k_ptr->tval == TV_GOLD) continue;
- object_prep(o_ptr, i);
+ object_prep(o_ptr, k_entry.first);
o_ptr->name1 = 0;
o_ptr->name2 = 0;
- apply_magic(o_ptr, dun_level, FALSE, FALSE, FALSE);
+ apply_magic(o_ptr, dun_level, false, false, false);
/* Hack : aware status must be restored after describing the item name */
save_aware = k_ptr->aware;
object_aware(o_ptr);
object_known(o_ptr);
- object_desc(buf, o_ptr, FALSE, 0);
+ object_desc(buf, o_ptr, false, 0);
strlower(buf);
k_ptr->aware = save_aware;
+ if (iequals(buf, name))
+ {
+ /* Don't search any more */
+ return true;
+ }
+
if (strstr(name, buf) ||
/* Hack hack hackery */
(o_ptr->tval == TV_ROD_MAIN && strstr(name, "rod of")))
{
/* try all ego */
- for (std::size_t j = 0; j < e_info.size(); j++)
+ for (std::size_t j = 1; j < e_info.size(); j++)
{
auto e_ptr = &e_info[j];
- bool_ ok = FALSE;
+ bool ok = false;
- if (j && !e_ptr->name) continue;
+ if (j && e_ptr->name.empty())
+ {
+ continue;
+ }
/* Must have the correct fields */
if (j)
@@ -5026,7 +5054,7 @@ static bool_ test_object_wish(char *name, object_type *o_ptr, object_type *forge
if (e_ptr->tval[z] == k_ptr->tval)
{
if ((e_ptr->min_sval[z] <= k_ptr->sval) &&
- (e_ptr->max_sval[z] >= k_ptr->sval)) ok = TRUE;
+ (e_ptr->max_sval[z] >= k_ptr->sval)) ok = true;
}
if (ok) break;
}
@@ -5035,62 +5063,88 @@ static bool_ test_object_wish(char *name, object_type *o_ptr, object_type *forge
continue;
}
}
+ do {
+ object_prep(o_ptr, k_entry.first);
+ o_ptr->name1 = 0;
+ o_ptr->name2 = j;
+ o_ptr->name2b = 0;
+ apply_magic(o_ptr, dun_level, false, true, false);
+ object_aware(o_ptr);
+ object_known(o_ptr);
+ object_desc(buf, o_ptr, false, 0);
+ strlower(buf);
+ } while (o_ptr->name2b || !o_ptr->artifact_name.empty()); //If apply magic added a second ego or made an artifact, retry.;
- /* try all ego */
- for (std::size_t jb = 0; jb < e_info.size(); jb++)
+ if (iequals(buf, name))
{
- auto eb_ptr = &e_info[jb];
- bool_ ok = FALSE;
-
- if (jb && !eb_ptr->name) continue;
+ /* Don't search any more */
+ return true;
+ }
- if (j && jb && (e_ptr->before == eb_ptr->before)) continue;
+ /* Restore again the aware status */
+ k_ptr->aware = save_aware;
- /* Must have the correct fields */
- if (jb)
+ if (strstr(name, buf))
+ {
+ /* try all ego */
+ for (std::size_t jb = 0; jb < e_info.size(); jb++)
{
- int z;
+ auto eb_ptr = &e_info[jb];
+ bool ok = false;
- for (z = 0; z < 6; z++)
+ if (jb && eb_ptr->name.empty())
{
- if (eb_ptr->tval[z] == k_ptr->tval)
+ continue;
+ }
+
+ /* Must have the correct fields */
+ if (jb)
+ {
+ int z;
+
+ for (z = 0; z < 6; z++)
+ {
+ if (eb_ptr->tval[z] == k_ptr->tval)
+ {
+ if ((eb_ptr->min_sval[z] <= k_ptr->sval) &&
+ (eb_ptr->max_sval[z] >= k_ptr->sval)) ok = true;
+ }
+ if (ok) break;
+ }
+ if (!ok)
{
- if ((eb_ptr->min_sval[z] <= k_ptr->sval) &&
- (eb_ptr->max_sval[z] >= k_ptr->sval)) ok = TRUE;
+ continue;
}
- if (ok) break;
}
- if (!ok)
+
+ do {
+ object_prep(o_ptr, k_entry.first);
+ o_ptr->name1 = 0;
+ o_ptr->name2 = j;
+ o_ptr->name2b = jb;
+ apply_magic(o_ptr, dun_level, false, true, true);
+ object_aware(o_ptr);
+ object_known(o_ptr);
+ object_desc(buf, o_ptr, false, 0);
+ strlower(buf);
+ } while (!o_ptr->artifact_name.empty()); //If apply magic turns it into an artifact, retry.
+
+ if (iequals(buf, name))
{
- continue;
+ /* Don't search any more */
+ return true;
+ }
+ else
+ {
+ /* Restore again the aware status */
+ k_ptr->aware = save_aware;
}
- }
-
- object_prep(o_ptr, i);
- o_ptr->name1 = 0;
- o_ptr->name2 = j;
- o_ptr->name2b = jb;
- apply_magic(o_ptr, dun_level, FALSE, FALSE, FALSE);
- object_aware(o_ptr);
- object_known(o_ptr);
- object_desc(buf, o_ptr, FALSE, 0);
- strlower(buf);
-
- if (iequals(buf, name))
- {
- /* Don't search any more */
- return TRUE;
- }
- else
- {
- /* Restore again the aware status */
- k_ptr->aware = save_aware;
}
}
}
}
}
- return FALSE;
+ return false;
}
static void clean_wish_name(char *buf, char *name)
@@ -5130,7 +5184,7 @@ static void clean_wish_name(char *buf, char *name)
/*
* Allow the player to make a wish
*/
-void make_wish()
+bool make_wish()
{
auto const &re_info = game->edit_data.re_info;
auto const &r_info = game->edit_data.r_info;
@@ -5144,7 +5198,7 @@ void make_wish()
buf[0] = 0;
/* Ask for the wish */
- if (!get_string("Wish for what? ", buf, 80)) return;
+ if (!get_string("Wish for what? ", buf, 80)) return false;
clean_wish_name(buf, name);
@@ -5152,41 +5206,41 @@ void make_wish()
if (strstr(name, "wish"))
{
msg_print("You can't wish for a wish!");
- return;
+ return false;
}
- if (test_object_wish(name, o_ptr, &forge, "wish"))
+ if (test_object_wish(name, o_ptr, &forge))
{
msg_print("Your wish becomes truth!");
/* Give it to the player */
drop_near(o_ptr, -1, p_ptr->py, p_ptr->px);
- return;
+ return true;
}
/* try monsters */
- if (prefix(name, "enemy "))
+ if (starts_with(name, "enemy "))
{
mstatus = MSTATUS_ENEMY;
mname = name + 6;
}
- else if (prefix(name, "neutral "))
+ else if (starts_with(name, "neutral "))
{
mstatus = MSTATUS_NEUTRAL;
mname = name + 8;
}
- else if (prefix(name, "friendly "))
+ else if (starts_with(name, "friendly "))
{
mstatus = MSTATUS_FRIEND;
mname = name + 9;
}
- else if (prefix(name, "pet "))
+ else if (starts_with(name, "pet "))
{
mstatus = MSTATUS_PET;
mname = name + 4;
}
- else if (prefix(name, "companion "))
+ else if (starts_with(name, "companion "))
{
if (can_create_companion()) mstatus = MSTATUS_COMPANION;
else mstatus = MSTATUS_PET;
@@ -5251,17 +5305,18 @@ void make_wish()
while (!(in_bounds(wy, wx) && cave_floor_bold(wy, wx)) && --attempts);
/* Create the monster */
- if (place_monster_one(wy, wx, i, j, FALSE, mstatus))
+ if (place_monster_one(wy, wx, i, j, false, mstatus))
{
msg_print("Your wish becomes truth!");
}
/* Don't search any more */
- return;
+ return true;
}
}
}
}
+ return false;
}
@@ -5279,15 +5334,12 @@ static void corrupt_corrupted()
{
gain_random_corruption();
}
-
- /* We are done. */
- return;
}
/*
* Change to an other subrace
*/
-void switch_subrace(std::size_t racem, bool_ copy_old)
+void switch_subrace(std::size_t racem, bool copy_old)
{
auto &race_mod_info = game->edit_data.race_mod_info;
diff --git a/src/xtra2.hpp b/src/xtra2.hpp
index 9edcec1e..267e3c39 100644
--- a/src/xtra2.hpp
+++ b/src/xtra2.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "monster_race_fwd.hpp"
#include "object_type_fwd.hpp"
#include "player_race_mod_fwd.hpp"
@@ -8,82 +8,77 @@
#include <memory>
void do_rebirth();
-void switch_subrace(std::size_t racem, bool_ copy_old);
+void switch_subrace(std::size_t racem, bool copy_old);
void drop_from_wild();
-bool_ set_roots(int v, s16b ac, s16b dam);
-bool_ set_project(int v, s16b gf, s16b dam, s16b rad, s16b flag);
-bool_ set_parasite(int v, int r);
-bool_ set_disrupt_shield(int v);
-bool_ set_prob_travel(int v);
-bool_ set_absorb_soul(int v);
-bool_ set_tim_breath(int v, bool_ magical);
-bool_ set_tim_precognition(int v);
-bool_ set_tim_deadly(int v);
-bool_ set_tim_reflect(int v);
-bool_ set_tim_thunder(int v, int p1, int p2);
-bool_ set_strike(int v);
-bool_ set_tim_regen(int v, int p);
-bool_ set_tim_ffall(int v);
-bool_ set_tim_fly(int v);
-bool_ set_poison(int v);
-bool_ set_holy(int v);
+bool set_roots(int v, s16b ac, s16b dam);
+bool set_project(int v, s16b gf, s16b dam, s16b rad, s16b flag);
+bool set_parasite(int v, int r);
+bool set_disrupt_shield(int v);
+bool set_prob_travel(int v);
+bool set_absorb_soul(int v);
+bool set_tim_breath(int v, bool magical);
+bool set_tim_precognition(int v);
+bool set_tim_deadly(int v);
+bool set_tim_reflect(int v);
+bool set_tim_thunder(int v, int p1, int p2);
+bool set_strike(int v);
+bool set_tim_regen(int v, int p);
+bool set_tim_ffall(int v);
+bool set_tim_fly(int v);
+bool set_poison(int v);
+bool set_holy(int v);
void set_grace(s32b v);
-bool_ set_mimic(int v, int p, int level);
-bool_ set_no_breeders(int v);
-bool_ set_invis(int v,int p);
-bool_ set_lite(int v);
-bool_ set_blind(int v);
-bool_ set_confused(int v);
-bool_ set_poisoned(int v);
-bool_ set_afraid(int v);
-bool_ set_paralyzed(int v);
+bool set_mimic(int v, int p, int level);
+bool set_no_breeders(int v);
+bool set_invis(int v,int p);
+bool set_lite(int v);
+bool set_blind(int v);
+bool set_confused(int v);
+bool set_poisoned(int v);
+bool set_afraid(int v);
+bool set_paralyzed(int v);
void dec_paralyzed();
-bool_ set_image(int v);
-bool_ set_fast(int v, int p);
-bool_ set_light_speed(int v);
-bool_ set_slow(int v);
-bool_ set_shield(int v, int p, s16b o, s16b d1, s16b d2);
-bool_ set_blessed(int v);
-bool_ set_hero(int v);
-bool_ set_shero(int v);
-bool_ set_protevil(int v);
-bool_ set_invuln(int v);
-bool_ set_tim_invis(int v);
-bool_ set_tim_infra(int v);
-bool_ set_mental_barrier(int v);
-bool_ set_oppose_acid(int v);
-bool_ set_oppose_elec(int v);
-bool_ set_oppose_fire(int v);
-bool_ set_oppose_cold(int v);
-bool_ set_oppose_pois(int v);
-bool_ set_oppose_cc(int v);
-bool_ set_stun(int v);
-bool_ set_cut(int v);
-bool_ set_food(int v);
+bool set_image(int v);
+bool set_fast(int v, int p);
+bool set_light_speed(int v);
+bool set_slow(int v);
+bool set_shield(int v, int p, s16b o, s16b d1, s16b d2);
+bool set_blessed(int v);
+bool set_hero(int v);
+bool set_shero(int v);
+bool set_protevil(int v);
+bool set_invuln(int v);
+bool set_tim_invis(int v);
+bool set_tim_infra(int v);
+bool set_mental_barrier(int v);
+bool set_oppose_acid(int v);
+bool set_oppose_elec(int v);
+bool set_oppose_fire(int v);
+bool set_oppose_cold(int v);
+bool set_oppose_pois(int v);
+bool set_oppose_cc(int v);
+bool set_stun(int v);
+bool set_cut(int v);
+bool set_food(int v);
void check_experience();
void check_experience_obj(object_type *o_ptr);
void gain_exp(s32b amount);
void lose_exp(s32b amount);
int get_coin_type(std::shared_ptr<monster_race const> r_ptr);
void monster_death(int m_idx);
-bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note);
-bool_ change_panel(int dy, int dx);
+bool mon_take_hit(int m_idx, int dam, bool *fear, const char *note);
+bool change_panel(int dy, int dx);
void verify_panel();
-bool_ target_okay();
-bool_ target_set(int mode);
-bool_ get_aim_dir(int *dp);
-bool_ get_rep_dir(int *dp);
-bool_ set_shadow(int v);
-bool_ set_tim_esp(int v);
-bool_ tgp_pt(int *x, int * y);
-bool_ tgt_pt (int *x, int *y);
+bool target_okay();
+bool target_set(int mode);
+bool get_aim_dir(int *dp);
+bool get_rep_dir(int *dp);
+bool set_shadow(int v);
+bool set_tim_esp(int v);
+bool tgp_pt(int *x, int * y);
+bool tgt_pt (int *x, int *y);
void do_poly_self();
-bool_ curse_weapon();
-bool_ curse_armor();
-void make_wish();
+bool make_wish();
void create_between_gate(int dist, int y, int x);
-
-extern "C" {
- void resize_map();
- void resize_window();
-}
+void resize_map();
+void resize_window();
diff --git a/src/z-form.c b/src/z-form.cc
index 90d71294..5ee74e07 100644
--- a/src/z-form.c
+++ b/src/z-form.cc
@@ -1,12 +1,10 @@
-/* File: z-form.c */
+#include "z-form.hpp"
-/* Purpose: Low level text formatting -BEN- */
+#include "z-util.hpp"
-#include "z-form.h"
-
-#include "z-util.h"
-
-#include <stdlib.h>
+#include <cctype>
+#include <cstdlib>
+#include <cstdio>
/*
* Here is some information about the routines in this file.
@@ -48,7 +46,7 @@
* Save the current length into (*np).
* No legal modifiers.
*
- * Format("%p", vptr v)
+ * Format("%p", (void *) v)
* Append the pointer "v" (implementation varies).
* No legal modifiers.
*
@@ -92,12 +90,12 @@
* Append the character "c".
* Do not use the "+" or "0" flags.
*
- * Format("%s", cptr s)
+ * Format("%s", const char *s)
* Append the string "s".
* Do not use the "+" or "0" flags.
* Note that a "NULL" value of "s" is converted to the empty string.
*
- * Format("%V", vptr v)
+ * Format("%V", (void *) v)
* Note -- possibly significant mode flag
*
*
@@ -177,21 +175,21 @@
* the given buffer to a length of zero, and return a "length" of zero.
* The contents of "buf", except for "buf[0]", may then be undefined.
*/
-uint vstrnfmt(char *buf, uint max, cptr fmt, va_list vp)
+unsigned int vstrnfmt(char *buf, unsigned int max, const char *fmt, va_list vp)
{
- cptr s;
+ const char *s;
/* The argument is "long" */
- bool_ do_long;
+ bool do_long;
/* The argument needs "processing" */
- bool_ do_xtra;
+ bool do_xtra;
/* Bytes used in buffer */
- uint n;
+ unsigned int n;
/* Bytes used in format sequence */
- uint q;
+ unsigned int q;
/* Format sequence */
char aux[128];
@@ -214,7 +212,7 @@ uint vstrnfmt(char *buf, uint max, cptr fmt, va_list vp)
s = fmt;
/* Scan the format string */
- while (TRUE)
+ while (true)
{
/* All done */
if (!*s) break;
@@ -277,13 +275,13 @@ uint vstrnfmt(char *buf, uint max, cptr fmt, va_list vp)
aux[q++] = '%';
/* Assume no "long" argument */
- do_long = FALSE;
+ do_long = false;
/* Assume no "xtra" processing */
- do_xtra = FALSE;
+ do_xtra = false;
/* Build the "aux" string */
- while (TRUE)
+ while (true)
{
/* Error -- format sequence is not terminated */
if (!*s)
@@ -315,7 +313,7 @@ uint vstrnfmt(char *buf, uint max, cptr fmt, va_list vp)
aux[q++] = *s++;
/* Note the "long" flag */
- do_long = TRUE;
+ do_long = true;
}
/* Mega-Hack -- handle "extra-long" request */
@@ -364,7 +362,7 @@ uint vstrnfmt(char *buf, uint max, cptr fmt, va_list vp)
else if (*s == '^')
{
/* Note the "xtra" flag */
- do_xtra = TRUE;
+ do_xtra = true;
/* Skip the "^" */
s++;
@@ -486,10 +484,8 @@ uint vstrnfmt(char *buf, uint max, cptr fmt, va_list vp)
/* Pointer -- implementation varies */
case 'p':
{
- vptr arg;
-
/* Access next argument */
- arg = va_arg(vp, vptr);
+ void *arg = va_arg(vp, void *);
/* Format the argument */
sprintf(tmp, aux, arg);
@@ -501,10 +497,10 @@ uint vstrnfmt(char *buf, uint max, cptr fmt, va_list vp)
/* String */
case 's':
{
- cptr arg;
+ const char *arg;
/* Access next argument */
- arg = va_arg(vp, cptr);
+ arg = va_arg(vp, const char *);
/* Hack -- convert NULL to EMPTY */
if (!arg) arg = "";
@@ -558,7 +554,7 @@ uint vstrnfmt(char *buf, uint max, cptr fmt, va_list vp)
* Do a vstrnfmt (see above) into a (growable) static buffer.
* This buffer is usable for very short term formatting of results.
*/
-static char *vformat(cptr fmt, va_list vp)
+static char *vformat(const char *fmt, va_list vp)
{
static char *format_buf = NULL;
static size_t format_len = 0;
@@ -567,7 +563,7 @@ static char *vformat(cptr fmt, va_list vp)
if (!format_buf)
{
format_len = 1024;
- format_buf = calloc(format_len, sizeof(char));
+ format_buf = (char *) calloc(format_len, sizeof(char));
if (format_buf == NULL)
{
abort(); // Nothing sensible we can do
@@ -578,9 +574,9 @@ static char *vformat(cptr fmt, va_list vp)
if (!fmt) return (format_buf);
/* Keep going until successful */
- while (1)
+ while (true)
{
- uint len;
+ unsigned int len;
/* Build the string */
len = vstrnfmt(format_buf, format_len, fmt, vp);
@@ -591,7 +587,7 @@ static char *vformat(cptr fmt, va_list vp)
/* Grow the buffer */
free(format_buf);
format_len = format_len * 2;
- format_buf = calloc(format_len, sizeof(char));
+ format_buf = (char *) calloc(format_len, sizeof(char));
if (format_buf == NULL)
{
abort(); // Nothing sensible we can do
@@ -607,9 +603,9 @@ static char *vformat(cptr fmt, va_list vp)
/*
* Do a vstrnfmt (see above) into a buffer of a given size.
*/
-uint strnfmt(char *buf, uint max, cptr fmt, ...)
+unsigned int strnfmt(char *buf, unsigned int max, const char *fmt, ...)
{
- uint len;
+ unsigned int len;
va_list vp;
@@ -635,7 +631,7 @@ uint strnfmt(char *buf, uint max, cptr fmt, ...)
* Note that the buffer is (technically) writable, but only up to
* the length of the string contained inside it.
*/
-char *format(cptr fmt, ...)
+char *format(const char *fmt, ...)
{
char *res;
va_list vp;
@@ -659,7 +655,7 @@ char *format(cptr fmt, ...)
/*
* Vararg interface to quit()
*/
-void quit_fmt(cptr fmt, ...)
+void quit_fmt(const char *fmt, ...)
{
char *res;
va_list vp;
diff --git a/src/z-form.h b/src/z-form.hpp
index f67d1484..11d61ae3 100644
--- a/src/z-form.h
+++ b/src/z-form.hpp
@@ -1,10 +1,8 @@
#pragma once
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "h-basic.hpp"
-#include "h-basic.h"
+#include <cstdarg>
/*
* This file provides functions very similar to "sprintf()", but which
@@ -21,17 +19,13 @@ extern "C" {
/**** Available Functions ****/
/* Format arguments into given bounded-length buffer */
-uint vstrnfmt(char *buf, uint max, cptr fmt, va_list vp);
+unsigned int vstrnfmt(char *buf, unsigned int max, const char *fmt, va_list vp);
/* Simple interface to "vstrnfmt()" */
-uint strnfmt(char *buf, uint max, cptr fmt, ...);
+unsigned int strnfmt(char *buf, unsigned int max, const char *fmt, ...);
/* Simple interface to "vformat()" */
-char *format(cptr fmt, ...);
+char *format(const char *fmt, ...);
/* Vararg interface to "quit()", using "format()" */
-void quit_fmt(cptr fmt, ...);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
+void quit_fmt(const char *fmt, ...);
diff --git a/src/z-rand.cc b/src/z-rand.cc
index a35eb08b..f5f10066 100644
--- a/src/z-rand.cc
+++ b/src/z-rand.cc
@@ -4,7 +4,7 @@
#include "z-rand.hpp"
-#include <assert.h>
+#include <cassert>
#include <cstdint>
#include <limits>
#include <random>
@@ -24,7 +24,7 @@ using rng_t = pcg64_once_insecure;
/**
* Reseed the given RNG.
*/
-static void reseed_rng(rng_t *rng, seed_t const &seed)
+static void reseed_rng(rng_t *rng)
{
assert(rng != nullptr);
// Create a seed_seq from the seed data.
@@ -43,7 +43,7 @@ static void reseed_rng(rng_t *rng, seed_t const &seed)
static rng_t *new_seeded_rng(seed_t const &seed)
{
rng_t *rng = new rng_t;
- reseed_rng(rng, seed);
+ reseed_rng(rng);
return rng;
}
@@ -91,7 +91,7 @@ static rng_t *get_current_rng()
void set_quick_rng(seed_t const &seed)
{
- reseed_rng(quick_rng(), seed);
+ reseed_rng(quick_rng());
current_rng = quick_rng();
}
diff --git a/src/z-rand.hpp b/src/z-rand.hpp
index b04523c3..645b3117 100644
--- a/src/z-rand.hpp
+++ b/src/z-rand.hpp
@@ -1,8 +1,9 @@
#pragma once
-#include "h-basic.h"
+#include "h-basic.hpp"
#include "seed_fwd.hpp"
+#include <cassert>
#include <string>
/**** Available constants ****/
@@ -91,7 +92,8 @@ s32b rand_spread(s32b a, s32b d);
**/
template <class C> typename C::const_iterator uniform_element(C const &c)
{
- return c.cbegin() + rand_int(c.size());
+ assert(!c.empty());
+ return std::next(std::cbegin(c), rand_int(c.size()));
}
/**
@@ -101,5 +103,24 @@ template <class C> typename C::const_iterator uniform_element(C const &c)
**/
template <class C> typename C::iterator uniform_element(C &c)
{
- return c.begin() + rand_int(c.size());
+ assert(!c.empty());
+ return std::next(std::begin(c), rand_int(c.size()));
+}
+
+/**
+ * Shuffle contents of given random-access container.
+ */
+template <class C> void shuffle(C &c)
+{
+ if (c.empty())
+ {
+ return;
+ }
+
+ auto n = c.size();
+
+ for (auto i = n - 1; i > 0; i--)
+ {
+ std::swap(c[i], c[rand_int(i + 1)]);
+ }
}
diff --git a/src/z-term.c b/src/z-term.cc
index 53b23c02..cc7ee4d6 100644
--- a/src/z-term.c
+++ b/src/z-term.cc
@@ -8,8 +8,16 @@
/* Purpose: a generic, efficient, terminal window package -BEN- */
-#include "z-term.h"
+#include "z-term.hpp"
+#include "key_queue.hpp"
+#include "frontend.hpp"
+#include "tome/unique_handle.hpp"
+
+#include <cassert>
+#include <memory>
+#include <optional>
+#include <vector>
/*
@@ -226,160 +234,289 @@
/*
- * The current "term"
+ * A term_win is a "window" for a Term
+ *
+ * - Cursor Useless/Visible codes
+ * - Cursor Location (see "Useless")
+ *
+ * - Array[h] -- Access to the attribute array
+ * - Array[h] -- Access to the character array
+ *
+ * - Array[h*w] -- Attribute array
+ * - Array[h*w] -- Character array
+ *
+ * Note that the attr/char pair at (x,y) is a[y][x]/c[y][x]
+ * and that the row of attr/chars at (0,y) is a[y]/c[y]
*/
-term *Term = NULL;
-
-/*** Local routines ***/
-
-/*
- * Calloc wrapper which aborts if NULL is returned by calloc
- */
-static void *safe_calloc(size_t nmemb, size_t size)
+struct term_win final
{
- void *p = calloc(nmemb, size);
- if ((nmemb > 0) && (p == NULL))
+private:
+ std::vector<byte> va;
+ std::vector<char> vc;
+
+public:
+
+ bool cu = true;
+ bool cv = false;
+ byte cx = 0;
+ byte cy = 0;
+
+ std::vector<byte *> a;
+ std::vector<char *> c;
+
+ /**
+ * Ctor
+ */
+ explicit term_win(int w, int h)
+ : va(h * w)
+ , vc(h * w)
+ , a(h)
+ , c(h)
{
- abort();
+ // The idea here is that our va and vc vectors are just
+ // a single contiguous block of memory and that each "row"
+ // of a and c point into the correct location in that single
+ // block of memory.
+ for (int y = 0; y < h; y++)
+ {
+ a[y] = va.data() + w * y;
+ c[y] = vc.data() + w * y;
+ }
}
- return p;
-}
-/*
- * Nuke a term_win (see below)
- */
-static errr term_win_nuke(term_win *s, int w, int h)
-{
- /* Free the window access arrays */
- free(s->a);
- s->a = NULL;
+ /*
+ * Copy contents of a "term_win" up to the given dimensions.
+ */
+ void copy_from(term_win const *f, int w, int h)
+ {
+ /* Copy contents */
+ for (int y = 0; y < h; y++)
+ {
+ byte *f_aa = f->a[y];
+ char *f_cc = f->c[y];
- free(s->c);
- s->c = NULL;
+ byte *s_aa = a[y];
+ char *s_cc = c[y];
- /* Free the window content arrays */
- free(s->va);
- s->va = NULL;
+ for (int x = 0; x < w; x++)
+ {
+ *s_aa++ = *f_aa++;
+ *s_cc++ = *f_cc++;
+ }
+ }
- free(s->vc);
- s->vc = NULL;
+ /* Copy cursor */
+ cx = f->cx;
+ cy = f->cy;
+ cu = f->cu;
+ cv = f->cv;
+ }
- /* Success */
- return (0);
-}
+ /**
+ * Copy contents of a "term_win" up to the given dimensions.
+ */
+ void copy_from(std::unique_ptr<term_win> const &p, int w, int h)
+ {
+ copy_from(p.get(), w, h);
+ }
+ /**
+ * Force cursor to be visible.
+ */
+ void set_cursor_visible()
+ {
+ cu = false;
+ cv = true;
+ }
-/*
- * Initialize a "term_win" (using the given window size)
- */
-static errr term_win_init(term_win *s, int w, int h)
-{
- int y;
+ /**
+ * Dtor
+ */
+ ~term_win() = default;
- /* Make the window access arrays */
- s->a = safe_calloc(h, sizeof(byte*));
- s->c = safe_calloc(h, sizeof(char*));
+};
- /* Make the window content arrays */
- s->va = safe_calloc(h * w, sizeof(byte));
- s->vc = safe_calloc(h * w, sizeof(char));
- /* Prepare the window access arrays */
- for (y = 0; y < h; y++)
+
+static errr push_result_to_errr(key_queue::push_result_t r)
+{
+ using pr = key_queue::push_result_t;
+
+ switch (r)
{
- s->a[y] = s->va + w * y;
- s->c[y] = s->vc + w * y;
+ case pr::OK:
+ return 0;
+ case pr::OVERFLOW:
+ return 1;
}
- /* Success */
- return (0);
+ return -1;
}
+
/*
- * Copy a "term_win" from another
+ * An actual "term" structure
+ *
+ * - Extra "data" info (used by implementation)
+ *
+ *
+ * - Flag "active_flag"
+ * This "term" is "active"
+ *
+ * - Flag "mapped_flag"
+ * This "term" is "mapped"
+ *
+ * - Flag "total_erase"
+ * This "term" should be fully erased
+ *
+ * - Flag "icky_corner"
+ * This "term" has an "icky" corner grid
+ *
+ * - Flag "soft_cursor"
+ * This "term" uses a "software" cursor
+ *
+ *
+ *
+ *
+ * - Ignore this pointer
+ *
+ * - Keypress Queue -- various data
+ *
+ * - Keypress Queue -- pending keys
+ *
+ *
+ * - Window Width (max 255)
+ * - Window Height (max 255)
+ *
+ * - Minimum modified row
+ * - Maximum modified row
+ *
+ * - Minimum modified column (per row)
+ * - Maximum modified column (per row)
+ *
+ *
+ * - Displayed screen image
+ * - Requested screen image
+ *
+ * - Temporary screen image
+ * - Memorized screen image
+ *
+ *
+ * - Hook for init-ing the term
+ * - Hook for nuke-ing the term
+ *
+ * - Hook for extra actions
+ *
+ * - Hook for placing the cursor
+ *
+ * - Hook for drawing a string of chars using an attr
+ *
+ * - Hook for drawing a sequence of special attr/char pairs
*/
-static errr term_win_copy(term_win *s, term_win *f, int w, int h)
-{
- int x, y;
- /* Copy contents */
- for (y = 0; y < h; y++)
+struct term
+{
+ bool active_flag = false;
+ bool mapped_flag = false;
+ bool total_erase = true;
+
+ key_queue m_key_queue;
+
+ byte wid;
+ byte hgt;
+
+ byte y1;
+ byte y2;
+
+ std::vector<byte> x1;
+ std::vector<byte> x2;
+
+ std::unique_ptr<term_win> old;
+ std::unique_ptr<term_win> scr;
+ std::unique_ptr<term_win> mem;
+
+ std::shared_ptr<Frontend> m_frontend;
+ std::function<void ()> m_resize_hook;
+
+ bool icky_corner;
+ bool soft_cursor;
+
+ /**
+ * Ctor
+ */
+ term(int w, int h, int k, std::shared_ptr<Frontend> user_interface)
+ : m_key_queue(k)
+ , wid(w)
+ , hgt(h)
+ , x1(h)
+ , x2(h)
+ , m_frontend(std::move(user_interface))
+ , icky_corner(m_frontend->icky_corner())
+ , soft_cursor(m_frontend->soft_cursor())
{
- byte *f_aa = f->a[y];
- char *f_cc = f->c[y];
+ /* Allocate "displayed" */
+ old = std::make_unique<term_win>(w, h);
- byte *s_aa = s->a[y];
- char *s_cc = s->c[y];
+ /* Allocate "requested" */
+ scr = std::make_unique<term_win>(w, h);
- for (x = 0; x < w; x++)
+ /* Assume change */
+ for (int y = 0; y < h; y++)
{
- *s_aa++ = *f_aa++;
- *s_cc++ = *f_cc++;
+ /* Assume change */
+ x1[y] = 0;
+ x2[y] = w - 1;
}
- }
-
- /* Copy cursor */
- s->cx = f->cx;
- s->cy = f->cy;
- s->cu = f->cu;
- s->cv = f->cv;
-
- /* Success */
- return (0);
-}
+ /* Assume change */
+ y1 = 0;
+ y2 = h - 1;
+ }
+ /**
+ * Dtor
+ */
+ ~term()
+ {
+ /* Hack -- Call the special "nuke" hook */
+ if (active_flag)
+ {
+ /* Call the "nuke" hook */
+ m_frontend->nuke();
-/*** External hooks ***/
+ /* Remember */
+ active_flag = false;
+ /* Assume not mapped */
+ mapped_flag = false;
+ }
+ }
-/*
- * Execute the "Term->xtra_hook" hook, if available (see above).
- * And *hacky* get a return code
- */
-errr Term_xtra(int n, int v)
-{
- /* Verify the hook */
- if (!Term->xtra_hook) return ( -1);
+ void text(int x, int y, int n, byte a, const char *s)
+ {
+ m_frontend->draw_text(x, y, n, a, s);
+ }
- /* Call the hook */
- return ((*Term->xtra_hook)(n, v));
-}
+ void curs(int x, int y)
+ {
+ m_frontend->draw_cursor(x, y);
+ }
+ void fresh()
+ {
+ m_frontend->flush_output();
+ }
+};
-/*** Fake hooks ***/
/*
- * Hack -- fake hook for "Term_curs()" (see above)
+ * The current "term"
*/
-static errr Term_curs_hack(int x, int y)
-{
- /* Compiler silliness */
- if (x || y) return ( -2);
-
- /* Oops */
- return ( -1);
-}
-
-/*
- * Hack -- fake hook for "Term_text()" (see above)
- */
-static errr Term_text_hack(int x, int y, int n, byte a, const char *cp)
-{
- /* Compiler silliness */
- if (x || y || n || a || cp) return ( -2);
-
- /* Oops */
- return ( -1);
-}
-
-
-
-/*** Efficient routines ***/
+term *Term = nullptr;
/*
@@ -389,7 +526,7 @@ static errr Term_text_hack(int x, int y, int n, byte a, const char *cp)
*/
void Term_queue_char(int x, int y, byte a, char c)
{
- term_win *scrn = Term->scr;
+ auto const &scrn = Term->scr;
byte *scr_aa = &scrn->a[y][x];
char *scr_cc = &scrn->c[y][x];
@@ -420,7 +557,7 @@ void Term_queue_char(int x, int y, byte a, char c)
* a valid location, so the first "n" characters of "s" can all be added
* starting at (x,y) without causing any illegal operations.
*/
-void Term_queue_chars(int x, int y, int n, byte a, cptr s)
+static void Term_queue_chars(int x, int y, int n, byte a, const char *s)
{
int x1 = -1, x2 = -1;
@@ -512,7 +649,7 @@ static void Term_fresh_row_text(int y, int x1, int x2)
/* Flush */
if (fn)
{
- (void)((*Term->text_hook)(fx, y, fn, fa, &scr_cc[fx]));
+ Term->text(fx, y, fn, fa, &scr_cc[fx]);
/* Forget */
fn = 0;
@@ -533,7 +670,7 @@ static void Term_fresh_row_text(int y, int x1, int x2)
if (fn)
{
/* Draw the pending chars */
- (void)((*Term->text_hook)(fx, y, fn, fa, &scr_cc[fx]));
+ Term->text(fx, y, fn, fa, &scr_cc[fx]);
/* Forget */
fn = 0;
@@ -550,7 +687,7 @@ static void Term_fresh_row_text(int y, int x1, int x2)
/* Flush */
if (fn)
{
- (void)((*Term->text_hook)(fx, y, fn, fa, &scr_cc[fx]));
+ Term->text(fx, y, fn, fa, &scr_cc[fx]);
}
}
@@ -636,7 +773,7 @@ static void Term_fresh_row_text(int y, int x1, int x2)
* Currently, the use of "Term->icky_corner" and "Term->soft_cursor"
* together may result in undefined behavior.
*/
-errr Term_fresh(void)
+void Term_fresh()
{
int x, y;
@@ -646,12 +783,15 @@ errr Term_fresh(void)
int y1 = Term->y1;
int y2 = Term->y2;
- term_win *old = Term->old;
- term_win *scr = Term->scr;
+ auto const &old = Term->old;
+ auto const &scr = Term->scr;
/* Do nothing unless "mapped" */
- if (!Term->mapped_flag) return (1);
+ if (!Term->mapped_flag)
+ {
+ return;
+ }
/* Trivial Refresh */
@@ -663,15 +803,9 @@ errr Term_fresh(void)
!(Term->total_erase))
{
/* Nothing */
- return (1);
+ return;
}
-
- /* Paranoia -- use "fake" hooks to prevent core dumps */
- if (!Term->curs_hook) Term->curs_hook = Term_curs_hack;
- if (!Term->text_hook) Term->text_hook = Term_text_hack;
-
-
/* Handle "total erase" */
if (Term->total_erase)
{
@@ -679,10 +813,13 @@ errr Term_fresh(void)
char nc = CHAR_BLANK;
/* Physically erase the entire window */
- Term_xtra(TERM_XTRA_CLEAR, 0);
+ Term->m_frontend->clear();
/* Hack -- clear all "cursor" data */
- old->cv = old->cu = old->cx = old->cy = 0;
+ old->cv = false;
+ old->cu = false;
+ old->cx = 0;
+ old->cy = 0;
/* Wipe each row */
for (y = 0; y < h; y++)
@@ -711,7 +848,7 @@ errr Term_fresh(void)
}
/* Forget "total erase" */
- Term->total_erase = FALSE;
+ Term->total_erase = false;
}
@@ -731,22 +868,10 @@ errr Term_fresh(void)
char oc = old_cc[tx];
/* Hack -- restore the actual character */
- (void)((*Term->text_hook)(tx, ty, 1, oa, &oc));
+ Term->text(tx, ty, 1, oa, &oc);
}
}
- /* Cursor Update -- Erase old Cursor */
- else
- {
- /* Cursor will be invisible */
- if (scr->cu || !scr->cv)
- {
- /* Make the cursor invisible */
- Term_xtra(TERM_XTRA_SHAPE, 0);
- }
- }
-
-
/* Something to update */
if (y1 <= y2)
{
@@ -797,7 +922,7 @@ errr Term_fresh(void)
if (!scr->cu && scr->cv)
{
/* Call the cursor display routine */
- (void)((*Term->curs_hook)(scr->cx, scr->cy));
+ Term->curs(scr->cx, scr->cy);
}
}
@@ -808,7 +933,7 @@ errr Term_fresh(void)
if (scr->cu)
{
/* Paranoia -- Put the cursor NEAR where it belongs */
- (void)((*Term->curs_hook)(w - 1, scr->cy));
+ Term->curs(w - 1, scr->cy);
/* Make the cursor invisible */
/* Term_xtra(TERM_XTRA_SHAPE, 0); */
@@ -818,7 +943,7 @@ errr Term_fresh(void)
else if (!scr->cv)
{
/* Paranoia -- Put the cursor where it belongs */
- (void)((*Term->curs_hook)(scr->cx, scr->cy));
+ Term->curs(scr->cx, scr->cy);
/* Make the cursor invisible */
/* Term_xtra(TERM_XTRA_SHAPE, 0); */
@@ -828,10 +953,7 @@ errr Term_fresh(void)
else
{
/* Put the cursor where it belongs */
- (void)((*Term->curs_hook)(scr->cx, scr->cy));
-
- /* Make the cursor visible */
- Term_xtra(TERM_XTRA_SHAPE, 1);
+ Term->curs(scr->cx, scr->cy);
}
}
@@ -844,11 +966,7 @@ errr Term_fresh(void)
/* Actually flush the output */
- Term_xtra(TERM_XTRA_FRESH, 0);
-
-
- /* Success */
- return (0);
+ Term->fresh();
}
@@ -857,22 +975,6 @@ errr Term_fresh(void)
/*
- * Set the cursor visibility
- */
-errr Term_set_cursor(int v)
-{
- /* Already done */
- if (Term->scr->cv == v) return (1);
-
- /* Change */
- Term->scr->cv = v;
-
- /* Success */
- return (0);
-}
-
-
-/*
* Place the cursor at a given location
*
* Note -- "illegal" requests do not move the cursor.
@@ -891,7 +993,7 @@ errr Term_gotoxy(int x, int y)
Term->scr->cy = y;
/* The cursor is not useless */
- Term->scr->cu = 0;
+ Term->scr->cu = false;
/* Success */
return (0);
@@ -903,23 +1005,20 @@ errr Term_gotoxy(int x, int y)
* Do not change the cursor position
* No visual changes until "Term_fresh()".
*/
-errr Term_draw(int x, int y, byte a, char c)
+void Term_draw(int x, int y, byte a, char c)
{
int w = Term->wid;
int h = Term->hgt;
/* Verify location */
- if ((x < 0) || (x >= w)) return ( -1);
- if ((y < 0) || (y >= h)) return ( -1);
+ if ((x < 0) || (x >= w)) return;
+ if ((y < 0) || (y >= h)) return;
/* Paranoia -- illegal char */
- if (!c) return ( -2);
+ if (!c) return;
/* Queue it for later */
Term_queue_char(x, y, a, c);
-
- /* Success */
- return (0);
}
@@ -939,15 +1038,21 @@ errr Term_draw(int x, int y, byte a, char c)
* positive value, future calls to either function will
* return negative ones.
*/
-errr Term_addch(byte a, char c)
+void Term_addch(byte a, char c)
{
int w = Term->wid;
/* Handle "unusable" cursor */
- if (Term->scr->cu) return ( -1);
+ if (Term->scr->cu)
+ {
+ return;
+ }
/* Paranoia -- no illegal chars */
- if (!c) return ( -2);
+ if (!c)
+ {
+ return;
+ }
/* Queue the given character for display */
Term_queue_char(Term->scr->cx, Term->scr->cy, a, c);
@@ -956,13 +1061,13 @@ errr Term_addch(byte a, char c)
Term->scr->cx++;
/* Success */
- if (Term->scr->cx < w) return (0);
-
- /* Note "Useless" cursor */
- Term->scr->cu = 1;
+ if (Term->scr->cx < w)
+ {
+ return;
+ }
/* Note "Useless" cursor */
- return (1);
+ Term->scr->cu = true;
}
@@ -985,7 +1090,7 @@ errr Term_addch(byte a, char c)
* positive value, future calls to either function will
* return negative ones.
*/
-errr Term_addstr(int n, byte a, cptr s)
+errr Term_addstr(int n, byte a, const char *s)
{
int k;
@@ -1012,7 +1117,10 @@ errr Term_addstr(int n, byte a, cptr s)
Term->scr->cx += n;
/* Hack -- Notice "Useless" cursor */
- if (res) Term->scr->cu = 1;
+ if (res)
+ {
+ Term->scr->cu = true;
+ }
/* Success (usually) */
return (res);
@@ -1022,36 +1130,26 @@ errr Term_addstr(int n, byte a, cptr s)
/*
* Move to a location and, using an attr, add a char
*/
-errr Term_putch(int x, int y, byte a, char c)
+void Term_putch(int x, int y, byte a, char c)
{
- errr res;
-
/* Move first */
- if ((res = Term_gotoxy(x, y)) != 0) return (res);
+ if (Term_gotoxy(x, y)) return;
- /* Then add the char */
- if ((res = Term_addch(a, c)) != 0) return (res);
-
- /* Success */
- return (0);
+ /* Add the char */
+ Term_addch(a, c);
}
/*
* Move to a location and, using an attr, add a string
*/
-errr Term_putstr(int x, int y, int n, byte a, cptr s)
+void Term_putstr(int x, int y, int n, byte a, const char *s)
{
- errr res;
-
/* Move first */
- if ((res = Term_gotoxy(x, y)) != 0) return (res);
-
- /* Then add the string */
- if ((res = Term_addstr(n, a, s)) != 0) return (res);
+ if (Term_gotoxy(x, y)) return;
- /* Success */
- return (0);
+ /* Add the string */
+ Term_addstr(n, a, s);
}
@@ -1059,7 +1157,7 @@ errr Term_putstr(int x, int y, int n, byte a, cptr s)
/*
* Place cursor at (x,y), and clear the next "n" chars
*/
-errr Term_erase(int x, int y, int n)
+void Term_erase(int x, int y, int n)
{
int i;
@@ -1076,7 +1174,10 @@ errr Term_erase(int x, int y, int n)
char *scr_cc;
/* Place cursor */
- if (Term_gotoxy(x, y)) return ( -1);
+ if (Term_gotoxy(x, y))
+ {
+ return;
+ }
/* Force legal size */
if (x + n > w) n = w - x;
@@ -1122,9 +1223,6 @@ errr Term_erase(int x, int y, int n)
if (x1 < Term->x1[y]) Term->x1[y] = x1;
if (x2 > Term->x2[y]) Term->x2[y] = x2;
}
-
- /* Success */
- return (0);
}
@@ -1133,7 +1231,7 @@ errr Term_erase(int x, int y, int n)
*
* Note the use of the special "total_erase" code
*/
-errr Term_clear(void)
+void Term_clear()
{
int x, y;
@@ -1144,7 +1242,7 @@ errr Term_clear(void)
char nc = CHAR_BLANK;
/* Cursor usable */
- Term->scr->cu = 0;
+ Term->scr->cu = false;
/* Cursor to the top left */
Term->scr->cx = Term->scr->cy = 0;
@@ -1172,36 +1270,27 @@ errr Term_clear(void)
Term->y2 = h - 1;
/* Force "total erase" */
- Term->total_erase = TRUE;
-
- /* Success */
- return (0);
+ Term->total_erase = true;
}
-
-
-
/*
* Redraw (and refresh) the whole window.
*/
-errr Term_redraw(void)
+void Term_redraw()
{
/* Force "total erase" */
- Term->total_erase = TRUE;
+ Term->total_erase = true;
/* Hack -- Refresh */
Term_fresh();
-
- /* Success */
- return (0);
}
/*
* Redraw part of a window.
*/
-errr Term_redraw_section(int x1, int y1, int x2, int y2)
+void Term_redraw_section(int x1, int y1, int x2, int y2)
{
int i, j;
@@ -1235,39 +1324,144 @@ errr Term_redraw_section(int x1, int y1, int x2, int y2)
/* Hack -- Refresh */
Term_fresh();
-
- /* Success */
- return (0);
}
-
void Term_bell()
{
- Term_xtra(TERM_XTRA_NOISE, 0);
+ Term->m_frontend->noise();
}
/*** Access routines ***/
+namespace { // anonymous
-/*
- * Extract the cursor visibility
+/**
+ * Policy handler for setting/resetting cursor visibility.
*/
-errr Term_get_cursor(int *v)
+struct CursorVisibilyPolicy {
+public:
+ struct handle_type {
+ term *t = nullptr;
+ bool cv = false;
+ };
+
+ static handle_type from(term *t)
+ {
+ return handle_type {
+ .t = t,
+ .cv = t->scr->cv
+ };
+ }
+
+ static handle_type get_null()
+ {
+ return handle_type();
+ }
+
+ static bool is_null(handle_type const &v)
+ {
+ return v.t == nullptr;
+ }
+
+ static void close(handle_type const &v)
+ {
+ Term->scr->cv = v.cv;
+ }
+};
+
+/**
+ * Policy handler for setting/restoring cursor flags.
+ */
+struct CursorFlagsPolicy {
+
+public:
+ struct handle_type {
+ term *t = nullptr;
+ bool cu = false;
+ bool cv = false;
+ };
+
+private:
+ handle_type handle;
+
+public:
+ static handle_type from(term *t)
+ {
+ return handle_type {
+ .t = t,
+ .cu = t->scr->cu,
+ .cv = t->scr->cv
+ };
+ }
+
+ static handle_type get_null()
+ {
+ return handle_type();
+ }
+
+ static bool is_null(handle_type const &h)
+ {
+ return h.t == nullptr;
+ }
+
+ static void close(handle_type &h)
+ {
+ h.t->scr->cu = h.cu;
+ h.t->scr->cv = h.cv;
+ }
+
+};
+
+/**
+ * Policy handler for setting/resetting the active terminal.
+ */
+struct ActiveTerminalPolicy {
+public:
+ using handle_type = term *;
+
+ static handle_type get_null()
+ {
+ return nullptr;
+ }
+
+ static bool is_null(handle_type t)
+ {
+ return t == nullptr;
+ }
+
+ static void close(handle_type t)
+ {
+ Term_activate(t);
+ }
+};
+
+} // namespace (anonymous)
+
+
+void Term_with_saved_cursor_flags(std::function<void ()> callback)
{
- /* Extract visibility */
- (*v) = Term->scr->cv;
+ unique_handle<CursorFlagsPolicy> resetter(CursorFlagsPolicy::from(Term));
+ callback();
+}
- /* Success */
- return (0);
+void Term_with_saved_cursor_visbility(std::function<void ()> callback)
+{
+ unique_handle<CursorVisibilyPolicy> resetter(CursorVisibilyPolicy::from(Term));
+ callback();
}
+void Term_with_active(term *t, std::function<void ()> callback)
+{
+ unique_handle<ActiveTerminalPolicy> resetter(Term);
+ Term_activate(t);
+ callback();
+}
/*
* Extract the current window size
*/
-errr Term_get_size(int *w, int *h)
+void Term_get_size(int *w, int *h)
{
- /* Access the cursor */
if (w)
{
(*w) = Term->wid;
@@ -1277,26 +1471,17 @@ errr Term_get_size(int *w, int *h)
{
(*h) = Term->hgt;
}
-
- /* Success */
- return (0);
}
/*
* Extract the current cursor location
*/
-errr Term_locate(int *x, int *y)
+void Term_locate(int *x, int *y)
{
/* Access the cursor */
(*x) = Term->scr->cx;
(*y) = Term->scr->cy;
-
- /* Warn about "useless" cursor */
- if (Term->scr->cu) return (1);
-
- /* Success */
- return (0);
}
@@ -1305,21 +1490,32 @@ errr Term_locate(int *x, int *y)
* Note that this refers to what will be on the window after the
* next call to "Term_fresh()". It may or may not already be there.
*/
-errr Term_what(int x, int y, byte *a, char *c)
+void Term_what(int x, int y, byte *a, char *c)
{
int w = Term->wid;
int h = Term->hgt;
/* Verify location */
- if ((x < 0) || (x >= w)) return ( -1);
- if ((y < 0) || (y >= h)) return ( -1);
+ assert(x >= 0);
+ assert(x < w);
+ assert(y >= 0);
+ assert(y < h);
/* Direct access */
(*a) = Term->scr->a[y][x];
(*c) = Term->scr->c[y][x];
+}
- /* Success */
- return (0);
+
+void Term_hide_cursor()
+{
+ Term->scr->cv = 0;
+}
+
+
+void Term_show_cursor()
+{
+ Term->scr->set_cursor_visible();
}
@@ -1330,16 +1526,13 @@ errr Term_what(int x, int y, byte *a, char *c)
/*
* Flush and forget the input
*/
-errr Term_flush(void)
+void Term_flush()
{
/* Hack -- Flush all events */
- Term_xtra(TERM_XTRA_FLUSH, 0);
+ Term->m_frontend->flush_events();
/* Forget all keypresses */
- Term->key_head = Term->key_tail = 0;
-
- /* Success */
- return (0);
+ Term->m_key_queue.clear();
}
@@ -1347,22 +1540,13 @@ errr Term_flush(void)
/*
* Add a keypress to the "queue"
*/
-errr Term_keypress(int k)
+void Term_keypress(int k)
{
- /* Hack -- Refuse to enqueue non-keys */
- if (!k) return ( -1);
+ /* Ignore non-keys */
+ if (!k) return;
- /* Store the char, advance the queue */
- Term->key_queue[Term->key_head++] = k;
-
- /* Circular queue, handle wrap */
- if (Term->key_head == Term->key_size) Term->key_head = 0;
-
- /* Success (unless overflow) */
- if (Term->key_head != Term->key_tail) return (0);
-
- /* Problem */
- return (1);
+ /* Push */
+ Term->m_key_queue.push_back(k);
}
@@ -1374,23 +1558,11 @@ errr Term_key_push(int k)
/* Hack -- Refuse to enqueue non-keys */
if (!k) return ( -1);
- /* Hack -- Overflow may induce circular queue */
- if (Term->key_tail == 0) Term->key_tail = Term->key_size;
-
- /* Back up, Store the char */
- Term->key_queue[--Term->key_tail] = k;
-
- /* Success (unless overflow) */
- if (Term->key_head != Term->key_tail) return (0);
-
- /* Problem */
- return (1);
+ /* Push */
+ return push_result_to_errr(Term->m_key_queue.push_front(k));
}
-
-
-
/*
* Check for a pending keypress on the key queue.
*
@@ -1401,22 +1573,24 @@ errr Term_key_push(int k)
*
* Remove the keypress if "take" is true.
*/
-errr Term_inkey(char *ch, bool_ wait, bool_ take)
+errr Term_inkey(char *ch, bool wait, bool take)
{
+ auto &key_queue = Term->m_key_queue;
+
/* Assume no key */
(*ch) = '\0';
/* Process queued UI events */
- Term_xtra(TERM_XTRA_BORED, 0);
+ Term->m_frontend->process_queued_events();
/* Wait */
if (wait)
{
/* Process pending events while necessary */
- while (Term->key_head == Term->key_tail)
+ while (key_queue.empty())
{
/* Process events (wait for one) */
- Term_xtra(TERM_XTRA_EVENT, TRUE);
+ Term->m_frontend->process_event(true);
}
}
@@ -1424,28 +1598,34 @@ errr Term_inkey(char *ch, bool_ wait, bool_ take)
else
{
/* Process pending events if necessary */
- if (Term->key_head == Term->key_tail)
+ if (key_queue.empty())
{
/* Process events (do not wait) */
- Term_xtra(TERM_XTRA_EVENT, FALSE);
+ Term->m_frontend->process_event(false);
}
}
/* No keys are ready */
- if (Term->key_head == Term->key_tail) return (1);
+ if (key_queue.empty())
+ {
+ return (1);
+ }
/* Extract the next keypress */
- (*ch) = Term->key_queue[Term->key_tail];
-
- /* If requested, advance the queue, wrap around if necessary */
- if (take && (++Term->key_tail == Term->key_size)) Term->key_tail = 0;
+ if (take)
+ {
+ *ch = key_queue.pop_front();
+ }
+ else
+ {
+ *ch = key_queue.front();
+ }
/* Success */
return (0);
}
-
/*** Extra routines ***/
@@ -1454,7 +1634,7 @@ errr Term_inkey(char *ch, bool_ wait, bool_ take)
*
* Every "Term_save()" should match exactly one "Term_load()"
*/
-errr Term_save(void)
+void Term_save()
{
int w = Term->wid;
int h = Term->hgt;
@@ -1462,37 +1642,24 @@ errr Term_save(void)
/* Create */
if (!Term->mem)
{
- /* Allocate window */
- Term->mem = safe_calloc(1, sizeof(struct term_win));
-
- /* Initialize window */
- term_win_init(Term->mem, w, h);
+ Term->mem = std::make_unique<term_win>(w, h);
}
/* Grab */
- term_win_copy(Term->mem, Term->scr, w, h);
-
- /* Success */
- return (0);
+ Term->mem->copy_from(Term->scr, w, h);
}
/*
* Same as before but can save more than once
*/
-term_win* Term_save_to(void)
+term_win* Term_save_to()
{
int w = Term->wid;
int h = Term->hgt;
- term_win *save;
-
- /* Allocate window */
- save = safe_calloc(1, sizeof(struct term_win));
- /* Initialize window */
- term_win_init(save, w, h);
-
- /* Grab */
- term_win_copy(save, Term->scr, w, h);
+ /* Copy */
+ auto save = new term_win(w, h);
+ save->copy_from(Term->scr, w, h);
/* Success */
return (save);
@@ -1503,28 +1670,22 @@ term_win* Term_save_to(void)
*
* Every "Term_save()" should match exactly one "Term_load()"
*/
-errr Term_load(void)
+void Term_load()
{
- int y;
-
int w = Term->wid;
int h = Term->hgt;
- /* Create */
+ /* Create empty contents if nothing was actually saved previously */
if (!Term->mem)
{
- /* Allocate window */
- Term->mem = safe_calloc(1, sizeof(struct term_win));
-
- /* Initialize window */
- term_win_init(Term->mem, w, h);
+ Term->mem = std::make_unique<term_win>(w, h);
}
/* Load */
- term_win_copy(Term->scr, Term->mem, w, h);
+ Term->scr->copy_from(Term->mem, w, h);
/* Assume change */
- for (y = 0; y < h; y++)
+ for (int y = 0; y < h; y++)
{
/* Assume change */
Term->x1[y] = 0;
@@ -1534,15 +1695,12 @@ errr Term_load(void)
/* Assume change */
Term->y1 = 0;
Term->y2 = h - 1;
-
- /* Success */
- return (0);
}
/*
* Same as previous but allow to save more than one
*/
-errr Term_load_from(term_win *save)
+void Term_load_from(term_win *save)
{
int y;
@@ -1552,11 +1710,11 @@ errr Term_load_from(term_win *save)
/* Create */
if (!save)
{
- return (1);
+ return;
}
/* Load */
- term_win_copy(Term->scr, save, w, h);
+ Term->scr->copy_from(save, w, h);
/* Assume change */
for (y = 0; y < h; y++)
@@ -1571,128 +1729,75 @@ errr Term_load_from(term_win *save)
Term->y2 = h - 1;
/* Free is requested */
- free(save);
-
- /* Success */
- return (0);
+ delete save;
}
/*
* React to a new physical window size.
*/
-errr Term_resize(int w, int h)
+void Term_resize(int w, int h)
{
int i;
int wid, hgt;
- byte *hold_x1;
- byte *hold_x2;
-
- term_win *hold_old;
- term_win *hold_scr;
- term_win *hold_mem;
-
/* Ignore illegal changes */
- if ((w < 1) || (h < 1)) return ( -1);
-
+ if ((w < 1) || (h < 1))
+ {
+ return;
+ }
/* Ignore non-changes */
- if ((Term->wid == w) && (Term->hgt == h)) return (1);
+ if ((Term->wid == w) && (Term->hgt == h))
+ {
+ return;
+ }
/* Minimum dimensions */
- wid = MIN(Term->wid, w);
- hgt = MIN(Term->hgt, h);
-
- /* Save scanners */
- hold_x1 = Term->x1;
- hold_x2 = Term->x2;
-
- /* Save old window */
- hold_old = Term->old;
-
- /* Save old window */
- hold_scr = Term->scr;
-
- /* Save old window */
- hold_mem = Term->mem;
-
- /* Create new scanners */
- Term->x1 = safe_calloc(h, sizeof(byte));
- Term->x2 = safe_calloc(h, sizeof(byte));
+ wid = std::min<int>(Term->wid, w);
+ hgt = std::min<int>(Term->hgt, h);
/* Create new window */
- Term->old = safe_calloc(1, sizeof(struct term_win));
-
- /* Initialize new window */
- term_win_init(Term->old, w, h);
+ {
+ auto hold_old = std::move(Term->old);
+ Term->old = std::make_unique<term_win>(w, h);
+ Term->old->copy_from(hold_old, wid, hgt);
- /* Save the contents */
- term_win_copy(Term->old, hold_old, wid, hgt);
+ /* Illegal cursor? */
+ if (Term->old->cx >= w) Term->old->cu = true;
+ if (Term->old->cy >= h) Term->old->cu = true;
+ }
/* Create new window */
- Term->scr = safe_calloc(1, sizeof(struct term_win));
-
- /* Initialize new window */
- term_win_init(Term->scr, w, h);
-
- /* Save the contents */
- term_win_copy(Term->scr, hold_scr, wid, hgt);
-
- /* If needed */
- if (hold_mem)
{
- /* Create new window */
- Term->mem = safe_calloc(1, sizeof(struct term_win));
+ auto hold_scr = std::move(Term->scr);
+ Term->scr = std::make_unique<term_win>(w, h);
+ Term->scr->copy_from(hold_scr, wid, hgt);
- /* Initialize new window */
- term_win_init(Term->mem, w, h);
-
- /* Save the contents */
- term_win_copy(Term->mem, hold_mem, wid, hgt);
+ /* Illegal cursor? */
+ if (Term->scr->cx >= w) Term->scr->cu = true;
+ if (Term->scr->cy >= h) Term->scr->cu = true;
}
- /* Free some arrays */
- free(hold_x1);
- hold_x1 = NULL;
- free(hold_x2);
- hold_x2 = NULL;
-
- /* Nuke */
- term_win_nuke(hold_old, Term->wid, Term->hgt);
-
- /* Kill */
- free(hold_old);
- hold_old = NULL;
-
- /* Illegal cursor */
- if (Term->old->cx >= w) Term->old->cu = 1;
- if (Term->old->cy >= h) Term->old->cu = 1;
-
- /* Nuke */
- term_win_nuke(hold_scr, Term->wid, Term->hgt);
-
- /* Kill */
- free(hold_scr);
- hold_scr = NULL;
-
- /* Illegal cursor */
- if (Term->scr->cx >= w) Term->scr->cu = 1;
- if (Term->scr->cy >= h) Term->scr->cu = 1;
-
- /* If needed */
- if (hold_mem)
+ /* Create new window */
+ if (Term->mem)
{
- /* Nuke */
- term_win_nuke(hold_mem, Term->wid, Term->hgt);
+ auto hold_mem = std::move(Term->mem);
+ Term->mem = std::make_unique<term_win>(w, h);
+ Term->mem->copy_from(hold_mem, wid, hgt);
- /* Kill */
- free(hold_mem);
- hold_mem = NULL;
+ /* Illegal cursor? */
+ if (Term->mem->cx >= w) Term->mem->cu = true;
+ if (Term->mem->cy >= h) Term->mem->cu = true;
+ }
- /* Illegal cursor */
- if (Term->mem->cx >= w) Term->mem->cu = 1;
- if (Term->mem->cy >= h) Term->mem->cu = 1;
+ /* Resize scanners */
+ Term->x1.resize(h);
+ Term->x2.resize(h);
+ for (i = 0; i < h; i++)
+ {
+ Term->x1[i] = 0;
+ Term->x2[i] = w - 1;
}
/* Save new size */
@@ -1700,28 +1805,17 @@ errr Term_resize(int w, int h)
Term->hgt = h;
/* Force "total erase" */
- Term->total_erase = TRUE;
-
- /* Assume change */
- for (i = 0; i < h; i++)
- {
- /* Assume change */
- Term->x1[i] = 0;
- Term->x2[i] = w - 1;
- }
+ Term->total_erase = true;
/* Assume change */
Term->y1 = 0;
Term->y2 = h - 1;
/* Execute the "resize_hook" hook, if available */
- if (Term->resize_hook)
+ if (Term->m_resize_hook)
{
- Term->resize_hook();
+ Term->m_resize_hook();
}
-
- /* Success */
- return (0);
}
@@ -1735,98 +1829,57 @@ errr Term_resize(int w, int h)
* To "create" a valid "term", one should do "term_init(t)", then
* set the various flags and hooks, and then do "Term_activate(t)".
*/
-errr Term_activate(term *t)
+void Term_activate(term *t)
{
- /* Hack -- already done */
- if (Term == t) return (1);
-
- /* Deactivate the old Term */
- if (Term) Term_xtra(TERM_XTRA_LEVEL, 0);
+ /* No change? */
+ if (Term == t)
+ {
+ return;
+ }
/* Hack -- Call the special "init" hook */
if (t && !t->active_flag)
{
- /* Call the "init" hook */
- if (t->init_hook) (*t->init_hook)(t);
+ t->m_frontend->init();
/* Remember */
- t->active_flag = TRUE;
+ t->active_flag = true;
/* Assume mapped */
- t->mapped_flag = TRUE;
+ t->mapped_flag = true;
}
/* Remember the Term */
Term = t;
-
- /* Activate the new Term */
- if (Term) Term_xtra(TERM_XTRA_LEVEL, 1);
-
- /* Success */
- return (0);
}
+void Term_xtra_react()
+{
+ Term->m_frontend->react();
+}
-/*
- * Nuke a term
+/**
+ * Set the current terminal "mapped" flag.
*/
-errr term_nuke(term *t)
+void Term_mapped()
{
- int w = t->wid;
- int h = t->hgt;
-
- /* Hack -- Call the special "nuke" hook */
- if (t->active_flag)
- {
- /* Call the "nuke" hook */
- if (t->nuke_hook) (*t->nuke_hook)(t);
-
- /* Remember */
- t->active_flag = FALSE;
-
- /* Assume not mapped */
- t->mapped_flag = FALSE;
- }
-
-
- /* Nuke "displayed" */
- term_win_nuke(t->old, w, h);
-
- /* Kill "displayed" */
- free(t->old);
- t->old = NULL;
-
- /* Nuke "requested" */
- term_win_nuke(t->scr, w, h);
-
- /* Kill "requested" */
- free(t->scr);
- t->scr = NULL;
+ Term->mapped_flag = true;
+}
- /* If needed */
- if (t->mem)
- {
- /* Nuke "memorized" */
- term_win_nuke(t->mem, w, h);
- /* Kill "memorized" */
- free(t->mem);
- t->mem = NULL;
- }
-
- /* Free some arrays */
- free(t->x1);
- t->x1 = NULL;
- free(t->x2);
- t->x2 = NULL;
+/**
+ * Unset the current terminal "mapped" flag.
+ */
+void Term_unmapped()
+{
+ Term->mapped_flag = false;
+}
- /* Free the input queue */
- free(t->key_queue);
- t->key_queue = NULL;
- /* Success */
- return (0);
+void Term_rename_main_win(std::string_view name)
+{
+ Term->m_frontend->rename_main_window(name);
}
@@ -1836,63 +1889,23 @@ errr term_nuke(term *t)
* By default, the cursor starts out "invisible"
* By default, we "erase" using "black spaces"
*/
-errr term_init(term *t, int w, int h, int k)
+term *term_init(int w, int h, int k, std::shared_ptr<Frontend> user_interface)
{
- int y;
-
- /* Wipe it */
- memset(t, 0, sizeof(term));
-
-
- /* Prepare the input queue */
- t->key_head = t->key_tail = 0;
-
- /* Determine the input queue size */
- t->key_size = k;
-
- /* Allocate the input queue */
- t->key_queue = safe_calloc(t->key_size, sizeof(char));
-
-
- /* Save the size */
- t->wid = w;
- t->hgt = h;
-
- /* Allocate change arrays */
- t->x1 = safe_calloc(h, sizeof(byte));
- t->x2 = safe_calloc(h, sizeof(byte));
-
-
- /* Allocate "displayed" */
- t->old = safe_calloc(1, sizeof(struct term_win));
-
- /* Initialize "displayed" */
- term_win_init(t->old, w, h);
-
-
- /* Allocate "requested" */
- t->scr = safe_calloc(1, sizeof(struct term_win));
-
- /* Initialize "requested" */
- term_win_init(t->scr, w, h);
-
-
- /* Assume change */
- for (y = 0; y < h; y++)
- {
- /* Assume change */
- t->x1[y] = 0;
- t->x2[y] = w - 1;
- }
-
- /* Assume change */
- t->y1 = 0;
- t->y2 = h - 1;
-
- /* Force "total erase" */
- t->total_erase = TRUE;
+ return new term(w, h, k, user_interface);
+}
+/*
+ * Nuke a term
+ */
+void term_nuke(term *t)
+{
+ delete t;
+}
- /* Success */
- return (0);
+/**
+ * Set the function to call when terminal is resized.
+ */
+void term_set_resize_hook(term *t, std::function<void ()> f)
+{
+ t->m_resize_hook = f;
}
diff --git a/src/z-term.h b/src/z-term.h
deleted file mode 100644
index 92f09577..00000000
--- a/src/z-term.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/* File: z-term.h */
-
-/*
- * Copyright (c) 1997 Ben Harrison
- *
- * This software may be copied and distributed for educational, research,
- * and not for profit purposes provided that this copyright and statement
- * are included in all such copies.
- */
-
-#ifndef INCLUDED_Z_TERM_H
-#define INCLUDED_Z_TERM_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "h-basic.h"
-
-/*
- * A term_win is a "window" for a Term
- *
- * - Cursor Useless/Visible codes
- * - Cursor Location (see "Useless")
- *
- * - Array[h] -- Access to the attribute array
- * - Array[h] -- Access to the character array
- *
- * - Array[h*w] -- Attribute array
- * - Array[h*w] -- Character array
- *
- * Note that the attr/char pair at (x,y) is a[y][x]/c[y][x]
- * and that the row of attr/chars at (0,y) is a[y]/c[y]
- */
-
-typedef struct term_win term_win;
-
-struct term_win
-{
- bool_ cu, cv;
- byte cx, cy;
-
- byte **a;
- char **c;
-
- byte *va;
- char *vc;
-
-};
-
-
-
-/*
- * An actual "term" structure
- *
- * - Extra "data" info (used by implementation)
- *
- *
- * - Flag "active_flag"
- * This "term" is "active"
- *
- * - Flag "mapped_flag"
- * This "term" is "mapped"
- *
- * - Flag "total_erase"
- * This "term" should be fully erased
- *
- * - Flag "icky_corner"
- * This "term" has an "icky" corner grid
- *
- * - Flag "soft_cursor"
- * This "term" uses a "software" cursor
- *
- *
- *
- *
- * - Ignore this pointer
- *
- * - Keypress Queue -- various data
- *
- * - Keypress Queue -- pending keys
- *
- *
- * - Window Width (max 255)
- * - Window Height (max 255)
- *
- * - Minimum modified row
- * - Maximum modified row
- *
- * - Minimum modified column (per row)
- * - Maximum modified column (per row)
- *
- *
- * - Displayed screen image
- * - Requested screen image
- *
- * - Temporary screen image
- * - Memorized screen image
- *
- *
- * - Hook for init-ing the term
- * - Hook for nuke-ing the term
- *
- * - Hook for extra actions
- *
- * - Hook for placing the cursor
- *
- * - Hook for drawing a string of chars using an attr
- *
- * - Hook for drawing a sequence of special attr/char pairs
- */
-
-typedef struct term term;
-
-struct term
-{
- vptr data;
-
- bool_ active_flag;
- bool_ mapped_flag;
- bool_ total_erase;
- bool_ icky_corner;
- bool_ soft_cursor;
-
- char *key_queue;
- u16b key_head;
- u16b key_tail;
- u16b key_size;
-
- byte wid;
- byte hgt;
-
- byte y1;
- byte y2;
-
- byte *x1;
- byte *x2;
-
- term_win *old;
- term_win *scr;
-
- term_win *mem;
-
- void (*init_hook)(term *t);
- void (*nuke_hook)(term *t);
-
- errr (*xtra_hook)(int n, int v);
-
- errr (*curs_hook)(int x, int y);
-
- errr (*text_hook)(int x, int y, int n, byte a, cptr s);
-
- void (*resize_hook)();
-
-};
-
-
-
-/*** Color constants ***/
-
-
-/*
- * Angband "attributes" (with symbols, and base (R,G,B) codes)
- *
- * The "(R,G,B)" codes are given in "fourths" of the "maximal" value,
- * and should "gamma corrected" on most (non-Macintosh) machines.
- */
-#define TERM_DARK 0 /* 'd' */ /* 0,0,0 */
-#define TERM_WHITE 1 /* 'w' */ /* 4,4,4 */
-#define TERM_SLATE 2 /* 's' */ /* 2,2,2 */
-#define TERM_ORANGE 3 /* 'o' */ /* 4,2,0 */
-#define TERM_RED 4 /* 'r' */ /* 3,0,0 */
-#define TERM_GREEN 5 /* 'g' */ /* 0,2,1 */
-#define TERM_BLUE 6 /* 'b' */ /* 0,0,4 */
-#define TERM_UMBER 7 /* 'u' */ /* 2,1,0 */
-#define TERM_L_DARK 8 /* 'D' */ /* 1,1,1 */
-#define TERM_L_WHITE 9 /* 'W' */ /* 3,3,3 */
-#define TERM_VIOLET 10 /* 'v' */ /* 4,0,4 */
-#define TERM_YELLOW 11 /* 'y' */ /* 4,4,0 */
-#define TERM_L_RED 12 /* 'R' */ /* 4,0,0 */
-#define TERM_L_GREEN 13 /* 'G' */ /* 0,4,0 */
-#define TERM_L_BLUE 14 /* 'B' */ /* 0,4,4 */
-#define TERM_L_UMBER 15 /* 'U' */ /* 3,2,1 */
-
-
-
-/**** Available Constants ****/
-
-
-/*
- * Definitions for the "actions" of "Term_xtra()"
- *
- * These values may be used as the first parameter of "Term_xtra()",
- * with the second parameter depending on the "action" itself. Many
- * of the actions shown below are optional on at least one platform.
- *
- * The "TERM_XTRA_EVENT" action uses "v" to "wait" for an event
- * The "TERM_XTRA_SHAPE" action uses "v" to "show" the cursor
- * The "TERM_XTRA_ALIVE" action uses "v" to "activate" (or "close")
- * The "TERM_XTRA_LEVEL" action uses "v" to "resume" (or "suspend")
- *
- * The other actions do not need a "v" code, so "zero" is used.
- */
-#define TERM_XTRA_EVENT 1 /* Process some pending events */
-#define TERM_XTRA_FLUSH 2 /* Flush all pending events */
-#define TERM_XTRA_CLEAR 3 /* Clear the entire window */
-#define TERM_XTRA_SHAPE 4 /* Set cursor shape (optional) */
-#define TERM_XTRA_FRESH 6 /* Flush all rows (optional) */
-#define TERM_XTRA_NOISE 7 /* Make a noise (optional) */
-#define TERM_XTRA_BORED 9 /* Handle stuff when bored (optional) */
-#define TERM_XTRA_REACT 10 /* React to global changes (optional) */
-#define TERM_XTRA_ALIVE 11 /* Change the "hard" level (optional) */
-#define TERM_XTRA_LEVEL 12 /* Change the "soft" level (optional) */
-#define TERM_XTRA_RENAME_MAIN_WIN 16 /* Rename the main game window */
-
-
-/**** Available Variables ****/
-
-extern term *Term;
-
-/**** Available Functions ****/
-
-errr Term_xtra(int n, int v);
-
-void Term_queue_char(int x, int y, byte a, char c);
-void Term_queue_chars(int x, int y, int n, byte a, cptr s);
-
-errr Term_fresh();
-errr Term_set_cursor(int v);
-errr Term_gotoxy(int x, int y);
-errr Term_draw(int x, int y, byte a, char c);
-errr Term_addch(byte a, char c);
-errr Term_addstr(int n, byte a, cptr s);
-errr Term_putch(int x, int y, byte a, char c);
-errr Term_putstr(int x, int y, int n, byte a, cptr s);
-errr Term_erase(int x, int y, int n);
-errr Term_clear();
-errr Term_redraw();
-errr Term_redraw_section(int x1, int y1, int x2, int y2);
-void Term_bell();
-
-errr Term_get_cursor(int *v);
-errr Term_get_size(int *w, int *h);
-errr Term_locate(int *x, int *y);
-errr Term_what(int x, int y, byte *a, char *c);
-
-errr Term_flush();
-errr Term_keypress(int k);
-errr Term_key_push(int k);
-errr Term_inkey(char *ch, bool_ wait, bool_ take);
-
-errr Term_save();
-term_win* Term_save_to();
-errr Term_load();
-errr Term_load_from(term_win *save);
-
-errr Term_resize(int w, int h);
-
-errr Term_activate(term *t);
-
-errr term_nuke(term *t);
-errr term_init(term *t, int w, int h, int k);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif
-
diff --git a/src/z-term.hpp b/src/z-term.hpp
new file mode 100644
index 00000000..24077c16
--- /dev/null
+++ b/src/z-term.hpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1997 Ben Harrison
+ *
+ * This software may be copied and distributed for educational, research,
+ * and not for profit purposes provided that this copyright and statement
+ * are included in all such copies.
+ */
+
+#pragma once
+
+#include "h-basic.hpp"
+#include "frontend_fwd.hpp"
+
+#include <functional>
+#include <memory>
+#include <string_view>
+
+typedef struct term_win term_win;
+
+struct term_win; // Opaque
+
+typedef struct term term;
+
+struct term; // Opaque
+
+/*** Color constants ***/
+
+
+/*
+ * Angband "attributes" (with symbols, and base (R,G,B) codes)
+ *
+ * The "(R,G,B)" codes are given in "fourths" of the "maximal" value,
+ * and should "gamma corrected" on most (non-Macintosh) machines.
+ */
+#define TERM_DARK 0 /* 'd' */ /* 0,0,0 */
+#define TERM_WHITE 1 /* 'w' */ /* 4,4,4 */
+#define TERM_SLATE 2 /* 's' */ /* 2,2,2 */
+#define TERM_ORANGE 3 /* 'o' */ /* 4,2,0 */
+#define TERM_RED 4 /* 'r' */ /* 3,0,0 */
+#define TERM_GREEN 5 /* 'g' */ /* 0,2,1 */
+#define TERM_BLUE 6 /* 'b' */ /* 0,0,4 */
+#define TERM_UMBER 7 /* 'u' */ /* 2,1,0 */
+#define TERM_L_DARK 8 /* 'D' */ /* 1,1,1 */
+#define TERM_L_WHITE 9 /* 'W' */ /* 3,3,3 */
+#define TERM_VIOLET 10 /* 'v' */ /* 4,0,4 */
+#define TERM_YELLOW 11 /* 'y' */ /* 4,4,0 */
+#define TERM_L_RED 12 /* 'R' */ /* 4,0,0 */
+#define TERM_L_GREEN 13 /* 'G' */ /* 0,4,0 */
+#define TERM_L_BLUE 14 /* 'B' */ /* 0,4,4 */
+#define TERM_L_UMBER 15 /* 'U' */ /* 3,2,1 */
+
+
+
+/**** Available Variables ****/
+
+extern term *Term;
+
+/**** Available Functions ****/
+
+void Term_queue_char(int x, int y, byte a, char c);
+
+void Term_fresh();
+errr Term_gotoxy(int x, int y);
+void Term_draw(int x, int y, byte a, char c);
+void Term_addch(byte a, char c);
+errr Term_addstr(int n, byte a, const char *s);
+void Term_putch(int x, int y, byte a, char c);
+void Term_putstr(int x, int y, int n, byte a, const char *s);
+void Term_erase(int x, int y, int n);
+void Term_clear();
+void Term_redraw();
+void Term_redraw_section(int x1, int y1, int x2, int y2);
+void Term_bell();
+
+void Term_with_saved_cursor_flags(std::function<void ()> callback);
+void Term_with_saved_cursor_visbility(std::function<void ()> callback);
+void Term_with_active(term *t, std::function<void ()> callback);
+
+void Term_get_size(int *w, int *h);
+void Term_locate(int *x, int *y);
+void Term_what(int x, int y, byte *a, char *c);
+
+void Term_show_cursor();
+void Term_hide_cursor();
+
+void Term_flush();
+void Term_keypress(int k);
+errr Term_key_push(int k);
+errr Term_inkey(char *ch, bool wait, bool take);
+
+void Term_save();
+term_win* Term_save_to();
+void Term_load();
+void Term_load_from(term_win *save);
+
+void Term_resize(int w, int h);
+
+void Term_activate(term *t);
+
+void Term_xtra_react();
+
+void Term_mapped();
+void Term_unmapped();
+void Term_rename_main_win(std::string_view);
+
+term *term_init(int w, int h, int k, std::shared_ptr<Frontend> user_interface);
+void term_nuke(term *t);
+void term_set_resize_hook(term *t, std::function<void ()> f);
diff --git a/src/z-util.c b/src/z-util.cc
index 0304a1da..6ec1373f 100644
--- a/src/z-util.c
+++ b/src/z-util.cc
@@ -1,39 +1,9 @@
-/* File: z-util.c */
+#include "z-util.hpp"
-/* Purpose: Low level utilities -BEN- */
-
-#include "z-util.h"
-
-#include <assert.h>
-
-
-/*
- * Determine if string "t" is equal to string "t"
- */
-bool_ streq(cptr a, cptr b)
-{
- if ((a == NULL) && (b == NULL)) { return TRUE; }
- if (a == NULL) { return FALSE; }
- if (b == NULL) { return FALSE; }
- return (!strcmp(a, b));
-}
-
-
-/*
- * Determine if string "t" is a suffix of string "s"
- */
-bool_ suffix(cptr s, cptr t)
-{
- int tlen = strlen(t);
- int slen = strlen(s);
-
- /* Check for incompatible lengths */
- if (tlen > slen) return (FALSE);
-
- /* Compare "t" to the end of "s" */
- return (!strcmp(s + slen - tlen, t));
-}
+#include <boost/algorithm/string/predicate.hpp>
+#include <cassert>
+using boost::algorithm::equals;
/**
* Captialize letter
@@ -41,7 +11,7 @@ bool_ suffix(cptr s, cptr t)
void capitalize(char *s)
{
char *p = s;
- assert(s != NULL);
+ assert(s != nullptr);
for (; *p; p++)
{
@@ -61,13 +31,13 @@ void capitalize(char *s)
/*
* Redefinable "plog" action
*/
-void (*plog_aux)(cptr) = NULL;
+void (*plog_aux)(const char *) = nullptr;
/*
* Print (or log) a "warning" message (ala "perror()")
* Note the use of the (optional) "plog_aux" hook.
*/
-void plog(cptr str)
+void plog(const char *str)
{
/* Use the "alternative" function if possible */
if (plog_aux) (*plog_aux)(str);
@@ -81,7 +51,7 @@ void plog(cptr str)
/*
* Redefinable "quit" action
*/
-void (*quit_aux)(cptr) = NULL;
+void (*quit_aux)(const char *) = nullptr;
/*
* Exit (ala "exit()"). If 'str' is NULL, do "exit(0)".
@@ -89,7 +59,7 @@ void (*quit_aux)(cptr) = NULL;
* Otherwise, plog() 'str' and exit with an error code of -1.
* But always use 'quit_aux', if set, before anything else.
*/
-void quit(cptr str)
+void quit(const char *str)
{
/* Attempt to use the aux function */
if (quit_aux) (*quit_aux)(str);
diff --git a/src/z-util.h b/src/z-util.h
deleted file mode 100644
index d2fa79dc..00000000
--- a/src/z-util.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "h-basic.h"
-
-
-/*
- * Extremely basic stuff, like "streq()".
- */
-
-
-/* Aux functions */
-extern void (*plog_aux)(cptr);
-extern void (*quit_aux)(cptr);
-
-
-/**** Available Functions ****/
-
-
-/* Test equality, prefix, suffix */
-bool_ streq(cptr s, cptr t);
-bool_ prefix(cptr s, cptr t);
-bool_ suffix(cptr s, cptr t);
-
-
-/* Capitalize the first letter of string. Ignores whitespace at the start of string. */
-void capitalize(char *s);
-
-/* Print an error message */
-void plog(cptr str);
-
-/* Exit, with optional message */
-void quit(cptr str);
-
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
diff --git a/src/z-util.hpp b/src/z-util.hpp
new file mode 100644
index 00000000..e6225ea4
--- /dev/null
+++ b/src/z-util.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+/* Aux functions */
+extern void (*plog_aux)(const char *);
+extern void (*quit_aux)(const char *);
+
+/* Print an error message */
+void plog(const char *str);
+
+/* Exit, with optional message */
+void quit(const char *str);
+
+/**
+ * Capitalize the first letter of string. Ignores whitespace
+ * at the start of string.
+ */
+void capitalize(char *s);
diff --git a/tests/arbitrary/boost_optional.cc b/tests/arbitrary/boost_optional.cc
new file mode 100644
index 00000000..36b0b770
--- /dev/null
+++ b/tests/arbitrary/boost_optional.cc
@@ -0,0 +1 @@
+#include "boost_optional.hpp"
diff --git a/tests/arbitrary/boost_optional.hpp b/tests/arbitrary/boost_optional.hpp
new file mode 100644
index 00000000..445e8aca
--- /dev/null
+++ b/tests/arbitrary/boost_optional.hpp
@@ -0,0 +1,60 @@
+#pragma once
+
+#include <boost/optional.hpp>
+#include <boost/optional/optional_io.hpp>
+#include <cppqc/Arbitrary.h>
+
+namespace cppqc {
+
+template<typename T>
+boost::optional<T> arbitraryBoostOptional(RngEngine &rng, std::size_t size)
+{
+ std::uniform_int_distribution<> distribution(0, 4);
+
+ if (distribution(rng) == 0)
+ {
+ return boost::none;
+ }
+ else
+ {
+ return Arbitrary<T>::unGen(rng, size);
+ }
+}
+
+template<typename T>
+std::vector<boost::optional<T>> shrinkBoostOptional(boost::optional<T> shrinkInput)
+{
+ std::vector<boost::optional<T>> result;
+
+ if (shrinkInput)
+ {
+ result.push_back(boost::none);
+
+ for (auto const &t: Arbitrary<T>::shrink(*shrinkInput))
+ {
+ result.push_back(t);
+ }
+ }
+
+ return result;
+}
+
+template <typename T>
+class ArbitraryImpl<boost::optional<T>> {
+
+public:
+ static const typename Arbitrary<boost::optional<T>>::unGenType unGen;
+
+ static const typename Arbitrary<boost::optional<T>>::shrinkType shrink;
+
+};
+
+template <typename T>
+const typename Arbitrary<boost::optional<T>>::unGenType
+ArbitraryImpl<boost::optional<T>>::unGen = arbitraryBoostOptional<T>;
+
+template <typename T>
+const typename Arbitrary<boost::optional<T>>::shrinkType
+ArbitraryImpl<boost::optional<T>>::shrink = shrinkBoostOptional<T>;
+
+} // namespace cppqc
diff --git a/vendor/CppQuickCheck b/vendor/CppQuickCheck
new file mode 120000
index 00000000..693f84ae
--- /dev/null
+++ b/vendor/CppQuickCheck
@@ -0,0 +1 @@
+CppQuickCheck-2018-03-28 \ No newline at end of file
diff --git a/vendor/CppQuickCheck-2018-03-28/.travis.yml b/vendor/CppQuickCheck-2018-03-28/.travis.yml
new file mode 100644
index 00000000..46fc72ff
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/.travis.yml
@@ -0,0 +1,36 @@
+language: cpp
+
+sudo: required
+dist: trusty
+
+compiler:
+ - gcc
+ - clang
+
+os:
+- linux
+
+# source: https://github.com/OpenLightingProject/ola/blob/master/.travis.yml
+before_install:
+ - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
+ - sudo add-apt-repository ppa:h-rayflood/gcc-upper -y
+ - sudo add-apt-repository "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.8 main" -y
+ - wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -
+ - sudo apt-get update
+
+ - if [ "$CXX" = "g++" ]; then sudo apt-get install g++-4.9; fi
+ - if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi
+#Remove the old g++/gcc to ensure we're using the latest ones
+ - if [ "$CXX" = "g++-4.9" ]; then sudo rm /usr/bin/g++; sudo rm /usr/bin/gcc; fi
+
+ - if [ "$CXX" = "clang++" ]; then sudo apt-get install --force-yes clang-3.8; fi
+ - if [ "$CXX" = "clang++" ]; then export CXX="clang++-3.8" CC="clang-3.8"; fi
+#Remove the old clang to ensure we're using the latest ones
+
+#Report the compiler version
+ - $CXX --version
+
+ - sudo apt-get update
+ - sudo apt-get install libboost-thread-dev libboost-system-dev
+
+script: mkdir build && cd build && cmake .. && make && ./all-catch-tests
diff --git a/vendor/CppQuickCheck-2018-03-28/CMakeLists.txt b/vendor/CppQuickCheck-2018-03-28/CMakeLists.txt
new file mode 100644
index 00000000..c837c1e3
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/CMakeLists.txt
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 2.6)
+project(CppQuickCheck)
+set(CMAKE_CXX_FLAGS "-O3 -g -Wall -std=c++11")
+
+find_package(Boost REQUIRED)
+include_directories(${Boost_INCLUDE_DIR})
+
+include_directories("${PROJECT_SOURCE_DIR}/include")
+
+add_subdirectory(examples)
+
+add_library(cppqc SHARED src/Arbitrary.cpp)
+
+install(DIRECTORY "include/" DESTINATION "include"
+ PATTERN ".*" EXCLUDE)
+install(TARGETS cppqc DESTINATION "lib")
+
+# "catch" based unit tests
+enable_testing()
+add_executable(
+ all-catch-tests
+ test/catch-main.cpp
+ test/shrink-explosion-protection.cpp
+ test/compact-check-tests.cpp
+ test/functional-tests.cpp)
+target_link_libraries(all-catch-tests cppqc)
+add_test(all-catch-tests all-catch-tests)
+
+# workaround to force cmake to build test executable before running the test
+# (source: http://stackoverflow.com/a/736838/783510)
+add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}
+ DEPENDS all-catch-tests)
diff --git a/vendor/CppQuickCheck-2018-03-28/COPYING b/vendor/CppQuickCheck-2018-03-28/COPYING
new file mode 100644
index 00000000..384456ae
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/COPYING
@@ -0,0 +1,23 @@
+Copyright (c) 2010, Gregory Rogers All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/vendor/CppQuickCheck-2018-03-28/INSTALL b/vendor/CppQuickCheck-2018-03-28/INSTALL
new file mode 100644
index 00000000..45845dac
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/INSTALL
@@ -0,0 +1,11 @@
+CppQuickCheck is built using the CMake tool: http://www.cmake.org so you must have that installed on your system. In addition, the library uses significant functionality from the popular BOOST library: http://www.boost.org so you must have that installed to be able to use CppQuickCheck.
+
+To build and install the library, invoke the following commands:
+
+ cmake .
+ make
+ sudo make install
+
+This will install CppQuickCheck into the default install location (usually /usr/local/include). See the cmake homepage for more details on different options.
+
+CppQuickCheck is a header only library. You do not need to link any libraries to use it. When building, it will build the examples but these will not be installed.
diff --git a/vendor/CppQuickCheck-2018-03-28/LICENSE b/vendor/CppQuickCheck-2018-03-28/LICENSE
new file mode 100644
index 00000000..444b683c
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/LICENSE
@@ -0,0 +1,21 @@
+Copyright (c) 2010, Gregory Rogers All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/CppQuickCheck-2018-03-28/README.md b/vendor/CppQuickCheck-2018-03-28/README.md
new file mode 100644
index 00000000..d16f89e0
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/README.md
@@ -0,0 +1,74 @@
+***CppQuickCheck***
+
+## ABOUT
+
+CppQuickCheck is a library for automated testing of C++ code. You provide a
+specification how your code is supposed to behave through *properties* and
+CppQuickCheck will generate a large number of random test cases that attempt to
+prove or disprove the properties. The specifications are written in pure C++
+using the functionality of the CppQuickCheck library.
+
+## DOCUMENTATION
+
+You can find examples in 'examples/src'.
+
+## BACKGROUND
+
+CppQuickCheck is inspired and based on the
+[QuickCheck](http://code.haskell.org/QuickCheck/) library for
+Haskell. CppQuickCheck differs in some aspects of the implementation and
+interface (as well as being written in C++ instead of Haskell), but tries to
+maintain similar functionality to the QuickCheck library.
+
+A similar library for C++ exists called
+[QuickCheck++](http://software.legiasoft.com/quickcheck/). QuickCheck++ does
+not support several important things that the Haskell QuickCheck supports
+including:
+
+ * *Generator combinators* - In QuickCheck++ custom generators for user
+ defined types are written by hand, with no provided random number
+ generation facility. One example of a way that Haskell's QuickCheck (and
+ CppQuickCheck) improve on this is the function `oneof` whick takes a list
+ of generators and creates a new generator that when called, selects a
+ random generator from the list and uses that to generate the input. In
+ QuickCheck++ this has to be written by hand using some external random
+ number generating library.
+ * *Shrinking the input for failed test cases* - When a randomly generated
+ test case fails, Haskell's QuickCheck (and CppQuickCheck, but not
+ QuickCheck++) will try to shrink the input to provide a minimal failing
+ case. This makes debugging the failure easier because instead of working
+ with a potentially large input case, much of the input can be removed to
+ reveal the structure of the failure.
+
+For these reasons, CppQuickCheck tries to maintain all the functionality of the
+Haskell QuickCheck, and so taking a different implementation approach than
+QuickCheck++.
+
+## UNIT TESTS
+
+Unit tests exists in the directory 'test'.
+
+```
+$ mkdir build
+$ cd build
+$ cmake ..
+$ make check
+```
+
+To get a more detailed output, rerun it with
+
+```
+$ ./all-catch-tests
+```
+
+## CONTRIBUTING
+
+Please direct your pull requests to https://github.com/philipp-classen/CppQuickCheck,
+which is the repository where the active development takes place.
+
+Currently, CppQuickCheck uses C++11 but not C++14. Travis will compile
+the library and run the tests with GCC 4.9 and Clang 3.8.
+
+## LICENSE
+
+CppQuickCheck is distributed under a BSD license (see LICENSE).
diff --git a/vendor/CppQuickCheck-2018-03-28/examples/CMakeLists.txt b/vendor/CppQuickCheck-2018-03-28/examples/CMakeLists.txt
new file mode 100644
index 00000000..794e0c47
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/examples/CMakeLists.txt
@@ -0,0 +1,33 @@
+add_executable(sampleOutput src/sampleOutput.cpp)
+target_link_libraries(sampleOutput cppqc)
+
+add_executable(sampleShrinkOutput src/sampleShrinkOutput.cpp)
+target_link_libraries(sampleShrinkOutput cppqc)
+
+add_executable(testReverse src/TestReverse.cpp)
+target_link_libraries(testReverse cppqc)
+
+add_executable(testReverseArray src/TestReverseArray.cpp)
+target_link_libraries(testReverseArray cppqc)
+
+add_executable(testSort src/TestSort.cpp)
+target_link_libraries(testSort cppqc)
+
+add_executable(testSortCompact src/TestSortCompact.cpp)
+target_link_libraries(testSortCompact cppqc)
+
+add_executable(testChooseGenerator src/TestChooseGenerator.cpp)
+target_link_libraries(testChooseGenerator cppqc)
+
+add_executable(exampleElementsGen src/exampleElementsGen.cpp)
+target_link_libraries(exampleElementsGen cppqc)
+
+add_executable(testSlowShrinking src/TestSlowShrinking.cpp)
+target_link_libraries(testSlowShrinking cppqc)
+
+add_executable(testWithCustomGenerator src/TestWithCustomGenerator.cpp)
+target_link_libraries(testSlowShrinking cppqc)
+
+# requires c++1y compile flag
+#add_executable(testBoostTupleSupport src/BoostTupleSupport.cpp)
+#target_link_libraries(testBoostTupleSupport cppqc)
diff --git a/vendor/CppQuickCheck-2018-03-28/examples/src/BoostTupleSupport.cpp b/vendor/CppQuickCheck-2018-03-28/examples/src/BoostTupleSupport.cpp
new file mode 100644
index 00000000..72a5f17d
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/examples/src/BoostTupleSupport.cpp
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2015, Gregory Rogers All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// It demonstrates how to add support for boost::tuple by
+// writing a custom generator (using std::tuple).
+//
+// Note this file uses C++14 features.
+
+#include "cppqc.h"
+
+#include <boost/tuple/tuple.hpp>
+#include "boost/tuple/tuple_comparison.hpp"
+#include <boost/tuple/tuple_io.hpp>
+#include <utility>
+
+using namespace cppqc;
+
+namespace {
+
+ template <typename StdTuple, std::size_t... Is>
+ auto asBoostTuple(StdTuple &&stdTuple, std::index_sequence<Is...>) {
+ return boost::tuple<std::tuple_element_t<Is, std::decay_t<StdTuple>>...>
+ (std::get<Is>(std::forward<StdTuple>(stdTuple))...);
+ }
+
+ template <typename BoostTuple, std::size_t... Is>
+ auto asStdTuple(BoostTuple &&boostTuple, std::index_sequence<Is...>) {
+ return std::tuple<typename boost::tuples::element<Is, std::decay_t<BoostTuple>>::type...>
+ (boost::get<Is>(std::forward<BoostTuple>(boostTuple))...);
+ }
+
+ template <typename StdTuple>
+ auto asBoostTuple(StdTuple &&stdTuple) {
+ return asBoostTuple(std::forward<StdTuple>(stdTuple),
+ std::make_index_sequence<std::tuple_size<std::decay_t<StdTuple>>::value>());
+ }
+
+ template <typename BoostTuple>
+ auto asStdTuple(BoostTuple&& boostTuple) {
+ return asStdTuple(std::forward<BoostTuple>(boostTuple),
+ std::make_index_sequence<boost::tuples::length<std::decay_t<BoostTuple>>::value>());
+ }
+
+ template<typename... T>
+ struct BoostTupleGenerator
+ {
+ BoostTupleGenerator(const Generator<T> &...g) :
+ m_tupleGenerator(tupleOf(g...))
+ {
+ }
+
+ boost::tuple<T...> unGen(RngEngine &rng, std::size_t size) const
+ {
+ return asBoostTuple(m_tupleGenerator.unGen(rng, size));
+ }
+
+ std::vector<boost::tuple<T...>> shrink(boost::tuple<T...> shrinkInput) const
+ {
+ std::vector<boost::tuple<T...>> result;
+ for (const auto &shrink : m_tupleGenerator.shrink(asStdTuple(shrinkInput))) {
+ result.push_back(asBoostTuple(shrink));
+ }
+ return result;
+ }
+
+ private:
+
+ Generator<std::tuple<T...>> m_tupleGenerator;
+ };
+
+}
+
+template<typename... T>
+Generator<boost::tuple<T...>> boostTupleOf(const Generator<T> &...g)
+{
+ return BoostTupleGenerator<T...>(g...);
+}
+
+template<typename... T>
+Generator<boost::tuple<T...>> boostTupleOf()
+{
+ return BoostTupleGenerator<T...>(Arbitrary<T>()...);
+}
+
+
+struct AntisymmetricRelationProp : Property<boost::tuple<int, std::string, int>,
+ boost::tuple<int, std::string, int>>
+{
+ AntisymmetricRelationProp() : Property(
+ boostTupleOf<int, std::string, int>(),
+ boostTupleOf<int, std::string, int>())
+ {}
+
+ bool check(const boost::tuple<int, std::string, int> &v1,
+ const boost::tuple<int, std::string, int> &v2) const override
+ {
+ return (v1 <= v2 && v1 >= v2) == (v1 == v2);
+ }
+
+ std::string name() const override
+ {
+ return "Comparison must be antisymmetric";
+ }
+};
+
+int main()
+{
+ cppqc::quickCheckOutput(AntisymmetricRelationProp());
+}
diff --git a/vendor/CppQuickCheck-2018-03-28/examples/src/TestChooseGenerator.cpp b/vendor/CppQuickCheck-2018-03-28/examples/src/TestChooseGenerator.cpp
new file mode 100644
index 00000000..25d69aa4
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/examples/src/TestChooseGenerator.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, Gregory Rogers All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cppqc.h"
+
+// This property tests that A*A > A holds.
+//
+// In general, this is not true, for instance, if A is zero.
+// However, by using the "choose" generator, we can define that
+// A is in a given interval (between 2 and 1000 in this example).
+struct AxA_isGreaterThan_A : cppqc::Property<int>
+{
+ static constexpr int MIN = 2;
+ static constexpr int MAX = 1000;
+
+ AxA_isGreaterThan_A() : Property(cppqc::choose(MIN, MAX)) {}
+
+ bool check(const int &A) const override
+ {
+ return A * A > A;
+ }
+
+ std::string name() const override
+ {
+ return "A*A > A";
+ }
+};
+
+int main()
+{
+ cppqc::quickCheckOutput(AxA_isGreaterThan_A());
+}
diff --git a/vendor/CppQuickCheck-2018-03-28/examples/src/TestReverse.cpp b/vendor/CppQuickCheck-2018-03-28/examples/src/TestReverse.cpp
new file mode 100644
index 00000000..751e19c5
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/examples/src/TestReverse.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2010, Gregory Rogers All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cppqc.h"
+
+#include <algorithm>
+#include <sstream>
+
+struct PropTestReverse : cppqc::Property<std::vector<int>>
+{
+ bool check(const std::vector<int> &v) const override
+ {
+ std::vector<int> vrev(v);
+ std::reverse(vrev.begin(), vrev.end());
+ std::reverse(vrev.begin(), vrev.end());
+ return std::equal(v.begin(), v.end(), vrev.begin());
+ }
+ std::string name() const override
+ {
+ return "Reversing Twice is Identity";
+ }
+ std::string classify(const std::vector<int> &v) const override
+ {
+ std::ostringstream sstr;
+ sstr << "size " << v.size();
+ return sstr.str();
+ }
+ bool trivial(const std::vector<int> &v) const override
+ {
+ return v.empty() || v.size() == 1;
+ }
+};
+
+int main()
+{
+ cppqc::quickCheckOutput(PropTestReverse());
+}
diff --git a/vendor/CppQuickCheck-2018-03-28/examples/src/TestReverseArray.cpp b/vendor/CppQuickCheck-2018-03-28/examples/src/TestReverseArray.cpp
new file mode 100644
index 00000000..02ba1956
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/examples/src/TestReverseArray.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014, Gregory Rogers All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cppqc.h"
+
+#include <algorithm>
+#include <boost/static_assert.hpp>
+
+const int ArraySize = 5;
+
+struct PropTestArrayReverse :
+ cppqc::Property<std::array<std::string, ArraySize>>
+{
+ bool check(const std::array<std::string, ArraySize> &v) const override
+ {
+ auto vrev = v;
+ std::reverse(vrev.begin(), vrev.end());
+ std::reverse(vrev.begin(), vrev.end());
+ return std::equal(v.begin(), v.end(), vrev.begin());
+ }
+ std::string name() const override
+ {
+ return "Reversing Twice is Identity";
+ }
+};
+
+struct PropTestBoolArrayReverse :
+ cppqc::Property<std::array<bool, ArraySize>>
+{
+ bool check(const std::array<bool, ArraySize> &v) const override
+ {
+ auto vrev = v;
+ std::reverse(vrev.begin(), vrev.end());
+ std::reverse(vrev.begin(), vrev.end());
+ return std::equal(v.begin(), v.end(), vrev.begin());
+ }
+ std::string name() const override
+ {
+ return "Reversing Twice is Identity";
+ }
+};
+
+int main()
+{
+ cppqc::quickCheckOutput(PropTestArrayReverse());
+ cppqc::quickCheckOutput(PropTestBoolArrayReverse());
+}
diff --git a/vendor/CppQuickCheck-2018-03-28/examples/src/TestSlowShrinking.cpp b/vendor/CppQuickCheck-2018-03-28/examples/src/TestSlowShrinking.cpp
new file mode 100644
index 00000000..641016c4
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/examples/src/TestSlowShrinking.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016, Philipp Classen All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cppqc.h"
+
+#include <vector>
+#include <chrono>
+#include <thread>
+#include <atomic>
+
+// This simulates a test that is extremely slow. For such tests,
+// shrinking can become a problem, as it can take quite a while.
+struct PropTestSlowFunction: cppqc::Property<std::vector<int>>
+{
+ mutable std::atomic<bool> shrinking{false};
+
+ bool check(const std::vector<int> &v) const override
+ {
+ if (shrinking) {
+ std::cout << "Sleeping..." << std::endl;
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+ }
+
+ if (v.size() >= 4 && (v[3] % 5) == 1) {
+ shrinking = true;
+ return false;
+ }
+ return true;
+ }
+ std::string name() const override
+ {
+ return "Sorting should be sorted";
+ }
+};
+
+int main()
+{
+ cppqc::quickCheckOutput(PropTestSlowFunction());
+}
diff --git a/vendor/CppQuickCheck-2018-03-28/examples/src/TestSort.cpp b/vendor/CppQuickCheck-2018-03-28/examples/src/TestSort.cpp
new file mode 100644
index 00000000..f5e3c4dc
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/examples/src/TestSort.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010, Gregory Rogers All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cppqc.h"
+
+#include <algorithm>
+#include <iterator>
+#include <boost/static_assert.hpp>
+#include <sstream>
+
+namespace uut {
+
+template <typename InputIterator>
+void selection_sort(InputIterator b, InputIterator e, bool make_mistakes = false)
+{
+ //Selection sort performs the following steps:
+ //1) From the current iterator, find the smallest value
+ //2) Swap the smallest value with the current iterator
+ //3) Continue until end of range
+
+ make_mistakes && b != e ? ++b : b;
+ for(InputIterator c = b; c != e ; ++c)
+ {
+ std::swap(*(std::min_element(c, e)), *c);
+ }
+}
+
+}
+
+struct PropTestSort: cppqc::Property<std::vector<int>>
+{
+ bool check(const std::vector<int> &v) const override
+ {
+ std::vector<int> v_copy(v);
+ uut::selection_sort(std::begin(v_copy), std::end(v_copy), true);
+ return std::is_sorted(std::begin(v_copy), std::end(v_copy));
+ }
+ std::string name() const override
+ {
+ return "Sorting should be sorted";
+ }
+ std::string classify(const std::vector<int> &v) const override
+ {
+ std::ostringstream sstr;
+ sstr << "size " << v.size();
+ return sstr.str();
+ }
+ bool trivial(const std::vector<int> &v) const override
+ {
+ return v.empty() || v.size() == 1;
+ }
+};
+
+int main()
+{
+ cppqc::quickCheckOutput(PropTestSort());
+}
diff --git a/vendor/CppQuickCheck-2018-03-28/examples/src/TestSortCompact.cpp b/vendor/CppQuickCheck-2018-03-28/examples/src/TestSortCompact.cpp
new file mode 100644
index 00000000..a3a6ee71
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/examples/src/TestSortCompact.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2016, Vladimir Strisovsky All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cppqc.h"
+#include "cppqc/CompactCheck.h"
+
+#include <algorithm>
+#include <iterator>
+#include <boost/static_assert.hpp>
+#include <sstream>
+
+namespace uut {
+
+template <typename InputIterator>
+void selection_sort(InputIterator b, InputIterator e, bool make_mistakes = false)
+{
+ //Selection sort performs the following steps:
+ //1) From the current iterator, find the smallest value
+ //2) Swap the smallest value with the current iterator
+ //3) Continue until end of range
+
+ make_mistakes && b != e ? ++b : b;
+ for(InputIterator c = b; c != e ; ++c)
+ {
+ std::swap(*(std::min_element(c, e)), *c);
+ }
+}
+
+}
+
+int main()
+{
+ std::cout << "* uut::selection_sort" << std::endl;
+
+ cppqc::gen<std::vector<int>>()
+ .property("Sorting should be sorted",
+ [](const std::vector<int> &v)
+ {
+ std::vector<int> v_copy(v);
+ uut::selection_sort(std::begin(v_copy), std::end(v_copy), true);
+ return std::is_sorted(std::begin(v_copy), std::end(v_copy));
+ })
+ .classify([](const std::vector<int> &v)
+ {
+ return std::to_string(v.size());
+ })
+ .trivial([](const std::vector<int> &v)
+ {
+ return v.empty() || v.size() == 1;
+ })
+ .testWithOutput();
+
+ std::cout << "* std::sort" << std::endl;
+
+ cppqc::gen<std::vector<int>>()
+ .property("Sorting should be sorted",
+ [](const std::vector<int> &v)
+ {
+ std::vector<int> v_copy(v);
+ std::sort(v_copy.begin(), v_copy.end());
+ return std::is_sorted(std::begin(v_copy), std::end(v_copy));
+ })
+ .classify([](const std::vector<int> &v)
+ {
+ return std::to_string(v.size());
+ })
+ .trivial([](const std::vector<int> &v)
+ {
+ return v.empty() || v.size() == 1;
+ })
+ .testWithOutput();
+
+}
diff --git a/vendor/CppQuickCheck-2018-03-28/examples/src/TestWithCustomGenerator.cpp b/vendor/CppQuickCheck-2018-03-28/examples/src/TestWithCustomGenerator.cpp
new file mode 100644
index 00000000..0113cac4
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/examples/src/TestWithCustomGenerator.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2018, Amy de Buitléir All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cppqc.h"
+
+#include <random>
+#include <sstream>
+
+class Rectangle {
+public:
+ Rectangle (int w, int h) {
+ width = w;
+ height = h;
+ }
+ int getWidth() const { return width; }
+ int getHeight() const { return height; }
+ int getArea() const { return width*height; }
+ friend std::ostream& operator << (std::ostream& os, const Rectangle& r) {
+ os << "width: " << r.width << " height: " << r.height << std::endl;
+ return os ;
+ }
+private:
+ int width;
+ int height;
+};
+
+class CustomGenerator {
+public:
+ Rectangle unGen(cppqc::RngEngine &rng, std::size_t n) {
+ std::uniform_int_distribution<> dist{1, static_cast<int>(n) + 1};
+ int w = dist(rng);
+ int h = (n + 1)/w;
+ return Rectangle(w, h);
+ }
+
+ std::vector<Rectangle> shrink(const Rectangle &r) {
+ std::vector<Rectangle> ret;
+ if (r.getWidth() > 1)
+ ret.push_back(Rectangle(r.getWidth()-1, r.getHeight()));
+ if (r.getHeight() > 1) {
+ ret.push_back(Rectangle(r.getWidth(), r.getHeight()-1));
+ }
+ return ret;
+ }
+};
+
+// A silly test just to demonstrate the custom generator.
+struct PropTestCustomGen : cppqc::Property<Rectangle>
+{
+ PropTestCustomGen() : Property(CustomGenerator()) {}
+ bool check(const Rectangle &r) const override
+ {
+ return (r.getArea() == r.getWidth() * r.getHeight());
+ }
+ std::string name() const override
+ {
+ return "TestCustomGen";
+ }
+};
+
+int main()
+{
+ cppqc::quickCheckOutput(PropTestCustomGen());
+}
diff --git a/vendor/CppQuickCheck-2018-03-28/examples/src/exampleElementsGen.cpp b/vendor/CppQuickCheck-2018-03-28/examples/src/exampleElementsGen.cpp
new file mode 100644
index 00000000..fe6e953f
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/examples/src/exampleElementsGen.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010, Gregory Rogers All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cppqc.h"
+
+#include <algorithm>
+#include <sstream>
+
+// Useless property just to show usage of elements generator
+
+struct PropTestElementsGen : cppqc::Property<int>
+{
+ PropTestElementsGen() : Property(cppqc::elements({1, 4, 5})) {}
+ bool check(const int &v) const override
+ {
+ return (v == 1) || (v == 4) || (v == 5);
+ }
+ std::string name() const override
+ {
+ return "TestElementsGen";
+ }
+ std::string classify(const int &v) const override
+ {
+ std::ostringstream sstr;
+ sstr << v;
+ return sstr.str();
+ }
+};
+
+int main()
+{
+ cppqc::quickCheckOutput(PropTestElementsGen());
+}
diff --git a/vendor/CppQuickCheck-2018-03-28/examples/src/sampleOutput.cpp b/vendor/CppQuickCheck-2018-03-28/examples/src/sampleOutput.cpp
new file mode 100644
index 00000000..82d586b3
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/examples/src/sampleOutput.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2010, Gregory Rogers All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cppqc.h"
+
+#include <map>
+#include <boost/bind.hpp>
+#include <boost/assign/list_of.hpp>
+
+using namespace cppqc;
+
+const std::map<std::string, boost::function<void ()> >
+sampleOutputCommand = boost::assign::map_list_of<std::string, boost::function<void ()> >
+("bool", boost::bind(sampleOutput<bool>, Arbitrary<bool>(), boost::ref(std::cout), 0, 0))
+("char", boost::bind(sampleOutput<char>, Arbitrary<char>(), boost::ref(std::cout), 0, 0))
+("wchar_t", boost::bind(sampleOutput<wchar_t>, Arbitrary<wchar_t>(), boost::ref(std::cout), 0, 0))
+("signed char", boost::bind(sampleOutput<signed char>, Arbitrary<signed char>(), boost::ref(std::cout), 0, 0))
+("unsigned char", boost::bind(sampleOutput<unsigned char>, Arbitrary<unsigned char>(), boost::ref(std::cout), 0, 0))
+("short", boost::bind(sampleOutput<short>, Arbitrary<short>(), boost::ref(std::cout), 0, 0))
+("signed short", boost::bind(sampleOutput<signed short>, Arbitrary<signed short>(), boost::ref(std::cout), 0, 0))
+("unsigned short", boost::bind(sampleOutput<unsigned short>, Arbitrary<unsigned short>(), boost::ref(std::cout), 0, 0))
+("int", boost::bind(sampleOutput<int>, Arbitrary<int>(), boost::ref(std::cout), 0, 0))
+("signed", boost::bind(sampleOutput<signed>, Arbitrary<signed>(), boost::ref(std::cout), 0, 0))
+("unsigned", boost::bind(sampleOutput<unsigned>, Arbitrary<unsigned>(), boost::ref(std::cout), 0, 0))
+("signed int", boost::bind(sampleOutput<signed int>, Arbitrary<signed int>(), boost::ref(std::cout), 0, 0))
+("unsigned int", boost::bind(sampleOutput<unsigned int>, Arbitrary<unsigned int>(), boost::ref(std::cout), 0, 0))
+("long", boost::bind(sampleOutput<long>, Arbitrary<long>(), boost::ref(std::cout), 0, 0))
+("signed long", boost::bind(sampleOutput<signed long>, Arbitrary<signed long>(), boost::ref(std::cout), 0, 0))
+("unsigned long", boost::bind(sampleOutput<unsigned long>, Arbitrary<unsigned long>(), boost::ref(std::cout), 0, 0))
+("float", boost::bind(sampleOutput<float>, Arbitrary<float>(), boost::ref(std::cout), 0, 0))
+("double", boost::bind(sampleOutput<double>, Arbitrary<double>(), boost::ref(std::cout), 0, 0))
+("long double", boost::bind(sampleOutput<long double>, Arbitrary<long double>(), boost::ref(std::cout), 0, 0))
+("pair", boost::bind(sampleOutput<std::pair<int,int> >, Arbitrary<std::pair<int,int> >(), boost::ref(std::cout), 0, 0))
+("tuple", boost::bind(sampleOutput<std::tuple<int,int,int> >, tupleOf<int,int,int>(), boost::ref(std::cout), 0, 0))
+("string", boost::bind(sampleOutput<std::string>, Arbitrary<std::string>(), boost::ref(std::cout), 0, 0));
+
+int main(int argc, char **argv)
+{
+ if(argc == 1) {
+ std::cout << "Usage: TYPES... (e.g., int, double, string)\n";
+ return 0;
+ }
+
+ for (int i = 1; i < argc; ++i) {
+ auto it = sampleOutputCommand.find(argv[i]);
+ if (it != sampleOutputCommand.end())
+ it->second();
+ else
+ std::cout << "unrecognized type \"" << argv[i] << "\"\n";
+ }
+}
diff --git a/vendor/CppQuickCheck-2018-03-28/examples/src/sampleShrinkOutput.cpp b/vendor/CppQuickCheck-2018-03-28/examples/src/sampleShrinkOutput.cpp
new file mode 100644
index 00000000..b7c65ff2
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/examples/src/sampleShrinkOutput.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2010, Gregory Rogers All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cppqc.h"
+
+#include <map>
+#include <boost/bind.hpp>
+#include <boost/assign/list_of.hpp>
+
+using namespace cppqc;
+
+namespace std {
+ template<class T1, class T2>
+ std::ostream &operator<<(std::ostream &out, const std::pair<T1, T2> &x)
+ {
+ return out << '(' << x.first << ',' << x.second << ')';
+ }
+}
+
+const std::map<std::string, boost::function<void ()> >
+sampleShrinkOutputCommand = boost::assign::map_list_of<std::string, boost::function<void ()> >
+("bool", boost::bind(sampleShrinkOutput<bool>, Arbitrary<bool>(), boost::ref(std::cout), 0, true, 0))
+("char", boost::bind(sampleShrinkOutput<char>, Arbitrary<char>(), boost::ref(std::cout), 0, true, 0))
+("wchar_t", boost::bind(sampleShrinkOutput<wchar_t>, Arbitrary<wchar_t>(), boost::ref(std::cout), 0, true, 0))
+("signed char", boost::bind(sampleShrinkOutput<signed char>, Arbitrary<signed char>(), boost::ref(std::cout), 0, true, 0))
+("unsigned char", boost::bind(sampleShrinkOutput<unsigned char>, Arbitrary<unsigned char>(), boost::ref(std::cout), 0, true, 0))
+("short", boost::bind(sampleShrinkOutput<short>, Arbitrary<short>(), boost::ref(std::cout), 0, true, 0))
+("signed short", boost::bind(sampleShrinkOutput<signed short>, Arbitrary<signed short>(), boost::ref(std::cout), 0, true, 0))
+("unsigned short", boost::bind(sampleShrinkOutput<unsigned short>, Arbitrary<unsigned short>(), boost::ref(std::cout), 0, true, 0))
+("int", boost::bind(sampleShrinkOutput<int>, Arbitrary<int>(), boost::ref(std::cout), 0, true, 0))
+("signed", boost::bind(sampleShrinkOutput<signed>, Arbitrary<signed>(), boost::ref(std::cout), 0, true, 0))
+("unsigned", boost::bind(sampleShrinkOutput<unsigned>, Arbitrary<unsigned>(), boost::ref(std::cout), 0, true, 0))
+("signed int", boost::bind(sampleShrinkOutput<signed int>, Arbitrary<signed int>(), boost::ref(std::cout), 0, true, 0))
+("unsigned int", boost::bind(sampleShrinkOutput<unsigned int>, Arbitrary<unsigned int>(), boost::ref(std::cout), 0, true, 0))
+("long", boost::bind(sampleShrinkOutput<long>, Arbitrary<long>(), boost::ref(std::cout), 0, true, 0))
+("signed long", boost::bind(sampleShrinkOutput<signed long>, Arbitrary<signed long>(), boost::ref(std::cout), 0, true, 0))
+("unsigned long", boost::bind(sampleShrinkOutput<unsigned long>, Arbitrary<unsigned long>(), boost::ref(std::cout), 0, true, 0))
+("float", boost::bind(sampleShrinkOutput<float>, Arbitrary<float>(), boost::ref(std::cout), 0, true, 0))
+("double", boost::bind(sampleShrinkOutput<double>, Arbitrary<double>(), boost::ref(std::cout), 0, true, 0))
+("long double", boost::bind(sampleShrinkOutput<long double>, Arbitrary<long double>(), boost::ref(std::cout), 0, true, 0))
+("pair", boost::bind(sampleShrinkOutput<std::pair<int,int> >, Arbitrary<std::pair<int,int> >(), boost::ref(std::cout), 0, true, 0))
+("tuple", boost::bind(sampleShrinkOutput<std::tuple<int,int,int> >, tupleOf<int,int,int>(), boost::ref(std::cout), 0, true, 0))
+("string", boost::bind(sampleShrinkOutput<std::string>, Arbitrary<std::string>(), boost::ref(std::cout), 0, true, 0));
+
+int main(int argc, char **argv)
+{
+ if(argc == 1) {
+ std::cout << "Usage: TYPES... (e.g., int, double, string)\n";
+ return 0;
+ }
+
+ for (int i = 1; i < argc; ++i) {
+ std::map<std::string, boost::function<void ()> >::const_iterator it =
+ sampleShrinkOutputCommand.find(argv[i]);
+ if (it != sampleShrinkOutputCommand.end())
+ it->second();
+ else
+ std::cout << "unrecognized type \"" << argv[i] << "\"\n";
+ }
+}
diff --git a/vendor/CppQuickCheck-2018-03-28/include/cppqc.h b/vendor/CppQuickCheck-2018-03-28/include/cppqc.h
new file mode 100644
index 00000000..234bb264
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/include/cppqc.h
@@ -0,0 +1,9 @@
+#ifndef CPPQC_H
+#define CPPQC_H
+
+#include "cppqc/Generator.h"
+#include "cppqc/Arbitrary.h"
+#include "cppqc/Property.h"
+#include "cppqc/Test.h"
+
+#endif
diff --git a/vendor/CppQuickCheck-2018-03-28/include/cppqc/Arbitrary.h b/vendor/CppQuickCheck-2018-03-28/include/cppqc/Arbitrary.h
new file mode 100644
index 00000000..ecfc56c1
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/include/cppqc/Arbitrary.h
@@ -0,0 +1,446 @@
+/*
+ * Copyright (c) 2010, Gregory Rogers All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CPPQC_ARBITRARY_H
+#define CPPQC_ARBITRARY_H
+
+#include "Generator.h"
+
+#include <limits>
+
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_smallint.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/random/poisson_distribution.hpp>
+#include <boost/random/variate_generator.hpp>
+
+namespace cppqc {
+
+// default generators
+
+template<class Integral>
+Integral arbitrarySizedIntegral(RngEngine &rng, std::size_t size)
+{
+ boost::uniform_int<Integral> dist(std::numeric_limits<Integral>::is_signed ?
+ -Integral(size) : Integral(size),
+ Integral(size));
+ return dist(rng);
+}
+
+template<class Integral>
+Integral arbitraryBoundedIntegral(RngEngine &rng, std::size_t /*size*/)
+{
+ boost::uniform_int<Integral> dist(std::numeric_limits<Integral>::min(),
+ std::numeric_limits<Integral>::max());
+ return dist(rng);
+}
+
+template<class Integral>
+Integral arbitrarySizedBoundedIntegral(RngEngine &rng, std::size_t size)
+{
+ boost::poisson_distribution<Integral> dist(size == 0 ? 1 : size);
+ boost::variate_generator<RngEngine&, boost::uniform_01<> > gen(rng, boost::uniform_01<>());
+ Integral r = dist(gen);
+ if (std::numeric_limits<Integral>::is_signed) {
+ if (boost::uniform_smallint<int>(0, 1)(rng))
+ r = -r;
+ }
+ return r;
+}
+
+template<class Real>
+Real arbitrarySizedReal(RngEngine &rng, std::size_t size)
+{
+ boost::uniform_real<Real> dist(-Real(size + 1.0), Real(size + 1.0));
+ return dist(rng);
+}
+
+// default shrinkers
+
+template<class T>
+std::vector<T> shrinkNothing(const T &)
+{
+ return std::vector<T>();
+}
+
+template<class Integral>
+std::vector<Integral> shrinkIntegral(Integral x)
+{
+ std::vector<Integral> ret;
+ if (std::numeric_limits<Integral>::is_signed && x < 0) {
+ if (x == std::numeric_limits<Integral>::min()) {
+ ret.push_back(std::numeric_limits<Integral>::max());
+ } else {
+ assert(-x > 0);
+ ret.push_back(-x);
+ }
+ }
+
+ for (Integral n = x; n != 0; n /= 2)
+ ret.push_back(x - n);
+ return ret;
+}
+
+template<class Real>
+std::vector<Real> shrinkReal(Real x)
+{
+ std::vector<Real> ret;
+ if (x == 0)
+ return ret;
+ if (x < 0)
+ ret.push_back(-x);
+ ret.push_back(Real(0));
+
+ if (std::isnan(x) && std::abs(x) >= 2) {
+ if (std::abs(x) < 1e100) {
+ ret.push_back(x / Real(2));
+ } else {
+ // special case: reduce faster if the numbers are huge
+ // (Note: Maybe there is a better heuristic. Looks quite crude.)
+ ret.push_back(x / Real(1e20));
+ }
+ }
+ return ret;
+}
+
+
+template<class T>
+struct Arbitrary
+{
+ typedef boost::function<T (RngEngine &, std::size_t)> unGenType;
+ typedef boost::function<std::vector<T> (T)> shrinkType;
+
+ static const unGenType unGen;
+ static const shrinkType shrink;
+};
+
+/*
+ * specialize ArbitraryImpl and implement the members:
+ * static const Arbitrary<T>::unGenType unGen;
+ * static const Arbitrary<T>::shrinkType shrink;
+ */
+template<class T>
+struct ArbitraryImpl
+{
+ // no default implementation - users must specialize ArbitraryImpl
+ // and give an implementation of unGen and shrink. If they do not
+ // and they try to use Arbitrary<TheirClass>, a compile error will result.
+};
+
+// Note: The call is wrapped in a function to avoid issues
+// with static ordering when ArbitraryImpl is defined
+// in another compilation unit. Do not simplify it
+// by replacing it with an assignment.
+template<class T>
+const typename Arbitrary<T>::unGenType Arbitrary<T>::unGen = [](RngEngine &rng,
+ std::size_t size) {
+ return ArbitraryImpl<T>::unGen(rng, size);
+};
+
+// (function call is needed: see above)
+template<class T>
+const typename Arbitrary<T>::shrinkType Arbitrary<T>::shrink = [](const T &v) {
+ return ArbitraryImpl<T>::shrink(v);
+};
+
+// included specializations
+
+inline bool arbitraryBool(RngEngine &rng, std::size_t /*size*/)
+{
+ if (boost::uniform_smallint<int>(0, 1)(rng))
+ return true;
+ return false;
+}
+inline std::vector<bool> shrinkBool(bool x)
+{
+ std::vector<bool> ret;
+ if (x) ret.push_back(false);
+ return ret;
+}
+template<>
+struct ArbitraryImpl<bool>
+{
+ static const Arbitrary<bool>::unGenType unGen;
+ static const Arbitrary<bool>::shrinkType shrink;
+};
+
+template<>
+struct ArbitraryImpl<signed char>
+{
+ static const Arbitrary<signed char>::unGenType unGen;
+ static const Arbitrary<signed char>::shrinkType shrink;
+};
+
+template<>
+struct ArbitraryImpl<unsigned char>
+{
+ static const Arbitrary<unsigned char>::unGenType unGen;
+ static const Arbitrary<unsigned char>::shrinkType shrink;
+};
+
+template<>
+struct ArbitraryImpl<signed short>
+{
+ static const Arbitrary<signed short>::unGenType unGen;
+ static const Arbitrary<signed short>::shrinkType shrink;
+};
+
+template<>
+struct ArbitraryImpl<unsigned short>
+{
+ static const Arbitrary<unsigned short>::unGenType unGen;
+ static const Arbitrary<unsigned short>::shrinkType shrink;
+};
+
+template<>
+struct ArbitraryImpl<signed int>
+{
+ static const Arbitrary<signed int>::unGenType unGen;
+ static const Arbitrary<signed int>::shrinkType shrink;
+};
+
+template<>
+struct ArbitraryImpl<unsigned int>
+{
+ static const Arbitrary<unsigned int>::unGenType unGen;
+ static const Arbitrary<unsigned int>::shrinkType shrink;
+};
+
+template<>
+struct ArbitraryImpl<signed long>
+{
+ static const Arbitrary<signed long>::unGenType unGen;
+ static const Arbitrary<signed long>::shrinkType shrink;
+};
+
+template<>
+struct ArbitraryImpl<unsigned long>
+{
+ static const Arbitrary<unsigned long>::unGenType unGen;
+ static const Arbitrary<unsigned long>::shrinkType shrink;
+};
+
+template<>
+struct ArbitraryImpl<signed long long>
+{
+ static const Arbitrary<signed long long>::unGenType unGen;
+ static const Arbitrary<signed long long>::shrinkType shrink;
+};
+
+template<>
+struct ArbitraryImpl<unsigned long long>
+{
+ static const Arbitrary<unsigned long long>::unGenType unGen;
+ static const Arbitrary<unsigned long long>::shrinkType shrink;
+};
+
+template<>
+struct ArbitraryImpl<float>
+{
+ static const Arbitrary<float>::unGenType unGen;
+ static const Arbitrary<float>::shrinkType shrink;
+};
+
+template<>
+struct ArbitraryImpl<double>
+{
+ static const Arbitrary<double>::unGenType unGen;
+ static const Arbitrary<double>::shrinkType shrink;
+};
+
+template<>
+struct ArbitraryImpl<long double>
+{
+ static const Arbitrary<long double>::unGenType unGen;
+ static const Arbitrary<long double>::shrinkType shrink;
+};
+
+inline char arbitraryChar(RngEngine &rng, std::size_t)
+{
+ boost::uniform_int<char> dist(0x20, 0x7f);
+ return dist(rng);
+}
+inline std::vector<char> shrinkChar(char c)
+{
+ const char possShrinks[] = {'a', 'b', 'c', 'A', 'B', 'C', '1', '2', '3',
+ ' ', '\n', '\0'};
+ std::vector<char> ret;
+ for (auto & possShrink : possShrinks) {
+ if (possShrink < c)
+ ret.push_back(possShrink);
+ }
+ if (isupper(c) &&
+ std::find(possShrinks, possShrinks + sizeof(possShrinks),
+ tolower(c)) != possShrinks + sizeof(possShrinks))
+ ret.push_back(tolower(c));
+ return ret;
+}
+template<>
+struct ArbitraryImpl<char>
+{
+ static const Arbitrary<char>::unGenType unGen;
+ static const Arbitrary<char>::shrinkType shrink;
+};
+
+template<>
+struct ArbitraryImpl<wchar_t>
+{
+ static const Arbitrary<wchar_t>::unGenType unGen;
+ static const Arbitrary<wchar_t>::shrinkType shrink;
+};
+
+template<class String>
+String arbitraryString(RngEngine &rng, std::size_t size)
+{
+ boost::uniform_int<std::size_t> dist(0, size);
+ std::size_t n = dist(rng);
+ String ret;
+ ret.reserve(n);
+ while (n-- > 0)
+ ret.push_back(Arbitrary<typename String::value_type>::unGen(rng, size));
+ return ret;
+}
+template<class String>
+std::vector<String> shrinkString(const String &x)
+{
+ std::vector<String> ret;
+ ret.reserve(x.size());
+ for (auto it = x.begin(); it != x.end(); ++it) {
+ ret.push_back(String());
+ ret.back().reserve(x.size() - 1);
+ ret.back().insert(ret.back().end(), x.begin(), it);
+ ret.back().insert(ret.back().end(), it + 1, x.end());
+ }
+ return ret;
+}
+template<class CharT, class Traits, class Alloc>
+struct ArbitraryImpl<std::basic_string<CharT, Traits, Alloc> >
+{
+ static const typename
+ Arbitrary<std::basic_string<CharT, Traits, Alloc> >::unGenType unGen;
+ static const typename
+ Arbitrary<std::basic_string<CharT, Traits, Alloc> >::shrinkType shrink;
+};
+template<class CharT, class Traits, class Alloc>
+const typename Arbitrary<std::basic_string<CharT, Traits, Alloc> >::unGenType
+ArbitraryImpl<std::basic_string<CharT, Traits, Alloc> >::unGen =
+arbitraryString<std::basic_string<CharT, Traits, Alloc> >;
+template<class CharT, class Traits, class Alloc>
+const typename Arbitrary<std::basic_string<CharT, Traits, Alloc> >::shrinkType
+ArbitraryImpl<std::basic_string<CharT, Traits, Alloc> >::shrink =
+shrinkString<std::basic_string<CharT, Traits, Alloc> >;
+
+template<class PairType>
+PairType arbitraryPair(RngEngine &rng, std::size_t size)
+{
+ return PairType(Arbitrary<typename PairType::first_type>::unGen(rng, size),
+ Arbitrary<typename PairType::second_type>::unGen(rng, size));
+}
+template<class PairType>
+std::vector<PairType> shrinkPair(const PairType &x)
+{
+ typedef typename PairType::first_type FirstType;
+ typedef typename PairType::second_type SecondType;
+ std::vector<FirstType> shrinks1 = Arbitrary<FirstType>::shrink(x.first);
+ std::vector<SecondType> shrinks2 = Arbitrary<SecondType>::shrink(x.second);
+ std::vector<PairType> ret;
+ ret.reserve(shrinks1.size() + shrinks2.size());
+ for (auto it = shrinks1.begin(); it != shrinks1.end(); ++it) {
+ ret.push_back(PairType(*it, x.second));
+ }
+ for (auto it = shrinks2.begin(); it != shrinks2.end(); ++it) {
+ ret.push_back(PairType(x.first, *it));
+ }
+ return ret;
+}
+template<class T1, class T2>
+struct ArbitraryImpl<std::pair<T1, T2> >
+{
+ static const typename Arbitrary<std::pair<T1, T2> >::unGenType unGen;
+ static const typename Arbitrary<std::pair<T1, T2> >::shrinkType shrink;
+};
+template<class T1, class T2>
+const typename Arbitrary<std::pair<T1, T2> >::unGenType
+ArbitraryImpl<std::pair<T1, T2> >::unGen = arbitraryPair<std::pair<T1, T2> >;
+template<class T1, class T2>
+const typename Arbitrary<std::pair<T1, T2> >::shrinkType
+ArbitraryImpl<std::pair<T1, T2> >::shrink = shrinkPair<std::pair<T1, T2> >;
+
+template<typename T>
+struct ArbitraryImpl<std::vector<T>>
+{
+ static const typename Arbitrary<std::vector<T>>::unGenType unGen;
+ static const typename Arbitrary<std::vector<T>>::shrinkType shrink;
+};
+
+template <typename T>
+const typename Arbitrary<std::vector<T>>::unGenType
+ ArbitraryImpl<std::vector<T>>::unGen = [](RngEngine &rng,
+ std::size_t size) {
+ const auto& vectorGenerator = listOf<T>();
+ return vectorGenerator.unGen(rng, size);
+};
+
+template <typename T>
+const typename Arbitrary<std::vector<T>>::shrinkType
+ ArbitraryImpl<std::vector<T>>::shrink = [](const std::vector<T> &v) {
+
+ const auto& vectorGenerator = listOf<T>();
+ return vectorGenerator.shrink(v);
+};
+
+
+template<typename T, std::size_t N>
+struct ArbitraryImpl<std::array<T, N>>
+{
+ static const typename Arbitrary<std::array<T, N>>::unGenType unGen;
+ static const typename Arbitrary<std::array<T, N>>::shrinkType shrink;
+};
+
+/// Note: N is the fixed size of the array.
+/// It differs from the "size" param in the "unGen" function:
+///
+/// If "size" is increased, the output array will still contain
+/// N elements, but each element will, in general, be more complex.
+template <typename T, std::size_t N>
+const typename Arbitrary<std::array<T, N>>::unGenType
+ ArbitraryImpl<std::array<T, N>>::unGen = [](RngEngine &rng,
+ std::size_t size) {
+ const auto& arrayGenerator = arrayOf<T, N>();
+ return arrayGenerator.unGen(rng, size);
+};
+
+template <typename T, std::size_t N>
+const typename Arbitrary<std::array<T, N>>::shrinkType
+ ArbitraryImpl<std::array<T, N>>::shrink = [](const std::array<T, N> &arr) {
+
+ const auto& arrayGenerator = arrayOf<T, N>();
+ return arrayGenerator.shrink(arr);
+};
+
+}
+
+#endif
diff --git a/vendor/CppQuickCheck-2018-03-28/include/cppqc/CompactCheck.h b/vendor/CppQuickCheck-2018-03-28/include/cppqc/CompactCheck.h
new file mode 100644
index 00000000..cdd204a0
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/include/cppqc/CompactCheck.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2016, Vladimir Strisovsky All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "Test.h"
+#include "Arbitrary.h"
+
+namespace cppqc
+{
+
+template<typename Function>
+struct CompactCheckFunction
+{
+ using type = Function;
+ Function m_Function;
+
+ CompactCheckFunction(Function&& fnc)
+ : m_Function(std::move(fnc))
+ {}
+
+ CompactCheckFunction(CompactCheckFunction&&) = default;
+
+ static const bool valid = true;
+
+ template<typename ReturnType, typename ... T>
+ ReturnType apply(ReturnType, const T& ... v) const
+ {
+ return m_Function(v ...);
+ }
+};
+
+template<>
+struct CompactCheckFunction<void>
+{
+ using type = void;
+ static const bool valid = false;
+
+ CompactCheckFunction() = default;
+ CompactCheckFunction(CompactCheckFunction&&) = default;
+
+ template<typename ReturnType, typename ... T>
+ ReturnType apply(ReturnType r, const T& ... v) const
+ {
+ return r;
+ }
+};
+
+template<typename CheckFunction, typename TrivialFunction, typename ClassifyFunction, typename ... T>
+class CompactCheck : public Property<T ...>
+{
+ std::string m_name;
+
+ template<typename _CheckFunction, typename _TrivialFunction, typename _ClassifyFunction, typename ... _T>
+ friend class CompactCheck;
+
+ using CheckFunctionT = CompactCheckFunction<CheckFunction>;
+ CheckFunctionT m_checkFnc;
+
+ using TrivialFunctionT = CompactCheckFunction<TrivialFunction>;
+ TrivialFunctionT m_trivialFnc;
+
+ using ClassifyFunctionT = CompactCheckFunction<ClassifyFunction>;
+ ClassifyFunctionT m_classifyFnc;
+
+ CompactCheck( std::string name,
+ CheckFunctionT&& checkFunction,
+ TrivialFunctionT&& trivialFunctions,
+ ClassifyFunctionT&& classifyFunction)
+ : m_name(std::move(name))
+ , m_checkFnc(std::move(checkFunction))
+ , m_trivialFnc(std::move(trivialFunctions))
+ , m_classifyFnc(std::move(classifyFunction))
+ {}
+
+ bool check(const T& ... v) const override
+ {
+ return m_checkFnc.apply(true, v ...);
+ }
+
+ bool trivial(const T& ... v) const override
+ {
+ return m_trivialFnc.apply(false, v ...);
+ }
+
+ std::string classify(const T& ... v) const override
+ {
+ return m_classifyFnc.apply(std::string(), v ...);
+ }
+
+ std::string name() const
+ {
+ return m_name.empty() ? "no-name" : m_name;
+ }
+
+public:
+ CompactCheck()
+ {}
+
+ CompactCheck(const Generator<T>& ... g)
+ : Property<T ...>(g ...)
+ {}
+
+ template<typename _CheckFunction>
+ CompactCheck<_CheckFunction, TrivialFunction, ClassifyFunction, T ...> property(const std::string& name, _CheckFunction&& checkFnc)
+ {
+ static_assert(CheckFunctionT::valid == false, "Check function is already set");
+ return CompactCheck<_CheckFunction, TrivialFunction, ClassifyFunction, T ...>( name,
+ std::move(checkFnc),
+ std::move(m_trivialFnc),
+ std::move(m_classifyFnc));
+ }
+
+ template<typename _TrivialFunction>
+ CompactCheck<CheckFunction, _TrivialFunction, ClassifyFunction, T ...> trivial(_TrivialFunction&& trivialFnc)
+ {
+ static_assert(TrivialFunctionT::valid == false, "Trivial function is already set");
+ return CompactCheck<CheckFunction, _TrivialFunction, ClassifyFunction, T ...>( std::move(m_name),
+ std::move(m_checkFnc),
+ std::move(trivialFnc),
+ std::move(m_classifyFnc));
+ }
+
+ template<typename _ClassifyFunction>
+ CompactCheck<CheckFunction, TrivialFunction, _ClassifyFunction, T ...> classify(_ClassifyFunction&& classifyFnc)
+ {
+ static_assert(ClassifyFunctionT::valid == false, "Classsify function is already set");
+ return CompactCheck<CheckFunction, TrivialFunction, _ClassifyFunction, T ...>( std::move(m_name),
+ std::move(m_checkFnc),
+ std::move(m_trivialFnc),
+ std::move(classifyFnc));
+ }
+
+ Result test( std::size_t maxSuccess = 100, std::size_t maxDiscarded = 0, std::size_t maxSize = 0)
+ {
+ return quickCheck(*this, maxSuccess, maxDiscarded, maxSize);
+ }
+
+ Result testWithOutput( std::ostream &out = std::cout, std::size_t maxSuccess = 100, std::size_t maxDiscarded = 0, std::size_t maxSize = 0)
+ {
+ return quickCheckOutput(*this, out, maxSuccess, maxDiscarded, maxSize);
+ }
+};
+
+template<typename ... T>
+CompactCheck<void, void, void, T ...> gen()
+{
+ return CompactCheck<void, void, void, T ...>();
+}
+
+template<typename ... T>
+CompactCheck<void, void, void, T ...> gen(const Generator<T>& ... g)
+{
+ return CompactCheck<void, void, void, T ...>(g ...);
+}
+
+
+}
diff --git a/vendor/CppQuickCheck-2018-03-28/include/cppqc/Generator.h b/vendor/CppQuickCheck-2018-03-28/include/cppqc/Generator.h
new file mode 100644
index 00000000..98b96092
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/include/cppqc/Generator.h
@@ -0,0 +1,1355 @@
+/*
+ * Copyright (c) 2010, Gregory Rogers All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CPPQC_GEN_H
+#define CPPQC_GEN_H
+
+#include <boost/function.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <tuple>
+#include <utility>
+#include <cstddef>
+#include <iosfwd>
+#include <vector>
+#include <map>
+#include <algorithm>
+#include <stdexcept>
+#include <random>
+
+namespace cppqc {
+
+typedef std::mt19937 RngEngine;
+
+template<class T> struct Arbitrary;
+
+/*
+ * When creating user defined generators, they must model a
+ * "GeneratorConcept<T>", that is, they must be copy-constructable and have
+ * member functions compatible with the following signatures:
+ *
+ * T unGen(RngEngine &, std::size_t);
+ * std::vector<T> shrink(const T &);
+ *
+ * The unGen function generates a new value, and the shrink function shrinks
+ * the last previously generated value down - generating an std::vector<T> of
+ * possible alternative shrinks. It possible to create a stateful generator
+ * modelling GenConcept, which in the generator stores some state in unGen that
+ * is looked up when calling shrink. Note however that the shrink function may
+ * be called multiple times, the subsequent calls may be called with the
+ * argument being one of the values returned by the previous call to shrink.
+ * This limits the types of statefulness possible.
+ *
+ * GeneratorConcept<T>:
+ * T unGen(RngEngine &, std::size_t);
+ * std::vector<T> shrink(const T &);
+ *
+ * StatelessGeneratorConcept<T> (also models GeneratorConcept<T>):
+ * T unGen(RngEngine &, std::size_t) const;
+ * std::vector<T> shrink(const T &) const;
+ */
+
+
+namespace detail {
+
+ template<class T>
+ struct GenConcept
+ {
+ virtual ~GenConcept()
+ {
+ }
+ virtual T unGen(RngEngine &, std::size_t) = 0;
+ virtual std::vector<T> shrink(const T &) = 0;
+ virtual GenConcept *clone() const = 0;
+ };
+
+ template<class T>
+ struct StatelessGenConcept : GenConcept<T>
+ {
+ virtual ~StatelessGenConcept()
+ {
+ }
+ virtual T unGen(RngEngine &, std::size_t) override = 0;
+ virtual std::vector<T> shrink(const T &) override = 0;
+ virtual StatelessGenConcept *clone() const override = 0;
+ };
+}
+
+template<class T>
+class Generator;
+
+template<class T>
+class StatelessGenerator
+{
+ template<class StatelessGeneratorModel> class StatelessGenModel;
+ public:
+ template<class StatelessGeneratorModel>
+ StatelessGenerator(const StatelessGeneratorModel &gm) :
+ m_gen(new StatelessGenModel<StatelessGeneratorModel>(gm))
+ {
+ }
+
+ StatelessGenerator(const StatelessGenerator &g) :
+ m_gen(g.m_gen->clone())
+ {
+ }
+
+ template<class StatelessGeneratorModel>
+ StatelessGenerator &operator=(const StatelessGeneratorModel &gm)
+ {
+ detail::StatelessGenConcept<T> *tmp =
+ new StatelessGenModel<StatelessGeneratorModel>(gm);
+ delete m_gen;
+ m_gen = tmp;
+ return *this;
+ }
+
+ StatelessGenerator &operator=(const StatelessGenerator &g)
+ {
+ detail::StatelessGenConcept<T> *tmp = g.m_gen.clone();
+ delete m_gen;
+ m_gen = tmp;
+ return *this;
+ }
+
+ ~StatelessGenerator()
+ {
+ delete m_gen;
+ }
+
+ T unGen(RngEngine &rng, std::size_t size) const
+ {
+ return m_gen->unGen(rng, size);
+ }
+
+ std::vector<T> shrink(const T &x) const
+ {
+ return m_gen->shrink(x);
+ }
+
+ private:
+ template<class StatelessGeneratorModel>
+ class StatelessGenModel : public detail::StatelessGenConcept<T>
+ {
+ public:
+ StatelessGenModel(StatelessGeneratorModel gm) : m_obj(std::move(gm))
+ {
+ }
+
+ T unGen(RngEngine &rng, std::size_t size)
+ {
+ return m_obj.unGen(rng, size);
+ }
+
+ T unGen(RngEngine &rng, std::size_t size) const
+ {
+ return m_obj.unGen(rng, size);
+ }
+
+ std::vector<T> shrink(const T &x)
+ {
+ return m_obj.shrink(x);
+ }
+
+ std::vector<T> shrink(const T &x) const
+ {
+ return m_obj.shrink(x);
+ }
+
+ detail::StatelessGenConcept<T> *clone() const
+ {
+ return new StatelessGenModel(m_obj);
+ }
+
+ private:
+ const StatelessGeneratorModel m_obj;
+ };
+
+ friend class Generator<T>;
+ detail::StatelessGenConcept<T> *m_gen;
+};
+
+template<class T>
+class Generator
+{
+ template<class GeneratorModel> class GenModel;
+ public:
+ template<class GeneratorModel>
+ Generator(const GeneratorModel &gm) :
+ m_gen(new GenModel<GeneratorModel>(gm))
+ {
+ }
+
+ Generator(const Generator &g) :
+ m_gen(g.m_gen->clone())
+ {
+ }
+
+ Generator(const StatelessGenerator<T> &g) :
+ m_gen(g.m_gen->clone())
+ {
+ }
+
+ template<class GeneratorModel>
+ Generator &operator=(const GeneratorModel &gm)
+ {
+ detail::GenConcept<T> *tmp = new GenModel<GeneratorModel>(gm);
+ delete m_gen;
+ m_gen = tmp;
+ return *this;
+ }
+
+ Generator &operator=(const Generator &g)
+ {
+ detail::GenConcept<T> *tmp = g.m_gen->clone();
+ delete m_gen;
+ m_gen = tmp;
+ return *this;
+ }
+
+ Generator &operator=(const StatelessGenerator<T> &g)
+ {
+ detail::GenConcept<T> *tmp = g.m_gen->clone();
+ delete m_gen;
+ m_gen = tmp;
+ return *this;
+ }
+
+ ~Generator()
+ {
+ delete m_gen;
+ }
+
+ T unGen(RngEngine &rng, std::size_t size) const
+ {
+ return m_gen->unGen(rng, size);
+ }
+
+ std::vector<T> shrink(const T &x) const
+ {
+ return m_gen->shrink(x);
+ }
+
+ private:
+ template<class GeneratorModel>
+ class GenModel : public detail::GenConcept<T>
+ {
+ public:
+ GenModel(GeneratorModel gm) : m_obj(std::move(gm))
+ {
+ }
+
+ T unGen(RngEngine &rng, std::size_t size) override
+ {
+ return m_obj.unGen(rng, size);
+ }
+
+ std::vector<T> shrink(const T &x) override
+ {
+ return m_obj.shrink(x);
+ }
+
+ detail::GenConcept<T> *clone() const override
+ {
+ return new GenModel(m_obj);
+ }
+
+ private:
+ GeneratorModel m_obj;
+ };
+
+ detail::GenConcept<T> *m_gen;
+};
+
+
+/// Generates some example values and returns them.
+template<class T>
+std::vector<T> sample(const Generator<T> &g, std::size_t num = 0,
+ std::size_t seed = 0)
+{
+ if (num == 0)
+ num = 20;
+ if (seed == 0)
+ seed = time(nullptr);
+ RngEngine rng(seed);
+ std::vector<T> ret;
+ ret.reserve(num);
+ try {
+ for (std::size_t i = 0; i < num; ++i)
+ ret.push_back(g.unGen(rng, i));
+ } catch (...) {
+ }
+ return ret;
+}
+
+/// Generates some example values and prints them.
+template<class T>
+void sampleOutput(const Generator<T> &g,
+ std::ostream &out, std::size_t num = 0,
+ std::size_t seed = 0)
+{
+ if (num == 0)
+ num = 20;
+ if (seed == 0)
+ seed = time(nullptr);
+ RngEngine rng(seed);
+ try {
+ for (std::size_t i = 0; i < num; ++i) {
+ if (i != 0)
+ out << ' ';
+ out << g.unGen(rng, i);
+ }
+ } catch (...) {
+ }
+ out << std::endl;
+}
+
+/// Generates some example values, then generates a list of possible shrinks
+/// for each value and returns both the value and the shrinks.
+template<class T>
+std::vector<std::pair<T, std::vector<T> > > sampleShrink(const Generator<T> &g,
+ std::size_t num = 0, std::size_t seed = 0)
+{
+ if (num == 0)
+ num = 20;
+ if (seed == 0)
+ seed = time(nullptr);
+ RngEngine rng(seed);
+ std::vector<std::pair<T, std::vector<T> > > ret;
+ ret.reserve(num);
+ try {
+ for (std::size_t i = 0; i < num; ++i) {
+ T x = g.unGen(rng, i);
+ ret.push_back(std::make_pair(x, g.shrink(x)));
+ }
+ } catch (...) {
+ }
+ return ret;
+}
+
+/// Outputs some example values from a generator. For each value, outputs
+/// several possible shrinks of that value.
+template<class T>
+void sampleShrinkOutput(const Generator<T> &g, std::ostream &out,
+ std::size_t num = 0, bool randomized = false, std::size_t seed = 0)
+{
+ if (num == 0)
+ num = 20;
+ if (seed == 0)
+ seed = time(nullptr);
+ RngEngine rng(seed);
+ try {
+ for (std::size_t i = 0; i < num; ++i) {
+ T x = g.unGen(rng, i);
+ std::vector<T> shr = g.shrink(x);
+ if (randomized)
+ std::random_shuffle(shr.begin(), shr.end());
+ out << x << " ->";
+ for (std::size_t j = 0; j < num && j < shr.size(); ++j)
+ out << ' ' << shr[j];
+ out << '\n';
+ }
+ } catch (...) {
+ }
+ out << std::flush;
+}
+
+
+// generator combinators
+
+namespace detail {
+ template<class T>
+ class NoShrinkGenerator
+ {
+ public:
+ NoShrinkGenerator(const Generator<T> &g) :
+ m_gen(g)
+ {
+ }
+
+ T unGen(RngEngine &rng, std::size_t size)
+ {
+ return m_gen.unGen(rng, size);
+ }
+
+ std::vector<T> shrink(const T &)
+ {
+ return std::vector<T>();
+ }
+
+ private:
+ Generator<T> m_gen;
+ };
+
+ template<class T>
+ class NoShrinkStatelessGenerator
+ {
+ public:
+ NoShrinkStatelessGenerator(const Generator<T> &g) :
+ m_gen(g)
+ {
+ }
+
+ T unGen(RngEngine &rng, std::size_t size)
+ {
+ return m_gen.unGen(rng, size);
+ }
+
+ std::vector<T> shrink(const T &)
+ {
+ return std::vector<T>();
+ }
+
+ private:
+ StatelessGenerator<T> m_gen;
+ };
+}
+
+// Generates a value the same way as the input generator, but doesn't shrink.
+template<class T>
+Generator<T> noShrink(const Generator<T> &g)
+{
+ return detail::NoShrinkGenerator<T>(g);
+}
+template<class T>
+StatelessGenerator<T> noShrink(const StatelessGenerator<T> &g)
+{
+ return detail::NoShrinkStatelessGenerator<T>(g);
+}
+
+
+namespace detail {
+ template<class T>
+ class SizedGenerator
+ {
+ public:
+ SizedGenerator(boost::function<Generator<T> (std::size_t)> f) :
+ m_genfun(f), m_lastgen(f(0))
+ {
+ }
+
+ T unGen(RngEngine &rng, std::size_t size)
+ {
+ m_lastgen = m_genfun(size);
+ return m_lastgen.unGen(rng, size);
+ }
+
+ std::vector<T> shrink(const T &x)
+ {
+ return m_lastgen.shrink(x);
+ }
+
+ private:
+ const boost::function<Generator<T> (std::size_t)> m_genfun;
+ Generator<T> m_lastgen;
+ };
+}
+
+/// Used to create generators that depend on the size parameter.
+template<class T>
+Generator<T> sized(boost::function<Generator<T> (std::size_t)> f)
+{
+ return detail::SizedGenerator<T>(f);
+}
+
+
+namespace detail {
+ template<class T>
+ class ResizeGenerator
+ {
+ public:
+ ResizeGenerator(std::size_t size, const Generator<T> &g) :
+ m_size(size), m_gen(g)
+ {
+ }
+
+ T unGen(RngEngine &rng, std::size_t)
+ {
+ return m_gen.unGen(rng, m_size);
+ }
+
+ std::vector<T> shrink(const T &x)
+ {
+ return m_gen.shrink(x);
+ }
+
+ private:
+ const std::size_t m_size;
+ const Generator<T> m_gen;
+ };
+
+ template<class T>
+ class ResizeStatelessGenerator
+ {
+ public:
+ ResizeStatelessGenerator(std::size_t size,
+ const StatelessGenerator<T> &g) :
+ m_size(size), m_gen(g)
+ {
+ }
+
+ T unGen(RngEngine &rng, std::size_t) const
+ {
+ return m_gen.unGen(rng, m_size);
+ }
+
+ std::vector<T> shrink(const T &x) const
+ {
+ return m_gen.shrink(x);
+ }
+
+ private:
+ const std::size_t m_size;
+ const StatelessGenerator<T> m_gen;
+ };
+}
+
+/// Overrides the size parameter. Returns a generator which uses the given size
+/// instead of the runtime size parameter.
+template<class T>
+Generator<T> resize(std::size_t size, const Generator<T> &g)
+{
+ return detail::ResizeGenerator<T>(size, g);
+}
+template<class T>
+StatelessGenerator<T> resize(std::size_t size, const StatelessGenerator<T> &g)
+{
+ return detail::ResizeStatelessGenerator<T>(size, g);
+}
+
+
+namespace detail {
+ template<class Integer>
+ class ChooseStatelessGenerator
+ {
+ public:
+ ChooseStatelessGenerator(Integer min, Integer max) :
+ m_min(min), m_max(max)
+ {
+ assert(min <= max);
+ }
+
+ Integer unGen(RngEngine &rng, std::size_t) const
+ {
+ boost::uniform_int<Integer> dist(m_min, m_max);
+ return dist(rng);
+ }
+
+ std::vector<Integer> shrink(Integer x) const
+ {
+ std::vector<Integer> ret;
+ ret.reserve(x - m_min);
+ if (abs(m_min) <= abs(m_max)) {
+ for (Integer i = m_min; i != x; ++i)
+ ret.push_back(i);
+ } else {
+ for (Integer i = m_max; i != x; --i)
+ ret.push_back(i);
+ }
+ return ret;
+ }
+
+ private:
+ const Integer m_min;
+ const Integer m_max;
+ };
+}
+
+/// Generates a random integer in the range min..max inclusive, requires that
+/// min <= max. Shrinks towards smaller absolute values.
+template<class Integer>
+StatelessGenerator<Integer> choose(Integer min, Integer max)
+{
+ return detail::ChooseStatelessGenerator<Integer>(min, max);
+}
+
+
+namespace detail {
+ template<class T>
+ class SuchThatGenerator
+ {
+ public:
+ SuchThatGenerator(const Generator<T> &g,
+ boost::function<bool (T)> pred) :
+ m_gen(g), m_pred(pred)
+ {
+ }
+
+ T unGen(RngEngine &rng, std::size_t size)
+ {
+ T ret = m_gen.unGen(rng, size);
+ if (!m_pred(ret))
+ throw std::runtime_error("suchThat: generated value did not satisfy pred");
+ return ret;
+ }
+
+ std::vector<T> shrink(const T &x)
+ {
+ std::vector<T> ret = m_gen.shrink(x);
+ ret.erase(std::remove_if(ret.begin(), ret.end(),
+ std::not1(m_pred)), ret.end());
+ return ret;
+ }
+
+ private:
+ const Generator<T> m_gen;
+ const boost::function<bool (T)> m_pred;
+ };
+
+ template<class T>
+ class SuchThatStatelessGenerator
+ {
+ public:
+ SuchThatStatelessGenerator(const StatelessGenerator<T> &g,
+ boost::function<bool (T)> pred) :
+ m_gen(g), m_pred(pred)
+ {
+ }
+
+ T unGen(RngEngine &rng, std::size_t size) const
+ {
+ T ret = m_gen.unGen(rng, size);
+ if (!m_pred(ret))
+ throw std::runtime_error("suchThat: generated value did not satisfy pred");
+ return ret;
+ }
+
+ std::vector<T> shrink(const T &x) const
+ {
+ std::vector<T> ret = m_gen.shrink(x);
+ ret.erase(std::remove_if(ret.begin(), ret.end(),
+ std::not1(m_pred)), ret.end());
+ return ret;
+ }
+
+ private:
+ const StatelessGenerator<T> m_gen;
+ const boost::function<bool (T)> m_pred;
+ };
+}
+
+/// Generates a value that satisfies a predicate.
+template<class T, class Pred>
+Generator<T> suchThat(const Generator<T> &g, Pred pred)
+{
+ return detail::SuchThatGenerator<T>(g, pred);
+}
+template<class T, class Pred>
+StatelessGenerator<T> suchThat(const StatelessGenerator<T> &g, Pred pred)
+{
+ return detail::SuchThatStatelessGenerator<T>(g, pred);
+}
+
+
+namespace detail {
+ template<class T>
+ class OneOfGenerator
+ {
+ public:
+ OneOfGenerator &operator()(const Generator<T> &g)
+ {
+ m_gens.push_back(g);
+ return *this;
+ }
+
+ T unGen(RngEngine &rng, std::size_t size)
+ {
+ boost::uniform_int<std::size_t> dist(0, m_gens.size() - 1);
+ m_last_index = dist(rng);
+ return m_gens[m_last_index].unGen(rng, size);
+ }
+
+ std::vector<T> shrink(const T &x)
+ {
+ return m_gens[m_last_index].shrink(x);
+ }
+
+ private:
+ std::vector<Generator<T> > m_gens;
+ std::size_t m_last_index;
+ };
+}
+
+/// Randomly uses one of the given generators.
+template<class T>
+detail::OneOfGenerator<T> oneof(const Generator<T> &g)
+{
+ detail::OneOfGenerator<T> ret;
+ return ret(g);
+}
+
+
+namespace detail {
+ template<class T>
+ class FrequencyGenerator
+ {
+ public:
+ FrequencyGenerator() : m_tot(0)
+ {
+ }
+
+ FrequencyGenerator &operator()(std::size_t weight,
+ const Generator<T> &g)
+ {
+ if (weight != 0) {
+ m_tot += weight;
+ m_gens.insert(std::make_pair(m_tot, g));
+ }
+ return *this;
+ }
+
+ T unGen(RngEngine &rng, std::size_t size)
+ {
+ boost::uniform_int<std::size_t> dist(1, m_tot);
+ std::size_t weight = dist(rng);
+ typename std::map<std::size_t, Generator<T> >::iterator it =
+ m_gens.lower_bound(weight);
+ if (it == m_gens.end()) {
+ throw std::logic_error("frequency: all generators have weight 0");
+ } else {
+ m_last_index = it->first;
+ return it->second.unGen(rng, size);
+ }
+ }
+
+ std::vector<T> shrink(const T &x)
+ {
+ typename std::map<std::size_t, Generator<T> >::iterator it =
+ m_gens.find(m_last_index);
+ assert(it != m_gens.end());
+ return it->second.shrink(x);
+ }
+
+ private:
+ std::map<std::size_t, Generator<T> > m_gens;
+ std::size_t m_tot;
+ std::size_t m_last_index;
+ };
+}
+
+/// Chooses one of the given generators, with a weighted random distribution.
+/// Any generator with weight "0" will not be chosen.
+template<class T>
+detail::FrequencyGenerator<T> frequency(std::size_t f, const Generator<T> &g)
+{
+ detail::FrequencyGenerator<T> ret;
+ return ret(f, g);
+}
+
+
+namespace detail {
+ template<class T>
+ class ElementsGenerator
+ {
+ public:
+ ElementsGenerator &operator()(const std::initializer_list<T> x)
+ {
+ for (auto &i: x)
+ m_elems.push_back(i);
+ return *this;
+ }
+
+ ElementsGenerator &operator()(const T &x)
+ {
+ m_elems.push_back(x);
+ return *this;
+ }
+
+ T unGen(RngEngine &rng, std::size_t /*size*/)
+ {
+ boost::uniform_int<std::size_t> dist(0, m_elems.size() - 1);
+ m_last_index = dist(rng);
+ return m_elems[m_last_index];
+ }
+
+ std::vector<T> shrink(const T &)
+ {
+ std::vector<T> ret;
+ ret.reserve(m_last_index);
+ for (std::size_t i = 0; i != m_last_index; ++i)
+ ret.push_back(m_elems[i]);
+ return ret;
+ }
+
+ private:
+ std::vector<T> m_elems;
+ std::size_t m_last_index;
+ };
+}
+
+/// Generates one of the given values.
+template<class T>
+detail::ElementsGenerator<T> elements(const std::initializer_list<T> x)
+{
+ detail::ElementsGenerator<T> ret;
+ return ret(x);
+}
+
+template<class T>
+detail::ElementsGenerator<T> elements(const T &x)
+{
+ detail::ElementsGenerator<T> ret;
+ return ret(x);
+}
+
+
+namespace detail {
+ template<class T>
+ class FixedGenerator
+ {
+ public:
+ FixedGenerator() : m_last_index_plus_one(0)
+ {
+ }
+
+ FixedGenerator &operator()(const T &x)
+ {
+ m_fixed.push_back(x);
+ return *this;
+ }
+
+ T unGen(RngEngine &, std::size_t)
+ {
+ ++m_last_index_plus_one;
+ if (m_last_index_plus_one >= m_fixed.size()) {
+ throw std::runtime_error("fixed: exhausted fixed test cases");
+ } else {
+ return m_fixed[m_last_index_plus_one];
+ }
+ }
+
+ std::vector<T> shrink(const T &)
+ {
+ return std::vector<T>();
+ }
+
+ private:
+ std::size_t m_last_index_plus_one;
+ std::vector<T> m_fixed;
+ };
+}
+
+/// Generates each fixed test case until all have been generated. Does not
+/// shrink. Especially useful with "chain".
+template<class T>
+detail::FixedGenerator<T> fixed(const T &x)
+{
+ detail::FixedGenerator<T> ret;
+ return ret(x);
+}
+
+
+namespace detail {
+ template<class T>
+ class ChainGenerator
+ {
+ public:
+ ChainGenerator() : m_last_index(0)
+ {
+ }
+
+ ChainGenerator &operator()(const Generator<T> &x)
+ {
+ m_gens.push_back(x);
+ return *this;
+ }
+
+ T unGen(RngEngine &rng, std::size_t size)
+ {
+ for (m_last_index = 0; m_last_index < m_gens.size();
+ ++m_last_index) {
+ try {
+ return m_gens[m_last_index].unGen(rng, size);
+ } catch (...) {
+ }
+ }
+
+ throw std::runtime_error("chain: exhausted all possible generators");
+ }
+
+ std::vector<T> shrink(const T &x)
+ {
+ return m_gens[m_last_index].shrink(x);
+ }
+
+ private:
+ std::size_t m_last_index;
+ std::vector<Generator<T> > m_gens;
+ };
+}
+
+/// Attempts to generate from each generator, if a generator fails to generate
+/// input, the next one is tried.
+template<class T>
+detail::ChainGenerator<T> chain(const Generator<T> &g)
+{
+ detail::ChainGenerator<T> ret;
+ return ret(g);
+}
+
+
+namespace detail {
+ template<class T, class U>
+ class ConvertGenerator
+ {
+ public:
+ ConvertGenerator(boost::function<T (U)> f, const Generator<U> &g) :
+ m_convert(f), m_gen(g)
+ {
+ }
+
+ T unGen(RngEngine &rng, std::size_t size)
+ {
+ m_lastgen_u.clear();
+ m_lastgen_t.clear();
+ m_lastgen_u.push_back(m_gen.unGen(rng, size));
+ m_lastgen_t.push_back(m_convert(m_lastgen_u.back()));
+ return m_lastgen_t.back();
+ }
+
+ std::vector<T> shrink(const T &x)
+ {
+ typename std::vector<T>::iterator it =
+ std::find(m_lastgen_t.begin(), m_lastgen_t.end(), x);
+ assert(it != m_lastgen_t.end());
+ U last_u = m_lastgen_u[it - m_lastgen_t.begin()];
+ m_lastgen_t.clear();
+ m_lastgen_u = m_gen.shrink(last_u);
+ m_lastgen_t.reserve(m_lastgen_u.size());
+ std::transform(m_lastgen_u.begin(), m_lastgen_u.end(),
+ std::back_inserter(m_lastgen_t), m_convert);
+ return m_lastgen_t;
+ }
+
+ private:
+ boost::function<T (U)> m_convert;
+ const Generator<U> m_gen;
+ std::vector<T> m_lastgen_t;
+ std::vector<U> m_lastgen_u;
+ };
+}
+
+/// Converts a generator of U's into a generator of T's by passing the results
+/// through a function which converts U's into T's.
+template<class T, class U>
+Generator<T> convert(boost::function<T (U)> f,
+ const Generator<U> &g = Arbitrary<U>())
+{
+ return detail::ConvertGenerator<T, U>(f, g);
+}
+
+/// Convenience function to aid generic programming, equivalent to convert.
+template<class T, class U1>
+Generator<T> combine(boost::function<T (U1)> f,
+ const Generator<U1> &g1 = Arbitrary<U1>())
+{
+ return detail::ConvertGenerator<T, U1>(f, g1);
+}
+
+
+namespace detail {
+ template<class T, class U1, class U2>
+ class CombineGenerator
+ {
+ public:
+ CombineGenerator(boost::function<T (U1, U2)> f,
+ const Generator<U1> &g1,
+ const Generator<U2> &g2) :
+ m_combine(f), m_gen1(g1), m_gen2(g2)
+ {
+ }
+
+ T unGen(RngEngine &rng, std::size_t size)
+ {
+ m_lastgen_u1.clear();
+ m_lastgen_u2.clear();
+ m_lastgen_t.clear();
+ m_lastgen_u1.push_back(m_gen1.unGen(rng, size));
+ m_lastgen_u2.push_back(m_gen2.unGen(rng, size));
+ m_lastgen_t.push_back(m_combine(m_lastgen_u1.back(),
+ m_lastgen_u2.back()));
+ return m_lastgen_t.back();
+ }
+
+ std::vector<T> shrink(const T &x)
+ {
+ typename std::vector<T>::const_iterator it =
+ std::find(m_lastgen_t.begin(), m_lastgen_t.end(), x);
+ assert(it != m_lastgen_t.end());
+ std::size_t dist = it - m_lastgen_t.begin();
+ U1 last_u1 = m_lastgen_u1[dist];
+ U2 last_u2 = m_lastgen_u2[dist];
+ m_lastgen_t.clear();
+ std::vector<U1> shrink1 = m_gen1.shrink(last_u1);
+ std::vector<U2> shrink2 = m_gen2.shrink(last_u2);
+ m_lastgen_u1.assign(shrink1.begin(), shrink1.end());
+ m_lastgen_u1.insert(m_lastgen_u1.end(),
+ shrink2.size(), last_u1);
+ m_lastgen_u2.assign(shrink1.size(), last_u2);
+ m_lastgen_u2.insert(m_lastgen_u2.end(),
+ shrink2.begin(), shrink2.end());
+
+ m_lastgen_t.reserve(m_lastgen_u1.size());
+ std::transform(m_lastgen_u1.begin(), m_lastgen_u1.end(),
+ m_lastgen_u2.begin(), std::back_inserter(m_lastgen_t),
+ m_combine);
+ return m_lastgen_t;
+ }
+
+ private:
+ boost::function<T (U1, U2)> m_combine;
+ const Generator<U1> m_gen1;
+ const Generator<U2> m_gen2;
+ std::vector<T> m_lastgen_t;
+ std::vector<U1> m_lastgen_u1;
+ std::vector<U2> m_lastgen_u2;
+ };
+}
+
+/// Combines generators of U1's and U2's into a generator of T's by passing the
+/// results through a function which converts U1's and U2's into T's. Ie. the
+/// same as convert for functions taking more than one argument.
+template<class T, class U1, class U2>
+Generator<T> combine(boost::function<T (U1, U2)> f,
+ const Generator<U1> &g1 = Arbitrary<U1>(),
+ const Generator<U2> &g2 = Arbitrary<U2>())
+{
+ return detail::CombineGenerator<T, U1, U2>(f, g1, g2);
+}
+
+
+namespace detail {
+ template<class T>
+ class ListOfStatelessGenerator
+ {
+ public:
+ ListOfStatelessGenerator(const StatelessGenerator<T> &g) : m_gen(g)
+ {
+ }
+
+ std::vector<T> unGen(RngEngine &rng, std::size_t size) const
+ {
+ boost::uniform_int<std::size_t> dist(0, size);
+ std::size_t n = dist(rng);
+ std::vector<T> ret;
+ ret.reserve(n);
+ while (n-- > 0)
+ ret.push_back(m_gen.unGen(rng, size));
+ return ret;
+ }
+
+ std::vector<std::vector<T>> shrink(const std::vector<T> &v) const
+ {
+ std::vector<std::vector<T>> result;
+
+ // 1) leave one element out (reduces size of new arrays by one)
+ for(auto it = v.begin(); it != v.end(); ++it) {
+ typename std::vector<T> shortendV;
+ shortendV.reserve(v.size() - 1);
+ shortendV.insert(shortendV.end(), v.begin(), it);
+ shortendV.insert(shortendV.end(), it + 1, v.end());
+ assert(shortendV.size() == v.size() - 1);
+ result.push_back(std::move(shortendV));
+ }
+
+ // 2) shrink each element
+ // (array size stays the same but inner elements shrink)
+ for(int i = 0; i < static_cast<int>(v.size()); ++i) {
+ typename std::vector<T> shrinkedTypes = Arbitrary<T>::shrink(v[i]);
+ for(T &shrinked : Arbitrary<T>::shrink(v[i])) {
+ auto copy = v;
+ copy[i] = std::move(shrinked);
+ result.push_back(std::move(copy));
+ }
+ }
+ return result;
+ }
+
+ private:
+ const StatelessGenerator<T> m_gen;
+ };
+}
+
+/// Generates an std::vector of random length. The maximum length depends on the
+/// generation size parameter. Shrinks by removing elements from the vector.
+template<class T>
+StatelessGenerator<std::vector<T>> listOf(
+ const StatelessGenerator<T> &g = Arbitrary<T>())
+{
+ return detail::ListOfStatelessGenerator<T>(g);
+}
+
+
+namespace detail {
+ template<class T>
+ class ListOfNonEmptyStatelessGenerator
+ {
+ public:
+ ListOfNonEmptyStatelessGenerator(const StatelessGenerator<T> &g) :
+ m_gen(g), m_vectorGen(listOf<T>(g))
+ {
+ }
+
+ std::vector<T> unGen(RngEngine &rng, std::size_t size) const
+ {
+ std::vector<T> result = m_vectorGen.unGen(rng, size);
+ if (result.empty())
+ result.emplace_back(m_gen.unGen(rng, size));
+ return result;
+ }
+
+ std::vector<std::vector<T>> shrink(const std::vector<T> &x) const
+ {
+ assert(!x.empty());
+
+ // TODO: should work for now, but uses (too much?!) internal
+ // knowledge of the "ListOfStatelessGenerator"
+ // shrink function implementation
+ if (x.size() > 1)
+ return m_vectorGen.shrink(x);
+ else
+ return {};
+ }
+
+ private:
+ const StatelessGenerator<T> m_gen;
+ const StatelessGenerator<std::vector<T>> m_vectorGen;
+ };
+}
+
+/// Generates a non-empty std::vector of random length. The maximum length
+/// depends on the generation size parameter. Shrinks by removing elements from
+/// the vector.
+template<class T>
+StatelessGenerator<std::vector<T>> listOfNonEmpty(
+ const StatelessGenerator<T> &g = Arbitrary<T>())
+{
+ return detail::ListOfNonEmptyStatelessGenerator<T>(g);
+}
+
+
+namespace detail {
+ template<class T, std::size_t N>
+ class ArrayOfStatelessGenerator
+ {
+ public:
+ ArrayOfStatelessGenerator(const StatelessGenerator<T> &g) :
+ m_gen(g)
+ {
+ }
+
+ std::array<T, N> unGen(RngEngine &rng, std::size_t size) const
+ {
+ std::array<T, N> result;
+ for (size_t i = 0; i < N; i++)
+ result[i] = m_gen.unGen(rng, size);
+ return result;
+ }
+
+ std::vector<std::array<T, N>> shrink(
+ const std::array<T, N> &arr) const
+ {
+ std::vector<std::array<T, N>> result;
+
+ // shrink each element
+ // (array size stays the same but inner elements shrink)
+ for (size_t i = 0; i < N; i++) {
+ for (const auto &shrinkedInnerElem : m_gen.shrink(arr[i])) {
+ auto copy = arr;
+ copy[i] = shrinkedInnerElem;
+ result.push_back(std::move(copy));
+ }
+ }
+
+ return result;
+ }
+
+ private:
+ const StatelessGenerator<T> m_gen;
+ };
+}
+
+/// Generates an std::array of fixed length N.
+/// As the array's length is fixed, it cannot be shrunken.
+/// However, its inner elements can be.
+template<class T, std::size_t N>
+StatelessGenerator<std::array<T, N>> arrayOf(
+ const StatelessGenerator<T> &g = Arbitrary<T>())
+{
+ return detail::ArrayOfStatelessGenerator<T, N>(g);
+}
+
+
+namespace detail {
+ template<class T>
+ class VectorOfStatelessGenerator
+ {
+ public:
+ VectorOfStatelessGenerator(std::size_t size,
+ const StatelessGenerator<T> &g) :
+ m_size(size), m_gen(g)
+ {
+ }
+
+ std::vector<T> unGen(RngEngine &rng, std::size_t size) const
+ {
+ std::vector<T> ret;
+ std::size_t n = m_size;
+ ret.reserve(n);
+ while (n-- > 0)
+ ret.push_back(m_gen.unGen(rng, size));
+ return ret;
+ }
+
+ std::vector<std::vector<T> > shrink(const std::vector<T> &) const
+ {
+ return std::vector<std::vector<T> >();
+ }
+
+ private:
+ std::size_t m_size;
+ const StatelessGenerator<T> m_gen;
+ };
+}
+
+/// Generates an std::vector of the given length. Does not shrink. Prefer using
+/// listOf or listOfNonEmpty to vectorOf because those can shrink.
+template<class T>
+StatelessGenerator<std::vector<T> > vectorOf(std::size_t size,
+ const StatelessGenerator<T> &g = Arbitrary<T>())
+{
+ return detail::VectorOfStatelessGenerator<T>(size, g);
+}
+
+
+namespace detail {
+
+ template<int offset, typename T, typename... Ts>
+ struct TupleGeneratorHelper_unGen
+ {
+ template <typename Generators>
+ static std::tuple<T, Ts...> unGen(RngEngine &rng, std::size_t size,
+ const Generators &generators)
+ {
+ return std::tuple_cat(
+ std::make_tuple(std::get<offset>(generators).unGen(rng, size)),
+ TupleGeneratorHelper_unGen<
+ offset + 1, Ts...>::unGen(rng, size, generators));
+ }
+ };
+
+ template<int offset, typename T>
+ struct TupleGeneratorHelper_unGen<offset, T>
+ {
+ template <typename Generators>
+ static std::tuple<T> unGen(RngEngine &rng, std::size_t size,
+ const Generators &generators)
+ {
+ return std::tuple<T>(std::get<offset>(generators).unGen(rng, size));
+ }
+ };
+
+ template<int offset, typename... T>
+ struct TupleGeneratorHelper_shrink
+ {
+ template <typename Generators>
+ static void appendShrinks(const std::tuple<T...> &shrinkInput,
+ std::vector<std::tuple<T...>>& shrinkOutput,
+ const Generators &generators)
+ {
+ // Compute all shrink combinations for the tuple
+ // element at the position "offset".
+ // All other elements will not be changed.
+ static_assert(offset >= 0 && offset < sizeof...(T),
+ "offset out of bounds");
+ auto allLocalShrinks =
+ std::get<offset>(generators).shrink(std::get<offset>(shrinkInput));
+ for (auto&& localShrink : allLocalShrinks) {
+ auto copiedShrinkInput = shrinkInput;
+ std::get<offset>(copiedShrinkInput) = std::move(localShrink);
+ shrinkOutput.push_back(std::move(copiedShrinkInput));
+ }
+
+ // continue recursion (from right to left)
+ TupleGeneratorHelper_shrink<offset - 1, T...>::appendShrinks(
+ shrinkInput, shrinkOutput, generators);
+ }
+ };
+
+ template<typename... T>
+ struct TupleGeneratorHelper_shrink<-1, T...>
+ {
+ template <typename Generators>
+ static void appendShrinks(const std::tuple<T...> & /*shrinkInput*/,
+ std::vector<std::tuple<T...>> & /*shrinkOutput*/,
+ const Generators & /*generators*/)
+ {
+ // nothing to do (end of recursion)
+ }
+ };
+
+ template<typename... T>
+ struct TupleGenerator
+ {
+ TupleGenerator(const Generator<T> &...g) :
+ m_gen(g...)
+ {
+ }
+
+ std::tuple<T...> unGen(RngEngine &rng, std::size_t size) const
+ {
+ return TupleGeneratorHelper_unGen<0, T...>::unGen(rng, size, m_gen);
+ }
+
+ std::vector<std::tuple<T...>> shrink(const std::tuple<T...> &shrinkInput) const
+ {
+ std::vector<std::tuple<T...>> shrinkOutput;
+ constexpr auto last_index = sizeof...(T) - 1;
+ TupleGeneratorHelper_shrink<last_index, T...>::appendShrinks(
+ shrinkInput, shrinkOutput, m_gen);
+ return shrinkOutput;
+ }
+
+ private:
+ std::tuple<Generator<T>...> m_gen;
+ };
+
+}
+
+template<typename... T>
+Generator<std::tuple<T...>> tupleOf(const Generator<T> &...g)
+{
+ return detail::TupleGenerator<T...>(g...);
+}
+
+template<typename... T>
+Generator<std::tuple<T...>> tupleOf()
+{
+ return detail::TupleGenerator<T...>(Arbitrary<T>()...);
+}
+
+
+}
+
+#endif
diff --git a/vendor/CppQuickCheck-2018-03-28/include/cppqc/PrettyPrint.h b/vendor/CppQuickCheck-2018-03-28/include/cppqc/PrettyPrint.h
new file mode 100644
index 00000000..2285cfb6
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/include/cppqc/PrettyPrint.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2010, Gregory Rogers All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CPPQC_PRETTY_PRINT_H
+#define CPPQC_PRETTY_PRINT_H
+
+#include "cxx-prettyprint.h"
+#include <string>
+#include <sstream>
+
+namespace cppqc {
+
+ // The default implementation falls back to the std::ofstream
+ // implementation. Note that because of the usage of "cxx-prettyprint",
+ // it can handle understands C++ containers, pairs and tuples.
+ //
+ // Strings are quoted to improve readability.
+ //
+ template <class T>
+ struct PrettyPrint
+ {
+ static std::string toString(const T& x)
+ {
+ std::ostringstream out;
+ out << x;
+ return out.str();
+ }
+ };
+
+ template <>
+ struct PrettyPrint<std::string>
+ {
+ static std::string toString(const std::string& x)
+ {
+ return '\"' + x + '\"';
+ }
+ };
+
+ template <class T>
+ std::string prettyPrint(const T& x)
+ {
+ return PrettyPrint<T>::toString(x);
+ }
+
+}
+
+#endif
diff --git a/vendor/CppQuickCheck-2018-03-28/include/cppqc/Property.h b/vendor/CppQuickCheck-2018-03-28/include/cppqc/Property.h
new file mode 100644
index 00000000..579e6c53
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/include/cppqc/Property.h
@@ -0,0 +1,461 @@
+/*
+ * Copyright (c) 2010, Gregory Rogers All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CPPQC_PROPERTY_H
+#define CPPQC_PROPERTY_H
+
+#include "Generator.h"
+#include "PrettyPrint.h"
+
+namespace cppqc {
+
+namespace detail {
+ struct null_type {};
+}
+
+class PropertyBase
+{
+ public:
+ // By default, it is expected that every check passes.
+ virtual bool expect() const { return true; }
+
+ // Should be overwriten by subclasses, as the default
+ // implementation is compiler dependent.
+ // (However, in practice, gcc and clang produce useful defaults.)
+ virtual std::string name() const { return typeid(*this).name(); }
+
+ virtual ~PropertyBase() {}
+};
+
+template<class T0, class T1 = detail::null_type, class T2 = detail::null_type,
+ class T3 = detail::null_type, class T4 = detail::null_type>
+class Property : public PropertyBase
+{
+ public:
+ typedef std::tuple<T0, T1, T2, T3, T4> Input;
+
+ Property(const Generator<T0> &g0 = Arbitrary<T0>(),
+ const Generator<T1> &g1 = Arbitrary<T1>(),
+ const Generator<T2> &g2 = Arbitrary<T2>(),
+ const Generator<T3> &g3 = Arbitrary<T3>(),
+ const Generator<T4> &g4 = Arbitrary<T4>()) :
+ m_gen(tupleOf(g0, g1, g2, g3, g4))
+ {
+ }
+
+ Input generateInput(RngEngine &rng, std::size_t size) const
+ {
+ return m_gen.unGen(rng, size);
+ }
+ std::vector<Input> shrinkInput(const Input &in) const
+ {
+ return m_gen.shrink(in);
+ }
+ bool trivialInput(const Input &in) const
+ {
+ return trivial(std::get<0>(in), std::get<1>(in),
+ std::get<2>(in), std::get<3>(in), std::get<4>(in));
+ }
+ std::string classifyInput(const Input &in) const
+ {
+ return classify(std::get<0>(in), std::get<1>(in),
+ std::get<2>(in), std::get<3>(in), std::get<4>(in));
+ }
+ bool checkInput(const Input &in) const
+ {
+ return check(std::get<0>(in), std::get<1>(in),
+ std::get<2>(in), std::get<3>(in), std::get<4>(in));
+ }
+
+ private:
+ virtual bool trivial(const T0 &, const T1 &, const T2 &, const T3 &,
+ const T4 &) const
+ {
+ return false;
+ }
+
+ virtual std::string classify(const T0 &, const T1 &, const T2 &,
+ const T3 &, const T4 &) const
+ {
+ return "";
+ }
+
+ virtual bool check(const T0 &, const T1 &, const T2 &,
+ const T3 &, const T4 &) const = 0;
+
+ private:
+ const Generator<Input> m_gen;
+};
+
+template<class T0>
+class Property<T0, detail::null_type, detail::null_type, detail::null_type,
+ detail::null_type> : public PropertyBase
+{
+ public:
+ typedef std::tuple<T0> Input;
+
+ Property(const Generator<T0> &g0 = Arbitrary<T0>()) :
+ m_gen(tupleOf(g0))
+ {
+ }
+
+ Input generateInput(RngEngine &rng, std::size_t size) const
+ {
+ return m_gen.unGen(rng, size);
+ }
+ std::vector<Input> shrinkInput(const Input &in) const
+ {
+ return m_gen.shrink(in);
+ }
+ bool trivialInput(const Input &in) const
+ {
+ return trivial(std::get<0>(in));
+ }
+ std::string classifyInput(const Input &in) const
+ {
+ return classify(std::get<0>(in));
+ }
+ bool checkInput(const Input &in) const
+ {
+ return check(std::get<0>(in));
+ }
+
+ private:
+ virtual bool trivial(const T0 &) const
+ {
+ return false;
+ }
+
+ virtual std::string classify(const T0 &) const
+ {
+ return "";
+ }
+
+ virtual bool check(const T0 &) const = 0;
+
+ private:
+ const Generator<Input> m_gen;
+};
+
+template<class T0, class T1>
+class Property<T0, T1, detail::null_type, detail::null_type,
+ detail::null_type> : public PropertyBase
+{
+ public:
+ typedef std::tuple<T0, T1> Input;
+
+ Property(const Generator<T0> &g0 = Arbitrary<T0>(),
+ const Generator<T1> &g1 = Arbitrary<T1>()) :
+ m_gen(tupleOf(g0, g1))
+ {
+ }
+
+ Input generateInput(RngEngine &rng, std::size_t size) const
+ {
+ return m_gen.unGen(rng, size);
+ }
+ std::vector<Input> shrinkInput(const Input &in) const
+ {
+ return m_gen.shrink(in);
+ }
+ bool trivialInput(const Input &in) const
+ {
+ return trivial(std::get<0>(in), std::get<1>(in));
+ }
+ std::string classifyInput(const Input &in) const
+ {
+ return classify(std::get<0>(in), std::get<1>(in));
+ }
+ bool checkInput(const Input &in) const
+ {
+ return check(std::get<0>(in), std::get<1>(in));
+ }
+
+ private:
+ virtual bool trivial(const T0 &, const T1 &) const
+ {
+ return false;
+ }
+
+ virtual std::string classify(const T0 &, const T1 &) const
+ {
+ return "";
+ }
+
+ virtual bool check(const T0 &, const T1 &) const = 0;
+
+ private:
+ const Generator<Input> m_gen;
+};
+
+template<class T0, class T1, class T2>
+class Property<T0, T1, T2, detail::null_type, detail::null_type> :
+ public PropertyBase
+{
+ public:
+ typedef std::tuple<T0, T1, T2> Input;
+
+ Property(const Generator<T0> &g0 = Arbitrary<T0>(),
+ const Generator<T1> &g1 = Arbitrary<T1>(),
+ const Generator<T2> &g2 = Arbitrary<T2>()) :
+ m_gen(tupleOf(g0, g1, g2))
+ {
+ }
+
+ Input generateInput(RngEngine &rng, std::size_t size) const
+ {
+ return m_gen.unGen(rng, size);
+ }
+ std::vector<Input> shrinkInput(const Input &in) const
+ {
+ return m_gen.shrink(in);
+ }
+ bool trivialInput(const Input &in) const
+ {
+ return trivial(std::get<0>(in), std::get<1>(in),
+ std::get<2>(in));
+ }
+ std::string classifyInput(const Input &in) const
+ {
+ return classify(std::get<0>(in), std::get<1>(in),
+ std::get<2>(in));
+ }
+ bool checkInput(const Input &in) const
+ {
+ return check(std::get<0>(in), std::get<1>(in),
+ std::get<2>(in));
+ }
+
+ private:
+ virtual bool trivial(const T0 &, const T1 &, const T2 &) const
+ {
+ return false;
+ }
+
+ virtual std::string classify(const T0 &, const T1 &, const T2 &) const
+ {
+ return "";
+ }
+
+ virtual bool check(const T0 &, const T1 &, const T2 &) const = 0;
+
+ private:
+ const Generator<Input> m_gen;
+};
+
+template<class T0, class T1, class T2, class T3>
+class Property<T0, T1, T2, T3, detail::null_type> : public PropertyBase
+{
+ public:
+ typedef std::tuple<T0, T1, T2, T3> Input;
+
+ Property(const Generator<T0> &g0 = Arbitrary<T0>(),
+ const Generator<T1> &g1 = Arbitrary<T1>(),
+ const Generator<T2> &g2 = Arbitrary<T2>(),
+ const Generator<T3> &g3 = Arbitrary<T3>()) :
+ m_gen(tupleOf(g0, g1, g2, g3))
+ {
+ }
+
+ Input generateInput(RngEngine &rng, std::size_t size) const
+ {
+ return m_gen.unGen(rng, size);
+ }
+ std::vector<Input> shrinkInput(const Input &in) const
+ {
+ return m_gen.shrink(in);
+ }
+ bool trivialInput(const Input &in) const
+ {
+ return trivial(std::get<0>(in), std::get<1>(in),
+ std::get<2>(in), std::get<3>(in));
+ }
+ std::string classifyInput(const Input &in) const
+ {
+ return classify(std::get<0>(in), std::get<1>(in),
+ std::get<2>(in), std::get<3>(in));
+ }
+ bool checkInput(const Input &in) const
+ {
+ return check(std::get<0>(in), std::get<1>(in),
+ std::get<2>(in), std::get<3>(in));
+ }
+
+ private:
+ virtual bool trivial(const T0 &, const T1 &, const T2 &,
+ const T3 &) const
+ {
+ return false;
+ }
+
+ virtual std::string classify(const T0 &, const T1 &, const T2 &,
+ const T3 &) const
+ {
+ return "";
+ }
+
+ virtual bool check(const T0 &, const T1 &, const T2 &,
+ const T3 &) const = 0;
+
+ private:
+ const Generator<Input> m_gen;
+};
+
+
+// named
+// expectFailure
+// classifyWith
+// trivializeWith
+
+ template<class T0>
+ std::ostream &printInput(std::ostream &out, const std::tuple<T0> &in)
+ {
+ return out << " 0: " << prettyPrint(std::get<0>(in)) << '\n'
+ << std::flush;
+ }
+
+ template<class T0, class T1>
+ std::ostream &printInput(std::ostream &out, const std::tuple<T0, T1> &in)
+ {
+ return out << " 0: " << prettyPrint(std::get<0>(in)) << '\n'
+ << " 1: " << prettyPrint(std::get<1>(in)) << '\n'
+ << std::flush;
+ }
+
+ template<class T0, class T1, class T2>
+ std::ostream &printInput(std::ostream &out,
+ const std::tuple<T0, T1, T2> &in)
+ {
+ return out << " 0: " << prettyPrint(std::get<0>(in)) << '\n'
+ << " 1: " << prettyPrint(std::get<1>(in)) << '\n'
+ << " 2: " << prettyPrint(std::get<2>(in)) << '\n'
+ << std::flush;
+ }
+
+ template<class T0, class T1, class T2, class T3>
+ std::ostream &printInput(std::ostream &out,
+ const std::tuple<T0, T1, T2, T3> &in)
+ {
+ return out << " 0: " << prettyPrint(std::get<0>(in)) << '\n'
+ << " 1: " << prettyPrint(std::get<1>(in)) << '\n'
+ << " 2: " << prettyPrint(std::get<2>(in)) << '\n'
+ << " 3: " << prettyPrint(std::get<3>(in)) << '\n'
+ << std::flush;
+ }
+
+ template<class T0, class T1, class T2, class T3, class T4>
+ std::ostream &printInput(std::ostream &out,
+ const std::tuple<T0, T1, T2, T3, T4> &in)
+ {
+ return out << " 0: " << prettyPrint(std::get<0>(in)) << '\n'
+ << " 1: " << prettyPrint(std::get<1>(in)) << '\n'
+ << " 2: " << prettyPrint(std::get<2>(in)) << '\n'
+ << " 3: " << prettyPrint(std::get<3>(in)) << '\n'
+ << " 4: " << prettyPrint(std::get<4>(in)) << '\n'
+ << std::flush;
+ }
+
+ template<class T0, class T1, class T2, class T3, class T4, class T5>
+ std::ostream &printInput(std::ostream &out,
+ const std::tuple<T0, T1, T2, T3, T4, T5> &in)
+ {
+ return out << " 0: " << prettyPrint(std::get<0>(in)) << '\n'
+ << " 1: " << prettyPrint(std::get<1>(in)) << '\n'
+ << " 2: " << prettyPrint(std::get<2>(in)) << '\n'
+ << " 3: " << prettyPrint(std::get<3>(in)) << '\n'
+ << " 4: " << prettyPrint(std::get<4>(in)) << '\n'
+ << " 5: " << prettyPrint(std::get<5>(in)) << '\n'
+ << std::flush;
+ }
+
+ template<class T0, class T1, class T2, class T3, class T4,
+ class T5, class T6>
+ std::ostream &printInput(std::ostream &out,
+ const std::tuple<T0, T1, T2, T3, T4, T5, T6> &in)
+ {
+ return out << " 0: " << prettyPrint(std::get<0>(in)) << '\n'
+ << " 1: " << prettyPrint(std::get<1>(in)) << '\n'
+ << " 2: " << prettyPrint(std::get<2>(in)) << '\n'
+ << " 3: " << prettyPrint(std::get<3>(in)) << '\n'
+ << " 4: " << prettyPrint(std::get<4>(in)) << '\n'
+ << " 5: " << prettyPrint(std::get<5>(in)) << '\n'
+ << " 6: " << prettyPrint(std::get<6>(in)) << '\n'
+ << std::flush;
+ }
+
+ template<class T0, class T1, class T2, class T3, class T4,
+ class T5, class T6, class T7>
+ std::ostream &printInput(std::ostream &out,
+ const std::tuple<T0, T1, T2, T3, T4, T5, T6, T7> &in)
+ {
+ return out << " 0: " << prettyPrint(std::get<0>(in)) << '\n'
+ << " 1: " << prettyPrint(std::get<1>(in)) << '\n'
+ << " 2: " << prettyPrint(std::get<2>(in)) << '\n'
+ << " 3: " << prettyPrint(std::get<3>(in)) << '\n'
+ << " 4: " << prettyPrint(std::get<4>(in)) << '\n'
+ << " 5: " << prettyPrint(std::get<5>(in)) << '\n'
+ << " 6: " << prettyPrint(std::get<6>(in)) << '\n'
+ << " 7: " << prettyPrint(std::get<7>(in)) << '\n'
+ << std::flush;
+ }
+
+ template<class T0, class T1, class T2, class T3, class T4,
+ class T5, class T6, class T7, class T8>
+ std::ostream &printInput(std::ostream &out,
+ const std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> &in)
+ {
+ return out << " 0: " << prettyPrint(std::get<0>(in)) << '\n'
+ << " 1: " << prettyPrint(std::get<1>(in)) << '\n'
+ << " 2: " << prettyPrint(std::get<2>(in)) << '\n'
+ << " 3: " << prettyPrint(std::get<3>(in)) << '\n'
+ << " 4: " << prettyPrint(std::get<4>(in)) << '\n'
+ << " 5: " << prettyPrint(std::get<5>(in)) << '\n'
+ << " 6: " << prettyPrint(std::get<6>(in)) << '\n'
+ << " 7: " << prettyPrint(std::get<7>(in)) << '\n'
+ << " 8: " << prettyPrint(std::get<8>(in)) << '\n'
+ << std::flush;
+ }
+
+ template<class T0, class T1, class T2, class T3, class T4,
+ class T5, class T6, class T7, class T8, class T9>
+ std::ostream &printInput(std::ostream &out,
+ const std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> &in)
+ {
+ return out << " 0: " << prettyPrint(std::get<0>(in)) << '\n'
+ << " 1: " << prettyPrint(std::get<1>(in)) << '\n'
+ << " 2: " << prettyPrint(std::get<2>(in)) << '\n'
+ << " 3: " << prettyPrint(std::get<3>(in)) << '\n'
+ << " 4: " << prettyPrint(std::get<4>(in)) << '\n'
+ << " 5: " << prettyPrint(std::get<5>(in)) << '\n'
+ << " 6: " << prettyPrint(std::get<6>(in)) << '\n'
+ << " 7: " << prettyPrint(std::get<7>(in)) << '\n'
+ << " 8: " << prettyPrint(std::get<8>(in)) << '\n'
+ << " 9: " << prettyPrint(std::get<9>(in)) << '\n'
+ << std::flush;
+ }
+
+}
+
+#endif
diff --git a/vendor/CppQuickCheck-2018-03-28/include/cppqc/Test.h b/vendor/CppQuickCheck-2018-03-28/include/cppqc/Test.h
new file mode 100644
index 00000000..8809c642
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/include/cppqc/Test.h
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2010, Gregory Rogers All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CPPQC_TEST_H
+#define CPPQC_TEST_H
+
+#include "Property.h"
+
+#include <map>
+#include <string>
+#include <iostream>
+#include <iomanip>
+#include <ostream>
+#include <limits>
+#include <chrono>
+
+namespace cppqc {
+
+using SeedType = uint32_t;
+
+// By default, a random seed will be used.
+// To overwrite the default behaviour, set the environment variable
+// "CPPQUICKCHECK_SEED".
+constexpr SeedType USE_DEFAULT_SEED = std::numeric_limits<uint32_t>::max();
+
+// If this environment variable is set, its value will overwrite the
+// default seed. In other words, no random seed will be generated but
+// if a seed has been explicitly set, it will will be used.
+constexpr const char* CPPQUICKCHECK_SEED_ENV = "CPPQUICKCHECK_SEED";
+
+// If this environment variable is set, failing tests will be
+// looped forever. Useful for attaching a debugger.
+constexpr const char *CPPQUICKCHECK_LOOP_FAILING_TESTS_ENV =
+ "CPPQUICKCHECK_LOOP_FAILING_TESTS";
+
+enum ResultType
+{
+ QC_SUCCESS, // All tests succeeded
+ QC_GAVE_UP, // Failed to generate data
+ QC_FAILURE, // A test failed
+ QC_NO_EXPECTED_FAILURE // The property was expected to fail but didn't
+};
+
+struct Result
+{
+ ResultType result;
+ std::size_t numTests;
+ std::multimap<std::size_t, std::string> labels;
+ SeedType seed;
+
+ // only used if result is QC_FAILURE
+ std::size_t numShrinks;
+ std::size_t usedSize;
+};
+
+namespace detail {
+ struct NullOstream : std::ostream
+ {
+ NullOstream() : std::ios(nullptr), std::ostream(nullptr) {}
+ };
+}
+
+template<class T0, class T1, class T2, class T3, class T4>
+Result quickCheck(const Property<T0, T1, T2, T3, T4> &prop,
+ std::size_t maxSuccess = 100, std::size_t maxDiscarded = 0,
+ std::size_t maxSize = 0)
+{
+ detail::NullOstream out;
+ return quickCheckOutput(prop, out, maxSuccess, maxDiscarded, maxSize);
+}
+
+namespace detail {
+ inline std::multimap<std::size_t, std::string> convertLabels(
+ const std::map<std::string, std::size_t> &labelsCollected)
+ {
+ std::multimap<std::size_t, std::string> labels;
+ for (const auto & elem : labelsCollected) {
+ labels.insert(std::make_pair(elem.second, elem.first));
+ }
+ return labels;
+ }
+
+ inline void outputLabels(std::ostream &out, std::size_t numSuccess,
+ const std::multimap<std::size_t, std::string> &labels)
+ {
+ std::size_t cnt = 20;
+ for (auto it = labels.rbegin(); it != labels.rend(); --cnt, ++it) {
+ if (cnt == 0) {
+ out << " ..." << std::endl;
+ break;
+ }
+
+ if (it->second != "") {
+ out << std::setw(3) << (100 * it->first / numSuccess) << "% "
+ << it->second << std::endl;
+ }
+ }
+ }
+
+ template<class T0, class T1, class T2, class T3, class T4>
+ std::pair<std::size_t, typename Property<T0, T1, T2, T3, T4>::Input>
+ doShrink(const Property<T0, T1, T2, T3, T4> &prop,
+ const typename Property<T0, T1, T2, T3, T4>::Input &in,
+ std::chrono::duration<double> timeout)
+ {
+ typedef typename Property<T0, T1, T2, T3, T4>::Input Input;
+
+ std::size_t numShrinks = 0;
+ Input shrunk = in;
+ const auto start = std::chrono::steady_clock::now();
+
+ try {
+continueShrinking:
+ std::vector<Input> shrinks =
+ prop.shrinkInput(shrunk);
+ for (Input input : shrinks) {
+ if (!prop.checkInput(input)) {
+ shrunk = std::move(input);
+ numShrinks++;
+ goto continueShrinking;
+ }
+
+ // No progress was made. Check the time limit:
+ const std::chrono::duration<double> elapsed =
+ std::chrono::steady_clock::now() - start;
+ if (elapsed >= timeout) {
+ std::cout << "Shrinking timed out...\n";
+ break;
+ }
+ }
+ } catch (...) {
+ }
+ return std::make_pair(numShrinks, shrunk);
+ }
+}
+
+namespace detail {
+ inline SeedType resolveSeed(SeedType originalSeed = USE_DEFAULT_SEED)
+ {
+ if (originalSeed == USE_DEFAULT_SEED) {
+ const char* seed_from_env = std::getenv(CPPQUICKCHECK_SEED_ENV);
+ if (seed_from_env != nullptr) {
+ try {
+ return static_cast<uint32_t>(std::stoi(seed_from_env));
+ } catch (std::invalid_argument&) {
+ std::ostringstream err;
+ err << "Failed to parse seed in environment variable "
+ << CPPQUICKCHECK_SEED_ENV
+ << ": Got <" << seed_from_env
+ << ">, but expected an integer between "
+ << "0 and " << (USE_DEFAULT_SEED - 1)
+ << ". To use a random seed instead, "
+ "unset the environment variable.";
+ throw std::invalid_argument{err.str()};
+ }
+ } else {
+ return static_cast<SeedType>(time(0));
+ }
+ } else {
+ return originalSeed;
+ }
+ }
+}
+
+constexpr auto DEFAULT_SHRINK_TIMEOUT = std::chrono::seconds(30);
+constexpr auto DISABLE_SHRINK_TIMEOUT = std::chrono::seconds::max();
+
+template<class T0, class T1, class T2, class T3, class T4>
+Result quickCheckOutput(const Property<T0, T1, T2, T3, T4> &prop,
+ std::ostream &out = std::cout,
+ std::size_t maxSuccess = 100,
+ std::size_t maxDiscarded = 0, std::size_t maxSize = 0,
+ std::chrono::duration<double> shrinkTimeout = DEFAULT_SHRINK_TIMEOUT,
+ SeedType seed = USE_DEFAULT_SEED)
+{
+ typedef typename Property<T0, T1, T2, T3, T4>::Input Input;
+
+ out << "* Checking property \"" << prop.name() << "\" ..." << std::endl;
+
+ if (maxDiscarded == 0)
+ maxDiscarded = maxSuccess * 5;
+ if (maxSize == 0)
+ maxSize = 100;
+
+ std::map<std::string, std::size_t> labelsCollected;
+ std::size_t numSuccess = 0, numDiscarded = 0, numTrivial = 0;
+
+ seed = detail::resolveSeed(seed);
+ RngEngine rng{seed};
+ while (numSuccess < maxSuccess) {
+ try {
+ std::size_t size = (numSuccess * maxSize + numDiscarded) / maxSuccess;
+ Input in = prop.generateInput(rng, size);
+ bool success = false;
+ try {
+ success = prop.checkInput(in);
+ } catch (...) {
+ out << "Caught exception checking property...\n";
+ }
+
+ if (prop.trivialInput(in))
+ ++numTrivial;
+ ++labelsCollected[prop.classifyInput(in)];
+
+ if (success) {
+ ++numSuccess;
+ } else {
+ if (prop.expect()) {
+ out << "*** Failed! ";
+ } else {
+ out << "+++ OK, failed as expected. ";
+ }
+
+ std::size_t numShrinks = 0;
+ try {
+ out << "Starting shrinking..." << std::flush;
+ std::pair<std::size_t, Input> shrinkRes =
+ detail::doShrink(prop, in, shrinkTimeout);
+ numShrinks = shrinkRes.first;
+ in = shrinkRes.second;
+ out << "done\n";
+ } catch (...) {
+ out << "WARN: Aborted shrinking because an exception was thrown\n";
+ }
+ out << "Falsifiable after " << numSuccess + 1
+ << (numSuccess == 0 ? " test" : " tests");
+ if (numShrinks > 0) {
+ out << " and " << numShrinks
+ << (numShrinks == 1 ? " shrink" : " shrinks");
+ }
+ out << " for input:\n";
+ printInput(out, in);
+ out << "(To reproduce the test, use "
+ << CPPQUICKCHECK_SEED_ENV << '=' << seed << ")\n";
+
+ if (prop.expect()) {
+ while (getenv(CPPQUICKCHECK_LOOP_FAILING_TESTS_ENV) != nullptr) {
+ out << "Looping failing test...\n";
+ prop.checkInput(in);
+ }
+ Result ret;
+ ret.result = QC_FAILURE;
+ ret.numTests = numSuccess + 1;
+ ret.labels = detail::convertLabels(labelsCollected);
+ ret.seed = seed;
+ ret.numShrinks = numShrinks;
+ ret.usedSize = size;
+ return ret;
+ } else {
+ Result ret;
+ ret.result = QC_SUCCESS;
+ ret.numTests = numSuccess + 1;
+ ret.labels = detail::convertLabels(labelsCollected);
+ ret.seed = seed;
+ return ret;
+ }
+ }
+ } catch (...) {
+ if (++numDiscarded >= maxDiscarded) {
+ out << "*** Gave up! Passed only " << numSuccess << " tests."
+ << std::endl;
+
+ Result ret;
+ ret.result = QC_GAVE_UP;
+ ret.numTests = numSuccess;
+ ret.labels = detail::convertLabels(labelsCollected);
+ ret.seed = seed;
+ return ret;
+ }
+ }
+ }
+
+ std::multimap<std::size_t, std::string> labels =
+ detail::convertLabels(labelsCollected);
+
+ if (prop.expect()) {
+ out << "+++ OK, passed " << numSuccess << " tests";
+ if (numTrivial != 0)
+ out << " (" << (100 * numTrivial / numSuccess) << "% trivial)";
+ out << '.' << std::endl;
+ detail::outputLabels(out, numSuccess, labels);
+
+ Result ret;
+ ret.result = QC_SUCCESS;
+ ret.numTests = numSuccess;
+ ret.labels = labels;
+ ret.seed = seed;
+ return ret;
+ } else {
+ out << "*** Failed! Expected failure but passed " << numSuccess
+ << " tests";
+ if (numTrivial != 0)
+ out << " (" << (100 * numTrivial / numSuccess) << "% trivial)";
+ out << '.' << std::endl;
+ detail::outputLabels(out, numSuccess, labels);
+
+ Result ret;
+ ret.result = QC_NO_EXPECTED_FAILURE;
+ ret.numTests = numSuccess;
+ ret.labels = labels;
+ ret.seed = seed;
+ return ret;
+ }
+}
+
+}
+
+#endif
diff --git a/vendor/CppQuickCheck-2018-03-28/include/cppqc/cxx-prettyprint.h b/vendor/CppQuickCheck-2018-03-28/include/cppqc/cxx-prettyprint.h
new file mode 100644
index 00000000..bbc644be
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/include/cppqc/cxx-prettyprint.h
@@ -0,0 +1,472 @@
+// Copyright Louis Delacroix 2010 - 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// A pretty printing library for C++
+//
+// Usage:
+// Include this header, and operator<< will "just work".
+
+#ifndef H_PRETTY_PRINT
+#define H_PRETTY_PRINT
+
+#include <cstddef>
+#include <iterator>
+#include <memory>
+#include <ostream>
+#include <set>
+#include <tuple>
+#include <type_traits>
+#include <unordered_set>
+#include <utility>
+#include <valarray>
+#include <sstream>
+
+namespace pretty_print
+{
+ namespace detail
+ {
+ // SFINAE type trait to detect whether T::const_iterator exists.
+
+ struct sfinae_base
+ {
+ using yes = char;
+ using no = yes[2];
+ };
+
+ template <typename T>
+ struct has_const_iterator : private sfinae_base
+ {
+ private:
+ template <typename C> static yes & test(typename C::const_iterator*);
+ template <typename C> static no & test(...);
+ public:
+ static const bool value = sizeof(test<T>(nullptr)) == sizeof(yes);
+ using type = T;
+ };
+
+ template <typename T>
+ struct has_begin_end : private sfinae_base
+ {
+ private:
+ template <typename C>
+ static yes & f(typename std::enable_if<
+ std::is_same<decltype(static_cast<typename C::const_iterator(C::*)() const>(&C::begin)),
+ typename C::const_iterator(C::*)() const>::value>::type *);
+
+ template <typename C> static no & f(...);
+
+ template <typename C>
+ static yes & g(typename std::enable_if<
+ std::is_same<decltype(static_cast<typename C::const_iterator(C::*)() const>(&C::end)),
+ typename C::const_iterator(C::*)() const>::value, void>::type*);
+
+ template <typename C> static no & g(...);
+
+ public:
+ static bool const beg_value = sizeof(f<T>(nullptr)) == sizeof(yes);
+ static bool const end_value = sizeof(g<T>(nullptr)) == sizeof(yes);
+ };
+
+ } // namespace detail
+
+
+ // Holds the delimiter values for a specific character type
+
+ template <typename TChar>
+ struct delimiters_values
+ {
+ using char_type = TChar;
+ const char_type * prefix;
+ const char_type * delimiter;
+ const char_type * postfix;
+ };
+
+
+ // Defines the delimiter values for a specific container and character type
+
+ template <typename T, typename TChar>
+ struct delimiters
+ {
+ using type = delimiters_values<TChar>;
+ static const type values;
+ };
+
+ template <typename T>
+ struct quoting_handler
+ {
+ static std::string toString(const T& x)
+ {
+ std::ostringstream out;
+ out << x;
+ return out.str();
+ }
+ };
+
+ template <>
+ struct quoting_handler<std::string>
+ {
+ static std::string toString(const std::string& x)
+ {
+ return '\"' + x + '\"';
+ }
+ };
+
+ template <class T>
+ std::string quote_if_necessary(const T& x)
+ {
+ return quoting_handler<T>::toString(x);
+ }
+
+ // Functor to print containers. You can use this directly if you want
+ // to specificy a non-default delimiters type. The printing logic can
+ // be customized by specializing the nested template.
+
+ template <typename T,
+ typename TChar = char,
+ typename TCharTraits = ::std::char_traits<TChar>,
+ typename TDelimiters = delimiters<T, TChar>>
+ struct print_container_helper
+ {
+ using delimiters_type = TDelimiters;
+ using ostream_type = std::basic_ostream<TChar, TCharTraits>;
+
+ template <typename U>
+ struct printer
+ {
+ static void print_body(const U & c, ostream_type & stream)
+ {
+ using std::begin;
+ using std::end;
+
+ auto it = begin(c);
+ const auto the_end = end(c);
+
+ if (it != the_end)
+ {
+ for ( ; ; )
+ {
+ stream << quote_if_necessary(*it);
+
+ if (++it == the_end)
+ break;
+
+ if (delimiters_type::values.delimiter != NULL)
+ stream << delimiters_type::values.delimiter;
+ }
+ }
+ }
+ };
+
+ print_container_helper(const T & container)
+ : container_(container)
+ { }
+
+ inline void operator()(ostream_type & stream) const
+ {
+ if (delimiters_type::values.prefix != NULL)
+ stream << delimiters_type::values.prefix;
+
+ printer<T>::print_body(container_, stream);
+
+ if (delimiters_type::values.postfix != NULL)
+ stream << delimiters_type::values.postfix;
+ }
+
+ private:
+ const T & container_;
+ };
+
+ // Specialization for pairs
+
+ template <typename T, typename TChar, typename TCharTraits, typename TDelimiters>
+ template <typename T1, typename T2>
+ struct print_container_helper<T, TChar, TCharTraits, TDelimiters>::printer<std::pair<T1, T2>>
+ {
+ using ostream_type = print_container_helper<T, TChar, TCharTraits, TDelimiters>::ostream_type;
+
+ static void print_body(const std::pair<T1, T2> & c, ostream_type & stream)
+ {
+ stream << quote_if_necessary(c.first);
+ if (print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter != NULL)
+ stream << print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter;
+ stream << quote_if_necessary(c.second);
+ }
+ };
+
+ // Specialization for tuples
+
+ template <typename T, typename TChar, typename TCharTraits, typename TDelimiters>
+ template <typename ...Args>
+ struct print_container_helper<T, TChar, TCharTraits, TDelimiters>::printer<std::tuple<Args...>>
+ {
+ using ostream_type = print_container_helper<T, TChar, TCharTraits, TDelimiters>::ostream_type;
+ using element_type = std::tuple<Args...>;
+
+ template <std::size_t I> struct Int { };
+
+ static void print_body(const element_type & c, ostream_type & stream)
+ {
+ tuple_print(c, stream, Int<0>());
+ }
+
+ static void tuple_print(const element_type &, ostream_type &, Int<sizeof...(Args)>)
+ {
+ }
+
+ static void tuple_print(const element_type & c, ostream_type & stream,
+ typename std::conditional<sizeof...(Args) != 0, Int<0>, std::nullptr_t>::type)
+ {
+ stream << quote_if_necessary(std::get<0>(c));
+ tuple_print(c, stream, Int<1>());
+ }
+
+ template <std::size_t N>
+ static void tuple_print(const element_type & c, ostream_type & stream, Int<N>)
+ {
+ if (print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter != NULL)
+ stream << print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter;
+
+ stream << quote_if_necessary(std::get<N>(c));
+
+ tuple_print(c, stream, Int<N + 1>());
+ }
+ };
+
+ // Prints a print_container_helper to the specified stream.
+
+ template<typename T, typename TChar, typename TCharTraits, typename TDelimiters>
+ inline std::basic_ostream<TChar, TCharTraits> & operator<<(
+ std::basic_ostream<TChar, TCharTraits> & stream,
+ const print_container_helper<T, TChar, TCharTraits, TDelimiters> & helper)
+ {
+ helper(stream);
+ return stream;
+ }
+
+
+ // Basic is_container template; specialize to derive from std::true_type for all desired container types
+
+ template <typename T>
+ struct is_container : public std::integral_constant<bool,
+ detail::has_const_iterator<T>::value &&
+ detail::has_begin_end<T>::beg_value &&
+ detail::has_begin_end<T>::end_value> { };
+
+ template <typename T, std::size_t N>
+ struct is_container<T[N]> : std::true_type { };
+
+ template <std::size_t N>
+ struct is_container<char[N]> : std::false_type { };
+
+ template <typename T>
+ struct is_container<std::valarray<T>> : std::true_type { };
+
+ template <typename T1, typename T2>
+ struct is_container<std::pair<T1, T2>> : std::true_type { };
+
+ template <typename ...Args>
+ struct is_container<std::tuple<Args...>> : std::true_type { };
+
+
+ // Default delimiters
+
+ template <typename T> struct delimiters<T, char> { static const delimiters_values<char> values; };
+ template <typename T> const delimiters_values<char> delimiters<T, char>::values = { "[", ", ", "]" };
+ template <typename T> struct delimiters<T, wchar_t> { static const delimiters_values<wchar_t> values; };
+ template <typename T> const delimiters_values<wchar_t> delimiters<T, wchar_t>::values = { L"[", L", ", L"]" };
+
+
+ // Delimiters for (multi)set and unordered_(multi)set
+
+ template <typename T, typename TComp, typename TAllocator>
+ struct delimiters< ::std::set<T, TComp, TAllocator>, char> { static const delimiters_values<char> values; };
+
+ template <typename T, typename TComp, typename TAllocator>
+ const delimiters_values<char> delimiters< ::std::set<T, TComp, TAllocator>, char>::values = { "{", ", ", "}" };
+
+ template <typename T, typename TComp, typename TAllocator>
+ struct delimiters< ::std::set<T, TComp, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; };
+
+ template <typename T, typename TComp, typename TAllocator>
+ const delimiters_values<wchar_t> delimiters< ::std::set<T, TComp, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" };
+
+ template <typename T, typename TComp, typename TAllocator>
+ struct delimiters< ::std::multiset<T, TComp, TAllocator>, char> { static const delimiters_values<char> values; };
+
+ template <typename T, typename TComp, typename TAllocator>
+ const delimiters_values<char> delimiters< ::std::multiset<T, TComp, TAllocator>, char>::values = { "{", ", ", "}" };
+
+ template <typename T, typename TComp, typename TAllocator>
+ struct delimiters< ::std::multiset<T, TComp, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; };
+
+ template <typename T, typename TComp, typename TAllocator>
+ const delimiters_values<wchar_t> delimiters< ::std::multiset<T, TComp, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" };
+
+ template <typename T, typename THash, typename TEqual, typename TAllocator>
+ struct delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, char> { static const delimiters_values<char> values; };
+
+ template <typename T, typename THash, typename TEqual, typename TAllocator>
+ const delimiters_values<char> delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, char>::values = { "{", ", ", "}" };
+
+ template <typename T, typename THash, typename TEqual, typename TAllocator>
+ struct delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; };
+
+ template <typename T, typename THash, typename TEqual, typename TAllocator>
+ const delimiters_values<wchar_t> delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" };
+
+ template <typename T, typename THash, typename TEqual, typename TAllocator>
+ struct delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, char> { static const delimiters_values<char> values; };
+
+ template <typename T, typename THash, typename TEqual, typename TAllocator>
+ const delimiters_values<char> delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, char>::values = { "{", ", ", "}" };
+
+ template <typename T, typename THash, typename TEqual, typename TAllocator>
+ struct delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; };
+
+ template <typename T, typename THash, typename TEqual, typename TAllocator>
+ const delimiters_values<wchar_t> delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" };
+
+
+ // Delimiters for pair and tuple
+
+ template <typename T1, typename T2> struct delimiters<std::pair<T1, T2>, char> { static const delimiters_values<char> values; };
+ template <typename T1, typename T2> const delimiters_values<char> delimiters<std::pair<T1, T2>, char>::values = { "(", ", ", ")" };
+ template <typename T1, typename T2> struct delimiters< ::std::pair<T1, T2>, wchar_t> { static const delimiters_values<wchar_t> values; };
+ template <typename T1, typename T2> const delimiters_values<wchar_t> delimiters< ::std::pair<T1, T2>, wchar_t>::values = { L"(", L", ", L")" };
+
+ template <typename ...Args> struct delimiters<std::tuple<Args...>, char> { static const delimiters_values<char> values; };
+ template <typename ...Args> const delimiters_values<char> delimiters<std::tuple<Args...>, char>::values = { "(", ", ", ")" };
+ template <typename ...Args> struct delimiters< ::std::tuple<Args...>, wchar_t> { static const delimiters_values<wchar_t> values; };
+ template <typename ...Args> const delimiters_values<wchar_t> delimiters< ::std::tuple<Args...>, wchar_t>::values = { L"(", L", ", L")" };
+
+
+ // Type-erasing helper class for easy use of custom delimiters.
+ // Requires TCharTraits = std::char_traits<TChar> and TChar = char or wchar_t, and MyDelims needs to be defined for TChar.
+ // Usage: "cout << pretty_print::custom_delims<MyDelims>(x)".
+
+ struct custom_delims_base
+ {
+ virtual ~custom_delims_base() { }
+ virtual std::ostream & stream(::std::ostream &) = 0;
+ virtual std::wostream & stream(::std::wostream &) = 0;
+ };
+
+ template <typename T, typename Delims>
+ struct custom_delims_wrapper : custom_delims_base
+ {
+ custom_delims_wrapper(const T & t_) : t(t_) { }
+
+ std::ostream & stream(std::ostream & s)
+ {
+ return s << print_container_helper<T, char, std::char_traits<char>, Delims>(t);
+ }
+
+ std::wostream & stream(std::wostream & s)
+ {
+ return s << print_container_helper<T, wchar_t, std::char_traits<wchar_t>, Delims>(t);
+ }
+
+ private:
+ const T & t;
+ };
+
+ template <typename Delims>
+ struct custom_delims
+ {
+ template <typename Container>
+ custom_delims(const Container & c) : base(new custom_delims_wrapper<Container, Delims>(c)) { }
+
+ std::unique_ptr<custom_delims_base> base;
+ };
+
+ template <typename TChar, typename TCharTraits, typename Delims>
+ inline std::basic_ostream<TChar, TCharTraits> & operator<<(std::basic_ostream<TChar, TCharTraits> & s, const custom_delims<Delims> & p)
+ {
+ return p.base->stream(s);
+ }
+
+
+ // A wrapper for a C-style array given as pointer-plus-size.
+ // Usage: std::cout << pretty_print_array(arr, n) << std::endl;
+
+ template<typename T>
+ struct array_wrapper_n
+ {
+ typedef const T * const_iterator;
+ typedef T value_type;
+
+ array_wrapper_n(const T * const a, size_t n) : _array(a), _n(n) { }
+ inline const_iterator begin() const { return _array; }
+ inline const_iterator end() const { return _array + _n; }
+
+ private:
+ const T * const _array;
+ size_t _n;
+ };
+
+
+ // A wrapper for hash-table based containers that offer local iterators to each bucket.
+ // Usage: std::cout << bucket_print(m, 4) << std::endl; (Prints bucket 5 of container m.)
+
+ template <typename T>
+ struct bucket_print_wrapper
+ {
+ typedef typename T::const_local_iterator const_iterator;
+ typedef typename T::size_type size_type;
+
+ const_iterator begin() const
+ {
+ return m_map.cbegin(n);
+ }
+
+ const_iterator end() const
+ {
+ return m_map.cend(n);
+ }
+
+ bucket_print_wrapper(const T & m, size_type bucket) : m_map(m), n(bucket) { }
+
+ private:
+ const T & m_map;
+ const size_type n;
+ };
+
+} // namespace pretty_print
+
+
+// Global accessor functions for the convenience wrappers
+
+template<typename T>
+inline pretty_print::array_wrapper_n<T> pretty_print_array(const T * const a, size_t n)
+{
+ return pretty_print::array_wrapper_n<T>(a, n);
+}
+
+template <typename T> pretty_print::bucket_print_wrapper<T>
+bucket_print(const T & m, typename T::size_type n)
+{
+ return pretty_print::bucket_print_wrapper<T>(m, n);
+}
+
+
+// Main magic entry point: An overload snuck into namespace std.
+// Can we do better?
+
+namespace std
+{
+ // Prints a container to the stream using default delimiters
+
+ template<typename T, typename TChar, typename TCharTraits>
+ inline typename enable_if< ::pretty_print::is_container<T>::value,
+ basic_ostream<TChar, TCharTraits> &>::type
+ operator<<(basic_ostream<TChar, TCharTraits> & stream, const T & container)
+ {
+ return stream << ::pretty_print::print_container_helper<T, TChar, TCharTraits>(container);
+ }
+}
+
+
+
+#endif // H_PRETTY_PRINT
diff --git a/vendor/CppQuickCheck-2018-03-28/src/Arbitrary.cpp b/vendor/CppQuickCheck-2018-03-28/src/Arbitrary.cpp
new file mode 100644
index 00000000..5da4d3d7
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/src/Arbitrary.cpp
@@ -0,0 +1,80 @@
+#include "cppqc/Arbitrary.h"
+
+namespace cppqc {
+
+const Arbitrary<bool>::unGenType ArbitraryImpl<bool>::unGen = arbitraryBool;
+const Arbitrary<bool>::shrinkType ArbitraryImpl<bool>::shrink = shrinkBool;
+
+const Arbitrary<signed char>::unGenType ArbitraryImpl<signed char>::unGen =
+ arbitrarySizedBoundedIntegral<signed char>;
+const Arbitrary<signed char>::shrinkType ArbitraryImpl<signed char>::shrink =
+ shrinkIntegral<signed char>;
+
+const Arbitrary<unsigned char>::unGenType ArbitraryImpl<unsigned char>::unGen =
+ arbitrarySizedBoundedIntegral<unsigned char>;
+const Arbitrary<unsigned char>::shrinkType
+ ArbitraryImpl<unsigned char>::shrink = shrinkIntegral<unsigned char>;
+
+const Arbitrary<signed short>::unGenType ArbitraryImpl<signed short>::unGen =
+ arbitrarySizedBoundedIntegral<signed short>;
+const Arbitrary<signed short>::shrinkType ArbitraryImpl<signed short>::shrink =
+ shrinkIntegral<signed short>;
+
+const Arbitrary<unsigned short>::unGenType
+ ArbitraryImpl<unsigned short>::unGen =
+ arbitrarySizedBoundedIntegral<unsigned short>;
+const Arbitrary<unsigned short>::shrinkType
+ ArbitraryImpl<unsigned short>::shrink = shrinkIntegral<unsigned short>;
+
+const Arbitrary<signed int>::unGenType ArbitraryImpl<signed int>::unGen =
+ arbitrarySizedBoundedIntegral<signed int>;
+const Arbitrary<signed int>::shrinkType ArbitraryImpl<signed int>::shrink =
+ shrinkIntegral<signed int>;
+
+const Arbitrary<unsigned int>::unGenType ArbitraryImpl<unsigned int>::unGen =
+ arbitrarySizedBoundedIntegral<unsigned int>;
+const Arbitrary<unsigned int>::shrinkType ArbitraryImpl<unsigned int>::shrink =
+ shrinkIntegral<unsigned int>;
+
+const Arbitrary<signed long>::unGenType ArbitraryImpl<signed long>::unGen =
+ arbitrarySizedBoundedIntegral<signed long>;
+const Arbitrary<signed long>::shrinkType ArbitraryImpl<signed long>::shrink =
+ shrinkIntegral<signed long>;
+
+const Arbitrary<unsigned long>::unGenType ArbitraryImpl<unsigned long>::unGen =
+ arbitrarySizedBoundedIntegral<unsigned long>;
+const Arbitrary<unsigned long>::shrinkType ArbitraryImpl<unsigned long>::shrink =
+ shrinkIntegral<unsigned long>;
+
+const Arbitrary<signed long long>::unGenType ArbitraryImpl<signed long long>::unGen =
+ arbitrarySizedBoundedIntegral<signed long long>;
+const Arbitrary<signed long long>::shrinkType ArbitraryImpl<signed long long>::shrink =
+ shrinkIntegral<signed long long>;
+
+const Arbitrary<unsigned long long>::unGenType ArbitraryImpl<unsigned long long>::unGen =
+ arbitrarySizedBoundedIntegral<unsigned long long>;
+const Arbitrary<unsigned long long>::shrinkType ArbitraryImpl<unsigned long long>::shrink =
+ shrinkIntegral<unsigned long long>;
+
+const Arbitrary<float>::unGenType ArbitraryImpl<float>::unGen =
+ arbitrarySizedReal<float>;
+const Arbitrary<float>::shrinkType ArbitraryImpl<float>::shrink = shrinkReal<float>;
+
+const Arbitrary<double>::unGenType ArbitraryImpl<double>::unGen =
+ arbitrarySizedReal<double>;
+const Arbitrary<double>::shrinkType ArbitraryImpl<double>::shrink = shrinkReal<double>;
+
+const Arbitrary<long double>::unGenType ArbitraryImpl<long double>::unGen =
+ arbitrarySizedReal<long double>;
+const Arbitrary<long double>::shrinkType ArbitraryImpl<long double>::shrink =
+ shrinkReal<long double>;
+
+const Arbitrary<char>::unGenType ArbitraryImpl<char>::unGen = arbitraryChar;
+const Arbitrary<char>::shrinkType ArbitraryImpl<char>::shrink = shrinkChar;
+
+const Arbitrary<wchar_t>::unGenType ArbitraryImpl<wchar_t>::unGen =
+ arbitraryBoundedIntegral<wchar_t>;
+const Arbitrary<wchar_t>::shrinkType ArbitraryImpl<wchar_t>::shrink =
+ shrinkIntegral<wchar_t>;
+
+}
diff --git a/vendor/CppQuickCheck-2018-03-28/test/catch-main.cpp b/vendor/CppQuickCheck-2018-03-28/test/catch-main.cpp
new file mode 100644
index 00000000..50c80130
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/test/catch-main.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016, Philipp Classen All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
+#include "catch.hpp"
diff --git a/vendor/CppQuickCheck-2018-03-28/test/catch.hpp b/vendor/CppQuickCheck-2018-03-28/test/catch.hpp
new file mode 100644
index 00000000..ec75bf1d
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/test/catch.hpp
@@ -0,0 +1,9427 @@
+/*
+ * CATCH v1.1 build 14 (develop branch)
+ * Generated: 2015-03-04 18:32:24.627737
+ * ----------------------------------------------------------
+ * This file has been merged from multiple headers. Please don't edit it directly
+ * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+
+#define TWOBLUECUBES_CATCH_HPP_INCLUDED
+
+// #included from: internal/catch_suppress_warnings.h
+
+#define TWOBLUECUBES_CATCH_SUPPRESS_WARNINGS_H_INCLUDED
+
+#ifdef __clang__
+# ifdef __ICC // icpc defines the __clang__ macro
+# pragma warning(push)
+# pragma warning(disable: 161 1682)
+# else // __ICC
+# pragma clang diagnostic ignored "-Wglobal-constructors"
+# pragma clang diagnostic ignored "-Wvariadic-macros"
+# pragma clang diagnostic ignored "-Wc99-extensions"
+# pragma clang diagnostic ignored "-Wunused-variable"
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wpadded"
+# pragma clang diagnostic ignored "-Wc++98-compat"
+# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
+# endif
+#elif defined __GNUC__
+# pragma GCC diagnostic ignored "-Wvariadic-macros"
+# pragma GCC diagnostic ignored "-Wunused-variable"
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wpadded"
+#endif
+
+#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
+# define CATCH_IMPL
+#endif
+
+#ifdef CATCH_IMPL
+# ifndef CLARA_CONFIG_MAIN
+# define CLARA_CONFIG_MAIN_NOT_DEFINED
+# define CLARA_CONFIG_MAIN
+# endif
+#endif
+
+// #included from: internal/catch_notimplemented_exception.h
+#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
+
+// #included from: catch_common.h
+#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
+
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
+#define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
+
+#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
+#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
+
+#include <sstream>
+#include <stdexcept>
+#include <algorithm>
+
+// #included from: catch_compiler_capabilities.h
+#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
+
+// Much of the following code is based on Boost (1.53)
+
+#ifdef __clang__
+
+# if __has_feature(cxx_nullptr)
+# define CATCH_CONFIG_CPP11_NULLPTR
+# endif
+
+# if __has_feature(cxx_noexcept)
+# define CATCH_CONFIG_CPP11_NOEXCEPT
+# endif
+
+#endif // __clang__
+
+////////////////////////////////////////////////////////////////////////////////
+// Borland
+#ifdef __BORLANDC__
+
+#if (__BORLANDC__ > 0x582 )
+//#define CATCH_CONFIG_SFINAE // Not confirmed
+#endif
+
+#endif // __BORLANDC__
+
+////////////////////////////////////////////////////////////////////////////////
+// EDG
+#ifdef __EDG_VERSION__
+
+#if (__EDG_VERSION__ > 238 )
+//#define CATCH_CONFIG_SFINAE // Not confirmed
+#endif
+
+#endif // __EDG_VERSION__
+
+////////////////////////////////////////////////////////////////////////////////
+// Digital Mars
+#ifdef __DMC__
+
+#if (__DMC__ > 0x840 )
+//#define CATCH_CONFIG_SFINAE // Not confirmed
+#endif
+
+#endif // __DMC__
+
+////////////////////////////////////////////////////////////////////////////////
+// GCC
+#ifdef __GNUC__
+
+#if __GNUC__ < 3
+
+#if (__GNUC_MINOR__ >= 96 )
+//#define CATCH_CONFIG_SFINAE
+#endif
+
+#elif __GNUC__ >= 3
+
+// #define CATCH_CONFIG_SFINAE // Taking this out completely for now
+
+#endif // __GNUC__ < 3
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) )
+
+#define CATCH_CONFIG_CPP11_NULLPTR
+#endif
+
+#endif // __GNUC__
+
+////////////////////////////////////////////////////////////////////////////////
+// Visual C++
+#ifdef _MSC_VER
+
+#if (_MSC_VER >= 1600)
+#define CATCH_CONFIG_CPP11_NULLPTR
+#endif
+
+#if (_MSC_VER >= 1310 ) // (VC++ 7.0+)
+//#define CATCH_CONFIG_SFINAE // Not confirmed
+#endif
+
+#endif // _MSC_VER
+
+// Use variadic macros if the compiler supports them
+#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
+ ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
+ ( defined __GNUC__ && __GNUC__ >= 3 ) || \
+ ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
+
+#ifndef CATCH_CONFIG_NO_VARIADIC_MACROS
+#define CATCH_CONFIG_VARIADIC_MACROS
+#endif
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// C++ language feature support
+
+// detect language version:
+#if (__cplusplus == 201103L)
+# define CATCH_CPP11
+# define CATCH_CPP11_OR_GREATER
+#elif (__cplusplus >= 201103L)
+# define CATCH_CPP11_OR_GREATER
+#endif
+
+// noexcept support:
+#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
+# define CATCH_NOEXCEPT noexcept
+# define CATCH_NOEXCEPT_IS(x) noexcept(x)
+#else
+# define CATCH_NOEXCEPT throw()
+# define CATCH_NOEXCEPT_IS(x)
+#endif
+
+namespace Catch {
+
+ class NonCopyable {
+#ifdef CATCH_CPP11_OR_GREATER
+ NonCopyable( NonCopyable const& ) = delete;
+ NonCopyable( NonCopyable && ) = delete;
+ NonCopyable& operator = ( NonCopyable const& ) = delete;
+ NonCopyable& operator = ( NonCopyable && ) = delete;
+#else
+ NonCopyable( NonCopyable const& info );
+ NonCopyable& operator = ( NonCopyable const& );
+#endif
+
+ protected:
+ NonCopyable() {}
+ virtual ~NonCopyable();
+ };
+
+ class SafeBool {
+ public:
+ typedef void (SafeBool::*type)() const;
+
+ static type makeSafe( bool value ) {
+ return value ? &SafeBool::trueValue : 0;
+ }
+ private:
+ void trueValue() const {}
+ };
+
+ template<typename ContainerT>
+ inline void deleteAll( ContainerT& container ) {
+ typename ContainerT::const_iterator it = container.begin();
+ typename ContainerT::const_iterator itEnd = container.end();
+ for(; it != itEnd; ++it )
+ delete *it;
+ }
+ template<typename AssociativeContainerT>
+ inline void deleteAllValues( AssociativeContainerT& container ) {
+ typename AssociativeContainerT::const_iterator it = container.begin();
+ typename AssociativeContainerT::const_iterator itEnd = container.end();
+ for(; it != itEnd; ++it )
+ delete it->second;
+ }
+
+ bool startsWith( std::string const& s, std::string const& prefix );
+ bool endsWith( std::string const& s, std::string const& suffix );
+ bool contains( std::string const& s, std::string const& infix );
+ void toLowerInPlace( std::string& s );
+ std::string toLower( std::string const& s );
+ std::string trim( std::string const& str );
+ bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
+
+ struct pluralise {
+ pluralise( std::size_t count, std::string const& label );
+
+ friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
+
+ std::size_t m_count;
+ std::string m_label;
+ };
+
+ struct SourceLineInfo {
+
+ SourceLineInfo();
+ SourceLineInfo( char const* _file, std::size_t _line );
+ SourceLineInfo( SourceLineInfo const& other );
+# ifdef CATCH_CPP11_OR_GREATER
+ SourceLineInfo( SourceLineInfo && ) = default;
+ SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
+ SourceLineInfo& operator = ( SourceLineInfo && ) = default;
+# endif
+ bool empty() const;
+ bool operator == ( SourceLineInfo const& other ) const;
+ bool operator < ( SourceLineInfo const& other ) const;
+
+ std::string file;
+ std::size_t line;
+ };
+
+ std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
+
+ // This is just here to avoid compiler warnings with macro constants and boolean literals
+ inline bool isTrue( bool value ){ return value; }
+ inline bool alwaysTrue() { return true; }
+ inline bool alwaysFalse() { return false; }
+
+ void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
+
+ // Use this in variadic streaming macros to allow
+ // >> +StreamEndStop
+ // as well as
+ // >> stuff +StreamEndStop
+ struct StreamEndStop {
+ std::string operator+() {
+ return std::string();
+ }
+ };
+ template<typename T>
+ T const& operator + ( T const& value, StreamEndStop ) {
+ return value;
+ }
+}
+
+#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
+#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
+
+#include <ostream>
+
+namespace Catch {
+
+ class NotImplementedException : public std::exception
+ {
+ public:
+ NotImplementedException( SourceLineInfo const& lineInfo );
+ NotImplementedException( NotImplementedException const& ) {}
+
+ virtual ~NotImplementedException() CATCH_NOEXCEPT {}
+
+ virtual const char* what() const CATCH_NOEXCEPT;
+
+ private:
+ std::string m_what;
+ SourceLineInfo m_lineInfo;
+ };
+
+} // end namespace Catch
+
+///////////////////////////////////////////////////////////////////////////////
+#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
+
+// #included from: internal/catch_context.h
+#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
+
+// #included from: catch_interfaces_generators.h
+#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct IGeneratorInfo {
+ virtual ~IGeneratorInfo();
+ virtual bool moveNext() = 0;
+ virtual std::size_t getCurrentIndex() const = 0;
+ };
+
+ struct IGeneratorsForTest {
+ virtual ~IGeneratorsForTest();
+
+ virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
+ virtual bool moveNext() = 0;
+ };
+
+ IGeneratorsForTest* createGeneratorsForTest();
+
+} // end namespace Catch
+
+// #included from: catch_ptr.hpp
+#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+namespace Catch {
+
+ // An intrusive reference counting smart pointer.
+ // T must implement addRef() and release() methods
+ // typically implementing the IShared interface
+ template<typename T>
+ class Ptr {
+ public:
+ Ptr() : m_p( NULL ){}
+ Ptr( T* p ) : m_p( p ){
+ if( m_p )
+ m_p->addRef();
+ }
+ Ptr( Ptr const& other ) : m_p( other.m_p ){
+ if( m_p )
+ m_p->addRef();
+ }
+ ~Ptr(){
+ if( m_p )
+ m_p->release();
+ }
+ void reset() {
+ if( m_p )
+ m_p->release();
+ m_p = NULL;
+ }
+ Ptr& operator = ( T* p ){
+ Ptr temp( p );
+ swap( temp );
+ return *this;
+ }
+ Ptr& operator = ( Ptr const& other ){
+ Ptr temp( other );
+ swap( temp );
+ return *this;
+ }
+ void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
+ T* get() { return m_p; }
+ const T* get() const{ return m_p; }
+ T& operator*() const { return *m_p; }
+ T* operator->() const { return m_p; }
+ bool operator !() const { return m_p == NULL; }
+ operator SafeBool::type() const { return SafeBool::makeSafe( m_p != NULL ); }
+
+ private:
+ T* m_p;
+ };
+
+ struct IShared : NonCopyable {
+ virtual ~IShared();
+ virtual void addRef() const = 0;
+ virtual void release() const = 0;
+ };
+
+ template<typename T = IShared>
+ struct SharedImpl : T {
+
+ SharedImpl() : m_rc( 0 ){}
+
+ virtual void addRef() const {
+ ++m_rc;
+ }
+ virtual void release() const {
+ if( --m_rc == 0 )
+ delete this;
+ }
+
+ mutable unsigned int m_rc;
+ };
+
+} // end namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include <memory>
+#include <vector>
+#include <stdlib.h>
+
+namespace Catch {
+
+ class TestCase;
+ class Stream;
+ struct IResultCapture;
+ struct IRunner;
+ struct IGeneratorsForTest;
+ struct IConfig;
+
+ struct IContext
+ {
+ virtual ~IContext();
+
+ virtual IResultCapture* getResultCapture() = 0;
+ virtual IRunner* getRunner() = 0;
+ virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
+ virtual bool advanceGeneratorsForCurrentTest() = 0;
+ virtual Ptr<IConfig const> getConfig() const = 0;
+ };
+
+ struct IMutableContext : IContext
+ {
+ virtual ~IMutableContext();
+ virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
+ virtual void setRunner( IRunner* runner ) = 0;
+ virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
+ };
+
+ IContext& getCurrentContext();
+ IMutableContext& getCurrentMutableContext();
+ void cleanUpContext();
+ Stream createStream( std::string const& streamName );
+
+}
+
+// #included from: internal/catch_test_registry.hpp
+#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
+
+// #included from: catch_interfaces_testcase.h
+#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
+
+#include <vector>
+
+namespace Catch {
+
+ class TestSpec;
+
+ struct ITestCase : IShared {
+ virtual void invoke () const = 0;
+ protected:
+ virtual ~ITestCase();
+ };
+
+ class TestCase;
+ struct IConfig;
+
+ struct ITestCaseRegistry {
+ virtual ~ITestCaseRegistry();
+ virtual std::vector<TestCase> const& getAllTests() const = 0;
+ virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const = 0;
+
+ };
+}
+
+namespace Catch {
+
+template<typename C>
+class MethodTestCase : public SharedImpl<ITestCase> {
+
+public:
+ MethodTestCase( void (C::*method)() ) : m_method( method ) {}
+
+ virtual void invoke() const {
+ C obj;
+ (obj.*m_method)();
+ }
+
+private:
+ virtual ~MethodTestCase() {}
+
+ void (C::*m_method)();
+};
+
+typedef void(*TestFunction)();
+
+struct NameAndDesc {
+ NameAndDesc( const char* _name = "", const char* _description= "" )
+ : name( _name ), description( _description )
+ {}
+
+ const char* name;
+ const char* description;
+};
+
+struct AutoReg {
+
+ AutoReg( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc );
+
+ template<typename C>
+ AutoReg( void (C::*method)(),
+ char const* className,
+ NameAndDesc const& nameAndDesc,
+ SourceLineInfo const& lineInfo ) {
+ registerTestCase( new MethodTestCase<C>( method ),
+ className,
+ nameAndDesc,
+ lineInfo );
+ }
+
+ void registerTestCase( ITestCase* testCase,
+ char const* className,
+ NameAndDesc const& nameAndDesc,
+ SourceLineInfo const& lineInfo );
+
+ ~AutoReg();
+
+private:
+ AutoReg( AutoReg const& );
+ void operator= ( AutoReg const& );
+};
+
+} // end namespace Catch
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TESTCASE( ... ) \
+ static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
+ static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\
+ namespace{ \
+ struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
+ void test(); \
+ }; \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
+ } \
+ void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
+
+#else
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
+ static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
+ static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
+ namespace{ \
+ struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
+ void test(); \
+ }; \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
+ } \
+ void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
+
+#endif
+
+// #included from: internal/catch_capture.hpp
+#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
+
+// #included from: catch_result_builder.h
+#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
+
+// #included from: catch_result_type.h
+#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
+
+namespace Catch {
+
+ // ResultWas::OfType enum
+ struct ResultWas { enum OfType {
+ Unknown = -1,
+ Ok = 0,
+ Info = 1,
+ Warning = 2,
+
+ FailureBit = 0x10,
+
+ ExpressionFailed = FailureBit | 1,
+ ExplicitFailure = FailureBit | 2,
+
+ Exception = 0x100 | FailureBit,
+
+ ThrewException = Exception | 1,
+ DidntThrowException = Exception | 2,
+
+ FatalErrorCondition = 0x200 | FailureBit
+
+ }; };
+
+ inline bool isOk( ResultWas::OfType resultType ) {
+ return ( resultType & ResultWas::FailureBit ) == 0;
+ }
+ inline bool isJustInfo( int flags ) {
+ return flags == ResultWas::Info;
+ }
+
+ // ResultDisposition::Flags enum
+ struct ResultDisposition { enum Flags {
+ Normal = 0x00,
+
+ ContinueOnFailure = 0x01, // Failures fail test, but execution continues
+ FalseTest = 0x02, // Prefix expression with !
+ SuppressFail = 0x04 // Failures are reported but do not fail the test
+ }; };
+
+ inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
+ return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
+ }
+
+ inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
+ inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
+ inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
+
+} // end namespace Catch
+
+// #included from: catch_assertionresult.h
+#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct AssertionInfo
+ {
+ AssertionInfo() {}
+ AssertionInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ std::string const& _capturedExpression,
+ ResultDisposition::Flags _resultDisposition );
+
+ std::string macroName;
+ SourceLineInfo lineInfo;
+ std::string capturedExpression;
+ ResultDisposition::Flags resultDisposition;
+ };
+
+ struct AssertionResultData
+ {
+ AssertionResultData() : resultType( ResultWas::Unknown ) {}
+
+ std::string reconstructedExpression;
+ std::string message;
+ ResultWas::OfType resultType;
+ };
+
+ class AssertionResult {
+ public:
+ AssertionResult();
+ AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
+ ~AssertionResult();
+# ifdef CATCH_CPP11_OR_GREATER
+ AssertionResult( AssertionResult const& ) = default;
+ AssertionResult( AssertionResult && ) = default;
+ AssertionResult& operator = ( AssertionResult const& ) = default;
+ AssertionResult& operator = ( AssertionResult && ) = default;
+# endif
+
+ bool isOk() const;
+ bool succeeded() const;
+ ResultWas::OfType getResultType() const;
+ bool hasExpression() const;
+ bool hasMessage() const;
+ std::string getExpression() const;
+ std::string getExpressionInMacro() const;
+ bool hasExpandedExpression() const;
+ std::string getExpandedExpression() const;
+ std::string getMessage() const;
+ SourceLineInfo getSourceInfo() const;
+ std::string getTestMacroName() const;
+
+ protected:
+ AssertionInfo m_info;
+ AssertionResultData m_resultData;
+ };
+
+} // end namespace Catch
+
+namespace Catch {
+
+ struct TestFailureException{};
+
+ template<typename T> class ExpressionLhs;
+
+ struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
+
+ struct CopyableStream {
+ CopyableStream() {}
+ CopyableStream( CopyableStream const& other ) {
+ oss << other.oss.str();
+ }
+ CopyableStream& operator=( CopyableStream const& other ) {
+ oss.str("");
+ oss << other.oss.str();
+ return *this;
+ }
+ std::ostringstream oss;
+ };
+
+ class ResultBuilder {
+ public:
+ ResultBuilder( char const* macroName,
+ SourceLineInfo const& lineInfo,
+ char const* capturedExpression,
+ ResultDisposition::Flags resultDisposition );
+
+ template<typename T>
+ ExpressionLhs<T const&> operator->* ( T const& operand );
+ ExpressionLhs<bool> operator->* ( bool value );
+
+ template<typename T>
+ ResultBuilder& operator << ( T const& value ) {
+ m_stream.oss << value;
+ return *this;
+ }
+
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
+
+ ResultBuilder& setResultType( ResultWas::OfType result );
+ ResultBuilder& setResultType( bool result );
+ ResultBuilder& setLhs( std::string const& lhs );
+ ResultBuilder& setRhs( std::string const& rhs );
+ ResultBuilder& setOp( std::string const& op );
+
+ void endExpression();
+
+ std::string reconstructExpression() const;
+ AssertionResult build() const;
+
+ void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
+ void captureResult( ResultWas::OfType resultType );
+ void captureExpression();
+ void react();
+ bool shouldDebugBreak() const;
+ bool allowThrows() const;
+
+ private:
+ AssertionInfo m_assertionInfo;
+ AssertionResultData m_data;
+ struct ExprComponents {
+ ExprComponents() : testFalse( false ) {}
+ bool testFalse;
+ std::string lhs, rhs, op;
+ } m_exprComponents;
+ CopyableStream m_stream;
+
+ bool m_shouldDebugBreak;
+ bool m_shouldThrow;
+ };
+
+} // namespace Catch
+
+// Include after due to circular dependency:
+// #included from: catch_expression_lhs.hpp
+#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
+
+// #included from: catch_evaluate.hpp
+#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
+#endif
+
+#include <cstddef>
+
+namespace Catch {
+namespace Internal {
+
+ enum Operator {
+ IsEqualTo,
+ IsNotEqualTo,
+ IsLessThan,
+ IsGreaterThan,
+ IsLessThanOrEqualTo,
+ IsGreaterThanOrEqualTo
+ };
+
+ template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } };
+ template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } };
+ template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } };
+ template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } };
+ template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } };
+ template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } };
+ template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
+
+ template<typename T>
+ inline T& opCast(T const& t) { return const_cast<T&>(t); }
+
+// nullptr_t support based on pull request #154 from Konstantin Baumann
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+ inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
+#endif // CATCH_CONFIG_CPP11_NULLPTR
+
+ // So the compare overloads can be operator agnostic we convey the operator as a template
+ // enum, which is used to specialise an Evaluator for doing the comparison.
+ template<typename T1, typename T2, Operator Op>
+ class Evaluator{};
+
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs) {
+ return opCast( lhs ) == opCast( rhs );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsNotEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return opCast( lhs ) != opCast( rhs );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsLessThan> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return opCast( lhs ) < opCast( rhs );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsGreaterThan> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return opCast( lhs ) > opCast( rhs );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return opCast( lhs ) >= opCast( rhs );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return opCast( lhs ) <= opCast( rhs );
+ }
+ };
+
+ template<Operator Op, typename T1, typename T2>
+ bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
+ return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
+ }
+
+ // This level of indirection allows us to specialise for integer types
+ // to avoid signed/ unsigned warnings
+
+ // "base" overload
+ template<Operator Op, typename T1, typename T2>
+ bool compare( T1 const& lhs, T2 const& rhs ) {
+ return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
+ }
+
+ // unsigned X to int
+ template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+ }
+
+ // unsigned X to long
+ template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+ }
+
+ // int to unsigned X
+ template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+ }
+
+ // long to unsigned X
+ template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+
+ // pointer to long (when comparing against NULL)
+ template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
+ }
+
+ // pointer to int (when comparing against NULL)
+ template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
+ }
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+ // pointer to nullptr_t (when comparing against nullptr)
+ template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( NULL, rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, NULL );
+ }
+#endif // CATCH_CONFIG_CPP11_NULLPTR
+
+} // end of namespace Internal
+} // end of namespace Catch
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+// #included from: catch_tostring.h
+#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
+
+// #included from: catch_sfinae.hpp
+#define TWOBLUECUBES_CATCH_SFINAE_HPP_INCLUDED
+
+// Try to detect if the current compiler supports SFINAE
+
+namespace Catch {
+
+ struct TrueType {
+ static const bool value = true;
+ typedef void Enable;
+ char sizer[1];
+ };
+ struct FalseType {
+ static const bool value = false;
+ typedef void Disable;
+ char sizer[2];
+ };
+
+#ifdef CATCH_CONFIG_SFINAE
+
+ template<bool> struct NotABooleanExpression;
+
+ template<bool c> struct If : NotABooleanExpression<c> {};
+ template<> struct If<true> : TrueType {};
+ template<> struct If<false> : FalseType {};
+
+ template<int size> struct SizedIf;
+ template<> struct SizedIf<sizeof(TrueType)> : TrueType {};
+ template<> struct SizedIf<sizeof(FalseType)> : FalseType {};
+
+#endif // CATCH_CONFIG_SFINAE
+
+} // end namespace Catch
+
+#include <sstream>
+#include <iomanip>
+#include <limits>
+#include <vector>
+#include <cstddef>
+
+#ifdef __OBJC__
+// #included from: catch_objc_arc.hpp
+#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
+
+#import <Foundation/Foundation.h>
+
+#ifdef __has_feature
+#define CATCH_ARC_ENABLED __has_feature(objc_arc)
+#else
+#define CATCH_ARC_ENABLED 0
+#endif
+
+void arcSafeRelease( NSObject* obj );
+id performOptionalSelector( id obj, SEL sel );
+
+#if !CATCH_ARC_ENABLED
+inline void arcSafeRelease( NSObject* obj ) {
+ [obj release];
+}
+inline id performOptionalSelector( id obj, SEL sel ) {
+ if( [obj respondsToSelector: sel] )
+ return [obj performSelector: sel];
+ return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED
+#define CATCH_ARC_STRONG
+#else
+inline void arcSafeRelease( NSObject* ){}
+inline id performOptionalSelector( id obj, SEL sel ) {
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
+#endif
+ if( [obj respondsToSelector: sel] )
+ return [obj performSelector: sel];
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+ return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
+#define CATCH_ARC_STRONG __strong
+#endif
+
+#endif
+
+#ifdef CATCH_CPP11_OR_GREATER
+#include <tuple>
+#include <type_traits>
+#endif
+
+namespace Catch {
+
+// Why we're here.
+template<typename T>
+std::string toString( T const& value );
+
+// Built in overloads
+
+std::string toString( std::string const& value );
+std::string toString( std::wstring const& value );
+std::string toString( const char* const value );
+std::string toString( char* const value );
+std::string toString( const wchar_t* const value );
+std::string toString( wchar_t* const value );
+std::string toString( int value );
+std::string toString( unsigned long value );
+std::string toString( unsigned int value );
+std::string toString( const double value );
+std::string toString( const float value );
+std::string toString( bool value );
+std::string toString( char value );
+std::string toString( signed char value );
+std::string toString( unsigned char value );
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+std::string toString( std::nullptr_t );
+#endif
+
+#ifdef __OBJC__
+ std::string toString( NSString const * const& nsstring );
+ std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
+ std::string toString( NSObject* const& nsObject );
+#endif
+
+namespace Detail {
+
+ extern std::string unprintableString;
+
+// SFINAE is currently disabled by default for all compilers.
+// If the non SFINAE version of IsStreamInsertable is ambiguous for you
+// and your compiler supports SFINAE, try #defining CATCH_CONFIG_SFINAE
+#ifdef CATCH_CONFIG_SFINAE
+
+ template<typename T>
+ class IsStreamInsertableHelper {
+ template<int N> struct TrueIfSizeable : TrueType {};
+
+ template<typename T2>
+ static TrueIfSizeable<sizeof((*(std::ostream*)0) << *((T2 const*)0))> dummy(T2*);
+ static FalseType dummy(...);
+
+ public:
+ typedef SizedIf<sizeof(dummy((T*)0))> type;
+ };
+
+ template<typename T>
+ struct IsStreamInsertable : IsStreamInsertableHelper<T>::type {};
+
+#else
+
+ struct BorgType {
+ template<typename T> BorgType( T const& );
+ };
+
+ TrueType& testStreamable( std::ostream& );
+ FalseType testStreamable( FalseType );
+
+ FalseType operator<<( std::ostream const&, BorgType const& );
+
+ template<typename T>
+ struct IsStreamInsertable {
+ static std::ostream &s;
+ static T const&t;
+ enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
+ };
+
+#endif
+
+#if defined(CATCH_CPP11_OR_GREATER)
+ template<typename T,
+ bool IsEnum = std::is_enum<T>::value
+ >
+ struct EnumStringMaker
+ {
+ static std::string convert( T const& ) { return unprintableString; }
+ };
+
+ template<typename T>
+ struct EnumStringMaker<T,true>
+ {
+ static std::string convert( T const& v )
+ {
+ return ::Catch::toString(
+ static_cast<typename std::underlying_type<T>::type>(v)
+ );
+ }
+ };
+#endif
+ template<bool C>
+ struct StringMakerBase {
+#if defined(CATCH_CPP11_OR_GREATER)
+ template<typename T>
+ static std::string convert( T const& v )
+ {
+ return EnumStringMaker<T>::convert( v );
+ }
+#else
+ template<typename T>
+ static std::string convert( T const& ) { return unprintableString; }
+#endif
+ };
+
+ template<>
+ struct StringMakerBase<true> {
+ template<typename T>
+ static std::string convert( T const& _value ) {
+ std::ostringstream oss;
+ oss << _value;
+ return oss.str();
+ }
+ };
+
+ std::string rawMemoryToString( const void *object, std::size_t size );
+
+ template<typename T>
+ inline std::string rawMemoryToString( const T& object ) {
+ return rawMemoryToString( &object, sizeof(object) );
+ }
+
+} // end namespace Detail
+
+template<typename T>
+struct StringMaker :
+ Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
+
+template<typename T>
+struct StringMaker<T*> {
+ template<typename U>
+ static std::string convert( U* p ) {
+ if( !p )
+ return INTERNAL_CATCH_STRINGIFY( NULL );
+ else
+ return Detail::rawMemoryToString( p );
+ }
+};
+
+template<typename R, typename C>
+struct StringMaker<R C::*> {
+ static std::string convert( R C::* p ) {
+ if( !p )
+ return INTERNAL_CATCH_STRINGIFY( NULL );
+ else
+ return Detail::rawMemoryToString( p );
+ }
+};
+
+namespace Detail {
+ template<typename InputIterator>
+ std::string rangeToString( InputIterator first, InputIterator last );
+}
+
+//template<typename T, typename Allocator>
+//struct StringMaker<std::vector<T, Allocator> > {
+// static std::string convert( std::vector<T,Allocator> const& v ) {
+// return Detail::rangeToString( v.begin(), v.end() );
+// }
+//};
+
+template<typename T, typename Allocator>
+std::string toString( std::vector<T,Allocator> const& v ) {
+ return Detail::rangeToString( v.begin(), v.end() );
+}
+
+#ifdef CATCH_CPP11_OR_GREATER
+
+// toString for tuples
+namespace TupleDetail {
+ template<
+ typename Tuple,
+ std::size_t N = 0,
+ bool = (N < std::tuple_size<Tuple>::value)
+ >
+ struct ElementPrinter {
+ static void print( const Tuple& tuple, std::ostream& os )
+ {
+ os << ( N ? ", " : " " )
+ << Catch::toString(std::get<N>(tuple));
+ ElementPrinter<Tuple,N+1>::print(tuple,os);
+ }
+ };
+
+ template<
+ typename Tuple,
+ std::size_t N
+ >
+ struct ElementPrinter<Tuple,N,false> {
+ static void print( const Tuple&, std::ostream& ) {}
+ };
+
+}
+
+template<typename ...Types>
+struct StringMaker<std::tuple<Types...>> {
+
+ static std::string convert( const std::tuple<Types...>& tuple )
+ {
+ std::ostringstream os;
+ os << '{';
+ TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
+ os << " }";
+ return os.str();
+ }
+};
+#endif
+
+namespace Detail {
+ template<typename T>
+ std::string makeString( T const& value ) {
+ return StringMaker<T>::convert( value );
+ }
+} // end namespace Detail
+
+/// \brief converts any type to a string
+///
+/// The default template forwards on to ostringstream - except when an
+/// ostringstream overload does not exist - in which case it attempts to detect
+/// that and writes {?}.
+/// Overload (not specialise) this template for custom typs that you don't want
+/// to provide an ostream overload for.
+template<typename T>
+std::string toString( T const& value ) {
+ return StringMaker<T>::convert( value );
+}
+
+ namespace Detail {
+ template<typename InputIterator>
+ std::string rangeToString( InputIterator first, InputIterator last ) {
+ std::ostringstream oss;
+ oss << "{ ";
+ if( first != last ) {
+ oss << Catch::toString( *first );
+ for( ++first ; first != last ; ++first )
+ oss << ", " << Catch::toString( *first );
+ }
+ oss << " }";
+ return oss.str();
+ }
+}
+
+} // end namespace Catch
+
+namespace Catch {
+
+// Wraps the LHS of an expression and captures the operator and RHS (if any) -
+// wrapping them all in a ResultBuilder object
+template<typename T>
+class ExpressionLhs {
+ ExpressionLhs& operator = ( ExpressionLhs const& );
+# ifdef CATCH_CPP11_OR_GREATER
+ ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
+# endif
+
+public:
+ ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
+# ifdef CATCH_CPP11_OR_GREATER
+ ExpressionLhs( ExpressionLhs const& ) = default;
+ ExpressionLhs( ExpressionLhs && ) = default;
+# endif
+
+ template<typename RhsT>
+ ResultBuilder& operator == ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsEqualTo>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator != ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsNotEqualTo>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator < ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsLessThan>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator > ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsGreaterThan>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator <= ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator >= ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
+ }
+
+ ResultBuilder& operator == ( bool rhs ) {
+ return captureExpression<Internal::IsEqualTo>( rhs );
+ }
+
+ ResultBuilder& operator != ( bool rhs ) {
+ return captureExpression<Internal::IsNotEqualTo>( rhs );
+ }
+
+ void endExpression() {
+ bool value = m_lhs ? true : false;
+ m_rb
+ .setLhs( Catch::toString( value ) )
+ .setResultType( value )
+ .endExpression();
+ }
+
+ // Only simple binary expressions are allowed on the LHS.
+ // If more complex compositions are required then place the sub expression in parentheses
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
+
+private:
+ template<Internal::Operator Op, typename RhsT>
+ ResultBuilder& captureExpression( RhsT const& rhs ) {
+ return m_rb
+ .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
+ .setLhs( Catch::toString( m_lhs ) )
+ .setRhs( Catch::toString( rhs ) )
+ .setOp( Internal::OperatorTraits<Op>::getName() );
+ }
+
+private:
+ ResultBuilder& m_rb;
+ T m_lhs;
+};
+
+} // end namespace Catch
+
+
+namespace Catch {
+
+ template<typename T>
+ inline ExpressionLhs<T const&> ResultBuilder::operator->* ( T const& operand ) {
+ return ExpressionLhs<T const&>( *this, operand );
+ }
+
+ inline ExpressionLhs<bool> ResultBuilder::operator->* ( bool value ) {
+ return ExpressionLhs<bool>( *this, value );
+ }
+
+} // namespace Catch
+
+// #included from: catch_message.h
+#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct MessageInfo {
+ MessageInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ ResultWas::OfType _type );
+
+ std::string macroName;
+ SourceLineInfo lineInfo;
+ ResultWas::OfType type;
+ std::string message;
+ unsigned int sequence;
+
+ bool operator == ( MessageInfo const& other ) const {
+ return sequence == other.sequence;
+ }
+ bool operator < ( MessageInfo const& other ) const {
+ return sequence < other.sequence;
+ }
+ private:
+ static unsigned int globalCount;
+ };
+
+ struct MessageBuilder {
+ MessageBuilder( std::string const& macroName,
+ SourceLineInfo const& lineInfo,
+ ResultWas::OfType type )
+ : m_info( macroName, lineInfo, type )
+ {}
+
+ template<typename T>
+ MessageBuilder& operator << ( T const& value ) {
+ m_stream << value;
+ return *this;
+ }
+
+ MessageInfo m_info;
+ std::ostringstream m_stream;
+ };
+
+ class ScopedMessage {
+ public:
+ ScopedMessage( MessageBuilder const& builder );
+ ScopedMessage( ScopedMessage const& other );
+ ~ScopedMessage();
+
+ MessageInfo m_info;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_interfaces_capture.h
+#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ class TestCase;
+ class AssertionResult;
+ struct AssertionInfo;
+ struct SectionInfo;
+ struct MessageInfo;
+ class ScopedMessageBuilder;
+ struct Counts;
+
+ struct IResultCapture {
+
+ virtual ~IResultCapture();
+
+ virtual void assertionEnded( AssertionResult const& result ) = 0;
+ virtual bool sectionStarted( SectionInfo const& sectionInfo,
+ Counts& assertions ) = 0;
+ virtual void sectionEnded( SectionInfo const& name, Counts const& assertions, double _durationInSeconds ) = 0;
+ virtual void pushScopedMessage( MessageInfo const& message ) = 0;
+ virtual void popScopedMessage( MessageInfo const& message ) = 0;
+
+ virtual std::string getCurrentTestName() const = 0;
+ virtual const AssertionResult* getLastResult() const = 0;
+
+ virtual void handleFatalErrorCondition( std::string const& message ) = 0;
+ };
+
+ IResultCapture& getResultCapture();
+}
+
+// #included from: catch_debugger.h
+#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
+
+// #included from: catch_platform.h
+#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
+
+#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
+#define CATCH_PLATFORM_MAC
+#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
+#define CATCH_PLATFORM_IPHONE
+#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
+#define CATCH_PLATFORM_WINDOWS
+#endif
+
+#include <string>
+
+namespace Catch{
+
+ bool isDebuggerActive();
+ void writeToDebugConsole( std::string const& text );
+}
+
+#ifdef CATCH_PLATFORM_MAC
+
+ // The following code snippet based on:
+ // http://cocoawithlove.com/2008/03/break-into-debugger.html
+ #ifdef DEBUG
+ #if defined(__ppc64__) || defined(__ppc__)
+ #define CATCH_BREAK_INTO_DEBUGGER() \
+ if( Catch::isDebuggerActive() ) { \
+ __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
+ : : : "memory","r0","r3","r4" ); \
+ }
+ #else
+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
+ #endif
+ #endif
+
+#elif defined(_MSC_VER)
+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
+#elif defined(__MINGW32__)
+ extern "C" __declspec(dllimport) void __stdcall DebugBreak();
+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
+#endif
+
+#ifndef CATCH_BREAK_INTO_DEBUGGER
+#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
+#endif
+
+// #included from: catch_interfaces_runner.h
+#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
+
+namespace Catch {
+ class TestCase;
+
+ struct IRunner {
+ virtual ~IRunner();
+ virtual bool aborting() const = 0;
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// In the event of a failure works out if the debugger needs to be invoked
+// and/or an exception thrown and takes appropriate action.
+// This needs to be done as a macro so the debugger will stop in the user
+// source code rather than in Catch library code
+#define INTERNAL_CATCH_REACT( resultBuilder ) \
+ if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
+ resultBuilder.react();
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ try { \
+ ( __catchResult->*expr ).endExpression(); \
+ } \
+ catch( ... ) { \
+ __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
+ } \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::isTrue( false && (expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
+ INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
+ if( Catch::getResultCapture().getLastResult()->succeeded() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
+ INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
+ if( !Catch::getResultCapture().getLastResult()->succeeded() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ try { \
+ expr; \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ } \
+ catch( ... ) { \
+ __catchResult.useActiveException( resultDisposition ); \
+ } \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS( expr, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ if( __catchResult.allowThrows() ) \
+ try { \
+ expr; \
+ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
+ } \
+ catch( ... ) { \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ } \
+ else \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ if( __catchResult.allowThrows() ) \
+ try { \
+ expr; \
+ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
+ } \
+ catch( exceptionType ) { \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ } \
+ catch( ... ) { \
+ __catchResult.useActiveException( resultDisposition ); \
+ } \
+ else \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
+ __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
+ __catchResult.captureResult( messageType ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+#else
+ #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
+ __catchResult << log + ::Catch::StreamEndStop(); \
+ __catchResult.captureResult( messageType ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_INFO( log, macroName ) \
+ Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg " " #matcher, resultDisposition ); \
+ try { \
+ std::string matcherAsString = ::Catch::Matchers::matcher.toString(); \
+ __catchResult \
+ .setLhs( Catch::toString( arg ) ) \
+ .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
+ .setOp( "matches" ) \
+ .setResultType( ::Catch::Matchers::matcher.match( arg ) ); \
+ __catchResult.captureExpression(); \
+ } catch( ... ) { \
+ __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
+ } \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+// #included from: internal/catch_section.h
+#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
+
+// #included from: catch_section_info.h
+#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
+
+namespace Catch {
+
+ struct SectionInfo {
+ SectionInfo
+ ( SourceLineInfo const& _lineInfo,
+ std::string const& _name,
+ std::string const& _description = std::string() );
+
+ std::string name;
+ std::string description;
+ SourceLineInfo lineInfo;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_totals.hpp
+#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
+
+#include <cstddef>
+
+namespace Catch {
+
+ struct Counts {
+ Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
+
+ Counts operator - ( Counts const& other ) const {
+ Counts diff;
+ diff.passed = passed - other.passed;
+ diff.failed = failed - other.failed;
+ diff.failedButOk = failedButOk - other.failedButOk;
+ return diff;
+ }
+ Counts& operator += ( Counts const& other ) {
+ passed += other.passed;
+ failed += other.failed;
+ failedButOk += other.failedButOk;
+ return *this;
+ }
+
+ std::size_t total() const {
+ return passed + failed + failedButOk;
+ }
+ bool allPassed() const {
+ return failed == 0 && failedButOk == 0;
+ }
+ bool allOk() const {
+ return failed == 0;
+ }
+
+ std::size_t passed;
+ std::size_t failed;
+ std::size_t failedButOk;
+ };
+
+ struct Totals {
+
+ Totals operator - ( Totals const& other ) const {
+ Totals diff;
+ diff.assertions = assertions - other.assertions;
+ diff.testCases = testCases - other.testCases;
+ return diff;
+ }
+
+ Totals delta( Totals const& prevTotals ) const {
+ Totals diff = *this - prevTotals;
+ if( diff.assertions.failed > 0 )
+ ++diff.testCases.failed;
+ else if( diff.assertions.failedButOk > 0 )
+ ++diff.testCases.failedButOk;
+ else
+ ++diff.testCases.passed;
+ return diff;
+ }
+
+ Totals& operator += ( Totals const& other ) {
+ assertions += other.assertions;
+ testCases += other.testCases;
+ return *this;
+ }
+
+ Counts assertions;
+ Counts testCases;
+ };
+}
+
+// #included from: catch_timer.h
+#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
+
+#ifdef CATCH_PLATFORM_WINDOWS
+typedef unsigned long long uint64_t;
+#else
+#include <stdint.h>
+#endif
+
+namespace Catch {
+
+ class Timer {
+ public:
+ Timer() : m_ticks( 0 ) {}
+ void start();
+ unsigned int getElapsedMicroseconds() const;
+ unsigned int getElapsedMilliseconds() const;
+ double getElapsedSeconds() const;
+
+ private:
+ uint64_t m_ticks;
+ };
+
+} // namespace Catch
+
+#include <string>
+
+namespace Catch {
+
+ class Section : NonCopyable {
+ public:
+ Section( SectionInfo const& info );
+ ~Section();
+
+ // This indicates whether the section should be executed or not
+ operator bool() const;
+
+ private:
+ SectionInfo m_info;
+
+ std::string m_name;
+ Counts m_assertions;
+ bool m_sectionIncluded;
+ Timer m_timer;
+ };
+
+} // end namespace Catch
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define INTERNAL_CATCH_SECTION( ... ) \
+ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
+#else
+ #define INTERNAL_CATCH_SECTION( name, desc ) \
+ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
+#endif
+
+// #included from: internal/catch_generators.hpp
+#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
+
+#include <iterator>
+#include <vector>
+#include <string>
+#include <stdlib.h>
+
+namespace Catch {
+
+template<typename T>
+struct IGenerator {
+ virtual ~IGenerator() {}
+ virtual T getValue( std::size_t index ) const = 0;
+ virtual std::size_t size () const = 0;
+};
+
+template<typename T>
+class BetweenGenerator : public IGenerator<T> {
+public:
+ BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
+
+ virtual T getValue( std::size_t index ) const {
+ return m_from+static_cast<int>( index );
+ }
+
+ virtual std::size_t size() const {
+ return static_cast<std::size_t>( 1+m_to-m_from );
+ }
+
+private:
+
+ T m_from;
+ T m_to;
+};
+
+template<typename T>
+class ValuesGenerator : public IGenerator<T> {
+public:
+ ValuesGenerator(){}
+
+ void add( T value ) {
+ m_values.push_back( value );
+ }
+
+ virtual T getValue( std::size_t index ) const {
+ return m_values[index];
+ }
+
+ virtual std::size_t size() const {
+ return m_values.size();
+ }
+
+private:
+ std::vector<T> m_values;
+};
+
+template<typename T>
+class CompositeGenerator {
+public:
+ CompositeGenerator() : m_totalSize( 0 ) {}
+
+ // *** Move semantics, similar to auto_ptr ***
+ CompositeGenerator( CompositeGenerator& other )
+ : m_fileInfo( other.m_fileInfo ),
+ m_totalSize( 0 )
+ {
+ move( other );
+ }
+
+ CompositeGenerator& setFileInfo( const char* fileInfo ) {
+ m_fileInfo = fileInfo;
+ return *this;
+ }
+
+ ~CompositeGenerator() {
+ deleteAll( m_composed );
+ }
+
+ operator T () const {
+ size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
+
+ typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
+ typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
+ for( size_t index = 0; it != itEnd; ++it )
+ {
+ const IGenerator<T>* generator = *it;
+ if( overallIndex >= index && overallIndex < index + generator->size() )
+ {
+ return generator->getValue( overallIndex-index );
+ }
+ index += generator->size();
+ }
+ CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
+ return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so
+ }
+
+ void add( const IGenerator<T>* generator ) {
+ m_totalSize += generator->size();
+ m_composed.push_back( generator );
+ }
+
+ CompositeGenerator& then( CompositeGenerator& other ) {
+ move( other );
+ return *this;
+ }
+
+ CompositeGenerator& then( T value ) {
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( value );
+ add( valuesGen );
+ return *this;
+ }
+
+private:
+
+ void move( CompositeGenerator& other ) {
+ std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
+ m_totalSize += other.m_totalSize;
+ other.m_composed.clear();
+ }
+
+ std::vector<const IGenerator<T>*> m_composed;
+ std::string m_fileInfo;
+ size_t m_totalSize;
+};
+
+namespace Generators
+{
+ template<typename T>
+ CompositeGenerator<T> between( T from, T to ) {
+ CompositeGenerator<T> generators;
+ generators.add( new BetweenGenerator<T>( from, to ) );
+ return generators;
+ }
+
+ template<typename T>
+ CompositeGenerator<T> values( T val1, T val2 ) {
+ CompositeGenerator<T> generators;
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( val1 );
+ valuesGen->add( val2 );
+ generators.add( valuesGen );
+ return generators;
+ }
+
+ template<typename T>
+ CompositeGenerator<T> values( T val1, T val2, T val3 ){
+ CompositeGenerator<T> generators;
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( val1 );
+ valuesGen->add( val2 );
+ valuesGen->add( val3 );
+ generators.add( valuesGen );
+ return generators;
+ }
+
+ template<typename T>
+ CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
+ CompositeGenerator<T> generators;
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( val1 );
+ valuesGen->add( val2 );
+ valuesGen->add( val3 );
+ valuesGen->add( val4 );
+ generators.add( valuesGen );
+ return generators;
+ }
+
+} // end namespace Generators
+
+using namespace Generators;
+
+} // end namespace Catch
+
+#define INTERNAL_CATCH_LINESTR2( line ) #line
+#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
+
+#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
+
+// #included from: internal/catch_interfaces_exception.h
+#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
+
+#include <string>
+// #included from: catch_interfaces_registry_hub.h
+#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ class TestCase;
+ struct ITestCaseRegistry;
+ struct IExceptionTranslatorRegistry;
+ struct IExceptionTranslator;
+ struct IReporterRegistry;
+ struct IReporterFactory;
+
+ struct IRegistryHub {
+ virtual ~IRegistryHub();
+
+ virtual IReporterRegistry const& getReporterRegistry() const = 0;
+ virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
+ virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
+ };
+
+ struct IMutableRegistryHub {
+ virtual ~IMutableRegistryHub();
+ virtual void registerReporter( std::string const& name, IReporterFactory* factory ) = 0;
+ virtual void registerTest( TestCase const& testInfo ) = 0;
+ virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
+ };
+
+ IRegistryHub& getRegistryHub();
+ IMutableRegistryHub& getMutableRegistryHub();
+ void cleanUp();
+ std::string translateActiveException();
+
+}
+
+
+namespace Catch {
+
+ typedef std::string(*exceptionTranslateFunction)();
+
+ struct IExceptionTranslator {
+ virtual ~IExceptionTranslator();
+ virtual std::string translate() const = 0;
+ };
+
+ struct IExceptionTranslatorRegistry {
+ virtual ~IExceptionTranslatorRegistry();
+
+ virtual std::string translateActiveException() const = 0;
+ };
+
+ class ExceptionTranslatorRegistrar {
+ template<typename T>
+ class ExceptionTranslator : public IExceptionTranslator {
+ public:
+
+ ExceptionTranslator( std::string(*translateFunction)( T& ) )
+ : m_translateFunction( translateFunction )
+ {}
+
+ virtual std::string translate() const {
+ try {
+ throw;
+ }
+ catch( T& ex ) {
+ return m_translateFunction( ex );
+ }
+ }
+
+ protected:
+ std::string(*m_translateFunction)( T& );
+ };
+
+ public:
+ template<typename T>
+ ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
+ getMutableRegistryHub().registerTranslator
+ ( new ExceptionTranslator<T>( translateFunction ) );
+ }
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \
+ static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \
+ namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\
+ static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature )
+
+// #included from: internal/catch_approx.hpp
+#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
+
+#include <cmath>
+#include <limits>
+
+namespace Catch {
+namespace Detail {
+
+ class Approx {
+ public:
+ explicit Approx ( double value )
+ : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
+ m_scale( 1.0 ),
+ m_value( value )
+ {}
+
+ Approx( Approx const& other )
+ : m_epsilon( other.m_epsilon ),
+ m_scale( other.m_scale ),
+ m_value( other.m_value )
+ {}
+
+ static Approx custom() {
+ return Approx( 0 );
+ }
+
+ Approx operator()( double value ) {
+ Approx approx( value );
+ approx.epsilon( m_epsilon );
+ approx.scale( m_scale );
+ return approx;
+ }
+
+ friend bool operator == ( double lhs, Approx const& rhs ) {
+ // Thanks to Richard Harris for his help refining this formula
+ return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
+ }
+
+ friend bool operator == ( Approx const& lhs, double rhs ) {
+ return operator==( rhs, lhs );
+ }
+
+ friend bool operator != ( double lhs, Approx const& rhs ) {
+ return !operator==( lhs, rhs );
+ }
+
+ friend bool operator != ( Approx const& lhs, double rhs ) {
+ return !operator==( rhs, lhs );
+ }
+
+ Approx& epsilon( double newEpsilon ) {
+ m_epsilon = newEpsilon;
+ return *this;
+ }
+
+ Approx& scale( double newScale ) {
+ m_scale = newScale;
+ return *this;
+ }
+
+ std::string toString() const {
+ std::ostringstream oss;
+ oss << "Approx( " << Catch::toString( m_value ) << " )";
+ return oss.str();
+ }
+
+ private:
+ double m_epsilon;
+ double m_scale;
+ double m_value;
+ };
+}
+
+template<>
+inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
+ return value.toString();
+}
+
+} // end namespace Catch
+
+// #included from: internal/catch_matchers.hpp
+#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
+
+namespace Catch {
+namespace Matchers {
+ namespace Impl {
+
+ template<typename ExpressionT>
+ struct Matcher : SharedImpl<IShared>
+ {
+ typedef ExpressionT ExpressionType;
+
+ virtual ~Matcher() {}
+ virtual Ptr<Matcher> clone() const = 0;
+ virtual bool match( ExpressionT const& expr ) const = 0;
+ virtual std::string toString() const = 0;
+ };
+
+ template<typename DerivedT, typename ExpressionT>
+ struct MatcherImpl : Matcher<ExpressionT> {
+
+ virtual Ptr<Matcher<ExpressionT> > clone() const {
+ return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
+ }
+ };
+
+ namespace Generic {
+
+ template<typename ExpressionT>
+ class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
+ public:
+
+ AllOf() {}
+ AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
+
+ AllOf& add( Matcher<ExpressionT> const& matcher ) {
+ m_matchers.push_back( matcher.clone() );
+ return *this;
+ }
+ virtual bool match( ExpressionT const& expr ) const
+ {
+ for( std::size_t i = 0; i < m_matchers.size(); ++i )
+ if( !m_matchers[i]->match( expr ) )
+ return false;
+ return true;
+ }
+ virtual std::string toString() const {
+ std::ostringstream oss;
+ oss << "( ";
+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+ if( i != 0 )
+ oss << " and ";
+ oss << m_matchers[i]->toString();
+ }
+ oss << " )";
+ return oss.str();
+ }
+
+ private:
+ std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
+ };
+
+ template<typename ExpressionT>
+ class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
+ public:
+
+ AnyOf() {}
+ AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
+
+ AnyOf& add( Matcher<ExpressionT> const& matcher ) {
+ m_matchers.push_back( matcher.clone() );
+ return *this;
+ }
+ virtual bool match( ExpressionT const& expr ) const
+ {
+ for( std::size_t i = 0; i < m_matchers.size(); ++i )
+ if( m_matchers[i]->match( expr ) )
+ return true;
+ return false;
+ }
+ virtual std::string toString() const {
+ std::ostringstream oss;
+ oss << "( ";
+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+ if( i != 0 )
+ oss << " or ";
+ oss << m_matchers[i]->toString();
+ }
+ oss << " )";
+ return oss.str();
+ }
+
+ private:
+ std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
+ };
+
+ }
+
+ namespace StdString {
+
+ inline std::string makeString( std::string const& str ) { return str; }
+ inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
+
+ struct Equals : MatcherImpl<Equals, std::string> {
+ Equals( std::string const& str ) : m_str( str ){}
+ Equals( Equals const& other ) : m_str( other.m_str ){}
+
+ virtual ~Equals();
+
+ virtual bool match( std::string const& expr ) const {
+ return m_str == expr;
+ }
+ virtual std::string toString() const {
+ return "equals: \"" + m_str + "\"";
+ }
+
+ std::string m_str;
+ };
+
+ struct Contains : MatcherImpl<Contains, std::string> {
+ Contains( std::string const& substr ) : m_substr( substr ){}
+ Contains( Contains const& other ) : m_substr( other.m_substr ){}
+
+ virtual ~Contains();
+
+ virtual bool match( std::string const& expr ) const {
+ return expr.find( m_substr ) != std::string::npos;
+ }
+ virtual std::string toString() const {
+ return "contains: \"" + m_substr + "\"";
+ }
+
+ std::string m_substr;
+ };
+
+ struct StartsWith : MatcherImpl<StartsWith, std::string> {
+ StartsWith( std::string const& substr ) : m_substr( substr ){}
+ StartsWith( StartsWith const& other ) : m_substr( other.m_substr ){}
+
+ virtual ~StartsWith();
+
+ virtual bool match( std::string const& expr ) const {
+ return expr.find( m_substr ) == 0;
+ }
+ virtual std::string toString() const {
+ return "starts with: \"" + m_substr + "\"";
+ }
+
+ std::string m_substr;
+ };
+
+ struct EndsWith : MatcherImpl<EndsWith, std::string> {
+ EndsWith( std::string const& substr ) : m_substr( substr ){}
+ EndsWith( EndsWith const& other ) : m_substr( other.m_substr ){}
+
+ virtual ~EndsWith();
+
+ virtual bool match( std::string const& expr ) const {
+ return expr.find( m_substr ) == expr.size() - m_substr.size();
+ }
+ virtual std::string toString() const {
+ return "ends with: \"" + m_substr + "\"";
+ }
+
+ std::string m_substr;
+ };
+ } // namespace StdString
+ } // namespace Impl
+
+ // The following functions create the actual matcher objects.
+ // This allows the types to be inferred
+ template<typename ExpressionT>
+ inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2 ) {
+ return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
+ }
+ template<typename ExpressionT>
+ inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2,
+ Impl::Matcher<ExpressionT> const& m3 ) {
+ return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
+ }
+ template<typename ExpressionT>
+ inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2 ) {
+ return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
+ }
+ template<typename ExpressionT>
+ inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2,
+ Impl::Matcher<ExpressionT> const& m3 ) {
+ return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
+ }
+
+ inline Impl::StdString::Equals Equals( std::string const& str ) {
+ return Impl::StdString::Equals( str );
+ }
+ inline Impl::StdString::Equals Equals( const char* str ) {
+ return Impl::StdString::Equals( Impl::StdString::makeString( str ) );
+ }
+ inline Impl::StdString::Contains Contains( std::string const& substr ) {
+ return Impl::StdString::Contains( substr );
+ }
+ inline Impl::StdString::Contains Contains( const char* substr ) {
+ return Impl::StdString::Contains( Impl::StdString::makeString( substr ) );
+ }
+ inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) {
+ return Impl::StdString::StartsWith( substr );
+ }
+ inline Impl::StdString::StartsWith StartsWith( const char* substr ) {
+ return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
+ }
+ inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) {
+ return Impl::StdString::EndsWith( substr );
+ }
+ inline Impl::StdString::EndsWith EndsWith( const char* substr ) {
+ return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
+ }
+
+} // namespace Matchers
+
+using namespace Matchers;
+
+} // namespace Catch
+
+// #included from: internal/catch_interfaces_tag_alias_registry.h
+#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
+
+// #included from: catch_tag_alias.h
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct TagAlias {
+ TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
+
+ std::string tag;
+ SourceLineInfo lineInfo;
+ };
+
+ struct RegistrarForTagAliases {
+ RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
+ };
+
+} // end namespace Catch
+
+#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
+// #included from: catch_option.hpp
+#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
+
+namespace Catch {
+
+ // An optional type
+ template<typename T>
+ class Option {
+ public:
+ Option() : nullableValue( NULL ) {}
+ Option( T const& _value )
+ : nullableValue( new( storage ) T( _value ) )
+ {}
+ Option( Option const& _other )
+ : nullableValue( _other ? new( storage ) T( *_other ) : NULL )
+ {}
+
+ ~Option() {
+ reset();
+ }
+
+ Option& operator= ( Option const& _other ) {
+ if( &_other != this ) {
+ reset();
+ if( _other )
+ nullableValue = new( storage ) T( *_other );
+ }
+ return *this;
+ }
+ Option& operator = ( T const& _value ) {
+ reset();
+ nullableValue = new( storage ) T( _value );
+ return *this;
+ }
+
+ void reset() {
+ if( nullableValue )
+ nullableValue->~T();
+ nullableValue = NULL;
+ }
+
+ T& operator*() { return *nullableValue; }
+ T const& operator*() const { return *nullableValue; }
+ T* operator->() { return nullableValue; }
+ const T* operator->() const { return nullableValue; }
+
+ T valueOr( T const& defaultValue ) const {
+ return nullableValue ? *nullableValue : defaultValue;
+ }
+
+ bool some() const { return nullableValue != NULL; }
+ bool none() const { return nullableValue == NULL; }
+
+ bool operator !() const { return nullableValue == NULL; }
+ operator SafeBool::type() const {
+ return SafeBool::makeSafe( some() );
+ }
+
+ private:
+ T* nullableValue;
+ char storage[sizeof(T)];
+ };
+
+} // end namespace Catch
+
+namespace Catch {
+
+ struct ITagAliasRegistry {
+ virtual ~ITagAliasRegistry();
+ virtual Option<TagAlias> find( std::string const& alias ) const = 0;
+ virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
+
+ static ITagAliasRegistry const& get();
+ };
+
+} // end namespace Catch
+
+// These files are included here so the single_include script doesn't put them
+// in the conditionally compiled sections
+// #included from: internal/catch_test_case_info.h
+#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
+
+#include <string>
+#include <set>
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+namespace Catch {
+
+ struct ITestCase;
+
+ struct TestCaseInfo {
+ enum SpecialProperties{
+ None = 0,
+ IsHidden = 1 << 1,
+ ShouldFail = 1 << 2,
+ MayFail = 1 << 3,
+ Throws = 1 << 4
+ };
+
+ TestCaseInfo( std::string const& _name,
+ std::string const& _className,
+ std::string const& _description,
+ std::set<std::string> const& _tags,
+ SourceLineInfo const& _lineInfo );
+
+ TestCaseInfo( TestCaseInfo const& other );
+
+ bool isHidden() const;
+ bool throws() const;
+ bool okToFail() const;
+ bool expectedToFail() const;
+
+ std::string name;
+ std::string className;
+ std::string description;
+ std::set<std::string> tags;
+ std::set<std::string> lcaseTags;
+ std::string tagsAsString;
+ SourceLineInfo lineInfo;
+ SpecialProperties properties;
+ };
+
+ class TestCase : public TestCaseInfo {
+ public:
+
+ TestCase( ITestCase* testCase, TestCaseInfo const& info );
+ TestCase( TestCase const& other );
+
+ TestCase withName( std::string const& _newName ) const;
+
+ void invoke() const;
+
+ TestCaseInfo const& getTestCaseInfo() const;
+
+ void swap( TestCase& other );
+ bool operator == ( TestCase const& other ) const;
+ bool operator < ( TestCase const& other ) const;
+ TestCase& operator = ( TestCase const& other );
+
+ private:
+ Ptr<ITestCase> test;
+ };
+
+ TestCase makeTestCase( ITestCase* testCase,
+ std::string const& className,
+ std::string const& name,
+ std::string const& description,
+ SourceLineInfo const& lineInfo );
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+
+#ifdef __OBJC__
+// #included from: internal/catch_objc.hpp
+#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
+
+#import <objc/runtime.h>
+
+#include <string>
+
+// NB. Any general catch headers included here must be included
+// in catch.hpp first to make sure they are included by the single
+// header for non obj-usage
+
+///////////////////////////////////////////////////////////////////////////////
+// This protocol is really only here for (self) documenting purposes, since
+// all its methods are optional.
+@protocol OcFixture
+
+@optional
+
+-(void) setUp;
+-(void) tearDown;
+
+@end
+
+namespace Catch {
+
+ class OcMethod : public SharedImpl<ITestCase> {
+
+ public:
+ OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
+
+ virtual void invoke() const {
+ id obj = [[m_cls alloc] init];
+
+ performOptionalSelector( obj, @selector(setUp) );
+ performOptionalSelector( obj, m_sel );
+ performOptionalSelector( obj, @selector(tearDown) );
+
+ arcSafeRelease( obj );
+ }
+ private:
+ virtual ~OcMethod() {}
+
+ Class m_cls;
+ SEL m_sel;
+ };
+
+ namespace Detail{
+
+ inline std::string getAnnotation( Class cls,
+ std::string const& annotationName,
+ std::string const& testCaseName ) {
+ NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
+ SEL sel = NSSelectorFromString( selStr );
+ arcSafeRelease( selStr );
+ id value = performOptionalSelector( cls, sel );
+ if( value )
+ return [(NSString*)value UTF8String];
+ return "";
+ }
+ }
+
+ inline size_t registerTestMethods() {
+ size_t noTestMethods = 0;
+ int noClasses = objc_getClassList( NULL, 0 );
+
+ Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
+ objc_getClassList( classes, noClasses );
+
+ for( int c = 0; c < noClasses; c++ ) {
+ Class cls = classes[c];
+ {
+ u_int count;
+ Method* methods = class_copyMethodList( cls, &count );
+ for( u_int m = 0; m < count ; m++ ) {
+ SEL selector = method_getName(methods[m]);
+ std::string methodName = sel_getName(selector);
+ if( startsWith( methodName, "Catch_TestCase_" ) ) {
+ std::string testCaseName = methodName.substr( 15 );
+ std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
+ std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
+ const char* className = class_getName( cls );
+
+ getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
+ noTestMethods++;
+ }
+ }
+ free(methods);
+ }
+ }
+ return noTestMethods;
+ }
+
+ namespace Matchers {
+ namespace Impl {
+ namespace NSStringMatchers {
+
+ template<typename MatcherT>
+ struct StringHolder : MatcherImpl<MatcherT, NSString*>{
+ StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
+ StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
+ StringHolder() {
+ arcSafeRelease( m_substr );
+ }
+
+ NSString* m_substr;
+ };
+
+ struct Equals : StringHolder<Equals> {
+ Equals( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str isEqualToString:m_substr];
+ }
+
+ virtual std::string toString() const {
+ return "equals string: " + Catch::toString( m_substr );
+ }
+ };
+
+ struct Contains : StringHolder<Contains> {
+ Contains( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location != NSNotFound;
+ }
+
+ virtual std::string toString() const {
+ return "contains string: " + Catch::toString( m_substr );
+ }
+ };
+
+ struct StartsWith : StringHolder<StartsWith> {
+ StartsWith( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location == 0;
+ }
+
+ virtual std::string toString() const {
+ return "starts with: " + Catch::toString( m_substr );
+ }
+ };
+ struct EndsWith : StringHolder<EndsWith> {
+ EndsWith( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location == [str length] - [m_substr length];
+ }
+
+ virtual std::string toString() const {
+ return "ends with: " + Catch::toString( m_substr );
+ }
+ };
+
+ } // namespace NSStringMatchers
+ } // namespace Impl
+
+ inline Impl::NSStringMatchers::Equals
+ Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
+
+ inline Impl::NSStringMatchers::Contains
+ Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
+
+ inline Impl::NSStringMatchers::StartsWith
+ StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
+
+ inline Impl::NSStringMatchers::EndsWith
+ EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
+
+ } // namespace Matchers
+
+ using namespace Matchers;
+
+} // namespace Catch
+
+///////////////////////////////////////////////////////////////////////////////
+#define OC_TEST_CASE( name, desc )\
++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
+{\
+return @ name; \
+}\
++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
+{ \
+return @ desc; \
+} \
+-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
+
+#endif
+
+#ifdef CATCH_IMPL
+// #included from: internal/catch_impl.hpp
+#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
+
+// Collect all the implementation files together here
+// These are the equivalent of what would usually be cpp files
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wweak-vtables"
+#endif
+
+// #included from: ../catch_runner.hpp
+#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
+
+// #included from: internal/catch_commandline.hpp
+#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
+
+// #included from: catch_config.hpp
+#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
+
+// #included from: catch_test_spec_parser.hpp
+#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+// #included from: catch_test_spec.hpp
+#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+#include <string>
+#include <vector>
+
+namespace Catch {
+
+ class TestSpec {
+ struct Pattern : SharedImpl<> {
+ virtual ~Pattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const = 0;
+ };
+ class NamePattern : public Pattern {
+ enum WildcardPosition {
+ NoWildcard = 0,
+ WildcardAtStart = 1,
+ WildcardAtEnd = 2,
+ WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
+ };
+
+ public:
+ NamePattern( std::string const& name ) : m_name( toLower( name ) ), m_wildcard( NoWildcard ) {
+ if( startsWith( m_name, "*" ) ) {
+ m_name = m_name.substr( 1 );
+ m_wildcard = WildcardAtStart;
+ }
+ if( endsWith( m_name, "*" ) ) {
+ m_name = m_name.substr( 0, m_name.size()-1 );
+ m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
+ }
+ }
+ virtual ~NamePattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const {
+ switch( m_wildcard ) {
+ case NoWildcard:
+ return m_name == toLower( testCase.name );
+ case WildcardAtStart:
+ return endsWith( toLower( testCase.name ), m_name );
+ case WildcardAtEnd:
+ return startsWith( toLower( testCase.name ), m_name );
+ case WildcardAtBothEnds:
+ return contains( toLower( testCase.name ), m_name );
+ }
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunreachable-code"
+#endif
+ throw std::logic_error( "Unknown enum" );
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+ }
+ private:
+ std::string m_name;
+ WildcardPosition m_wildcard;
+ };
+ class TagPattern : public Pattern {
+ public:
+ TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
+ virtual ~TagPattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const {
+ return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
+ }
+ private:
+ std::string m_tag;
+ };
+ class ExcludedPattern : public Pattern {
+ public:
+ ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
+ virtual ~ExcludedPattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
+ private:
+ Ptr<Pattern> m_underlyingPattern;
+ };
+
+ struct Filter {
+ std::vector<Ptr<Pattern> > m_patterns;
+
+ bool matches( TestCaseInfo const& testCase ) const {
+ // All patterns in a filter must match for the filter to be a match
+ for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
+ if( !(*it)->matches( testCase ) )
+ return false;
+ return true;
+ }
+ };
+
+ public:
+ bool hasFilters() const {
+ return !m_filters.empty();
+ }
+ bool matches( TestCaseInfo const& testCase ) const {
+ // A TestSpec matches if any filter matches
+ for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
+ if( it->matches( testCase ) )
+ return true;
+ return false;
+ }
+
+ private:
+ std::vector<Filter> m_filters;
+
+ friend class TestSpecParser;
+ };
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+namespace Catch {
+
+ class TestSpecParser {
+ enum Mode{ None, Name, QuotedName, Tag };
+ Mode m_mode;
+ bool m_exclusion;
+ std::size_t m_start, m_pos;
+ std::string m_arg;
+ TestSpec::Filter m_currentFilter;
+ TestSpec m_testSpec;
+ ITagAliasRegistry const* m_tagAliases;
+
+ public:
+ TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
+
+ TestSpecParser& parse( std::string const& arg ) {
+ m_mode = None;
+ m_exclusion = false;
+ m_start = std::string::npos;
+ m_arg = m_tagAliases->expandAliases( arg );
+ for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
+ visitChar( m_arg[m_pos] );
+ if( m_mode == Name )
+ addPattern<TestSpec::NamePattern>();
+ return *this;
+ }
+ TestSpec testSpec() {
+ addFilter();
+ return m_testSpec;
+ }
+ private:
+ void visitChar( char c ) {
+ if( m_mode == None ) {
+ switch( c ) {
+ case ' ': return;
+ case '~': m_exclusion = true; return;
+ case '[': return startNewMode( Tag, ++m_pos );
+ case '"': return startNewMode( QuotedName, ++m_pos );
+ default: startNewMode( Name, m_pos ); break;
+ }
+ }
+ if( m_mode == Name ) {
+ if( c == ',' ) {
+ addPattern<TestSpec::NamePattern>();
+ addFilter();
+ }
+ else if( c == '[' ) {
+ if( subString() == "exclude:" )
+ m_exclusion = true;
+ else
+ addPattern<TestSpec::NamePattern>();
+ startNewMode( Tag, ++m_pos );
+ }
+ }
+ else if( m_mode == QuotedName && c == '"' )
+ addPattern<TestSpec::NamePattern>();
+ else if( m_mode == Tag && c == ']' )
+ addPattern<TestSpec::TagPattern>();
+ }
+ void startNewMode( Mode mode, std::size_t start ) {
+ m_mode = mode;
+ m_start = start;
+ }
+ std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
+ template<typename T>
+ void addPattern() {
+ std::string token = subString();
+ if( startsWith( token, "exclude:" ) ) {
+ m_exclusion = true;
+ token = token.substr( 8 );
+ }
+ if( !token.empty() ) {
+ Ptr<TestSpec::Pattern> pattern = new T( token );
+ if( m_exclusion )
+ pattern = new TestSpec::ExcludedPattern( pattern );
+ m_currentFilter.m_patterns.push_back( pattern );
+ }
+ m_exclusion = false;
+ m_mode = None;
+ }
+ void addFilter() {
+ if( !m_currentFilter.m_patterns.empty() ) {
+ m_testSpec.m_filters.push_back( m_currentFilter );
+ m_currentFilter = TestSpec::Filter();
+ }
+ }
+ };
+ inline TestSpec parseTestSpec( std::string const& arg ) {
+ return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
+ }
+
+} // namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+// #included from: catch_interfaces_config.h
+#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace Catch {
+
+ struct Verbosity { enum Level {
+ NoOutput = 0,
+ Quiet,
+ Normal
+ }; };
+
+ struct WarnAbout { enum What {
+ Nothing = 0x00,
+ NoAssertions = 0x01
+ }; };
+
+ struct ShowDurations { enum OrNot {
+ DefaultForReporter,
+ Always,
+ Never
+ }; };
+ struct RunTests { enum InWhatOrder {
+ InDeclarationOrder,
+ InLexicographicalOrder,
+ InRandomOrder
+ }; };
+
+ class TestSpec;
+
+ struct IConfig : IShared {
+
+ virtual ~IConfig();
+
+ virtual bool allowThrows() const = 0;
+ virtual std::ostream& stream() const = 0;
+ virtual std::string name() const = 0;
+ virtual bool includeSuccessfulResults() const = 0;
+ virtual bool shouldDebugBreak() const = 0;
+ virtual bool warnAboutMissingAssertions() const = 0;
+ virtual int abortAfter() const = 0;
+ virtual bool showInvisibles() const = 0;
+ virtual ShowDurations::OrNot showDurations() const = 0;
+ virtual TestSpec const& testSpec() const = 0;
+ virtual RunTests::InWhatOrder runOrder() const = 0;
+ virtual unsigned int rngSeed() const = 0;
+ virtual bool forceColour() const = 0;
+ };
+}
+
+// #included from: catch_stream.h
+#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
+
+#include <streambuf>
+
+#ifdef __clang__
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+namespace Catch {
+
+ class Stream {
+ public:
+ Stream();
+ Stream( std::streambuf* _streamBuf, bool _isOwned );
+ void release();
+
+ std::streambuf* streamBuf;
+
+ private:
+ bool isOwned;
+ };
+
+ std::ostream& cout();
+ std::ostream& cerr();
+}
+
+#include <memory>
+#include <vector>
+#include <string>
+#include <iostream>
+#include <ctime>
+
+#ifndef CATCH_CONFIG_CONSOLE_WIDTH
+#define CATCH_CONFIG_CONSOLE_WIDTH 80
+#endif
+
+namespace Catch {
+
+ struct ConfigData {
+
+ ConfigData()
+ : listTests( false ),
+ listTags( false ),
+ listReporters( false ),
+ listTestNamesOnly( false ),
+ showSuccessfulTests( false ),
+ shouldDebugBreak( false ),
+ noThrow( false ),
+ showHelp( false ),
+ showInvisibles( false ),
+ forceColour( false ),
+ abortAfter( -1 ),
+ rngSeed( 0 ),
+ verbosity( Verbosity::Normal ),
+ warnings( WarnAbout::Nothing ),
+ showDurations( ShowDurations::DefaultForReporter ),
+ runOrder( RunTests::InDeclarationOrder )
+ {}
+
+ bool listTests;
+ bool listTags;
+ bool listReporters;
+ bool listTestNamesOnly;
+
+ bool showSuccessfulTests;
+ bool shouldDebugBreak;
+ bool noThrow;
+ bool showHelp;
+ bool showInvisibles;
+ bool forceColour;
+
+ int abortAfter;
+ unsigned int rngSeed;
+
+ Verbosity::Level verbosity;
+ WarnAbout::What warnings;
+ ShowDurations::OrNot showDurations;
+ RunTests::InWhatOrder runOrder;
+
+ std::string reporterName;
+ std::string outputFilename;
+ std::string name;
+ std::string processName;
+
+ std::vector<std::string> testsOrTags;
+ };
+
+ class Config : public SharedImpl<IConfig> {
+ private:
+ Config( Config const& other );
+ Config& operator = ( Config const& other );
+ virtual void dummy();
+ public:
+
+ Config()
+ : m_os( Catch::cout().rdbuf() )
+ {}
+
+ Config( ConfigData const& data )
+ : m_data( data ),
+ m_os( Catch::cout().rdbuf() )
+ {
+ if( !data.testsOrTags.empty() ) {
+ TestSpecParser parser( ITagAliasRegistry::get() );
+ for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
+ parser.parse( data.testsOrTags[i] );
+ m_testSpec = parser.testSpec();
+ }
+ }
+
+ virtual ~Config() {
+ m_os.rdbuf( Catch::cout().rdbuf() );
+ m_stream.release();
+ }
+
+ void setFilename( std::string const& filename ) {
+ m_data.outputFilename = filename;
+ }
+
+ std::string const& getFilename() const {
+ return m_data.outputFilename ;
+ }
+
+ bool listTests() const { return m_data.listTests; }
+ bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
+ bool listTags() const { return m_data.listTags; }
+ bool listReporters() const { return m_data.listReporters; }
+
+ std::string getProcessName() const { return m_data.processName; }
+
+ bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
+
+ void setStreamBuf( std::streambuf* buf ) {
+ m_os.rdbuf( buf ? buf : Catch::cout().rdbuf() );
+ }
+
+ void useStream( std::string const& streamName ) {
+ Stream stream = createStream( streamName );
+ setStreamBuf( stream.streamBuf );
+ m_stream.release();
+ m_stream = stream;
+ }
+
+ std::string getReporterName() const { return m_data.reporterName; }
+
+ int abortAfter() const { return m_data.abortAfter; }
+
+ TestSpec const& testSpec() const { return m_testSpec; }
+
+ bool showHelp() const { return m_data.showHelp; }
+ bool showInvisibles() const { return m_data.showInvisibles; }
+
+ // IConfig interface
+ virtual bool allowThrows() const { return !m_data.noThrow; }
+ virtual std::ostream& stream() const { return m_os; }
+ virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
+ virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
+ virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
+ virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
+ virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; }
+ virtual unsigned int rngSeed() const { return m_data.rngSeed; }
+ virtual bool forceColour() const { return m_data.forceColour; }
+
+ private:
+ ConfigData m_data;
+
+ Stream m_stream;
+ mutable std::ostream m_os;
+ TestSpec m_testSpec;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_clara.h
+#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
+
+// Use Catch's value for console width (store Clara's off to the side, if present)
+#ifdef CLARA_CONFIG_CONSOLE_WIDTH
+#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
+#undef CLARA_CONFIG_CONSOLE_WIDTH
+#endif
+#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
+
+// Declare Clara inside the Catch namespace
+#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
+// #included from: ../external/clara.h
+
+// Only use header guard if we are not using an outer namespace
+#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
+
+#ifndef STITCH_CLARA_OPEN_NAMESPACE
+#define TWOBLUECUBES_CLARA_H_INCLUDED
+#define STITCH_CLARA_OPEN_NAMESPACE
+#define STITCH_CLARA_CLOSE_NAMESPACE
+#else
+#define STITCH_CLARA_CLOSE_NAMESPACE }
+#endif
+
+#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
+
+// ----------- #included from tbc_text_format.h -----------
+
+// Only use header guard if we are not using an outer namespace
+#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
+#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+#define TBC_TEXT_FORMAT_H_INCLUDED
+#endif
+
+#include <string>
+#include <vector>
+#include <sstream>
+
+// Use optional outer namespace
+#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
+#endif
+
+namespace Tbc {
+
+#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
+ const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
+#else
+ const unsigned int consoleWidth = 80;
+#endif
+
+ struct TextAttributes {
+ TextAttributes()
+ : initialIndent( std::string::npos ),
+ indent( 0 ),
+ width( consoleWidth-1 ),
+ tabChar( '\t' )
+ {}
+
+ TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
+ TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
+ TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
+ TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
+
+ std::size_t initialIndent; // indent of first line, or npos
+ std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
+ std::size_t width; // maximum width of text, including indent. Longer text will wrap
+ char tabChar; // If this char is seen the indent is changed to current pos
+ };
+
+ class Text {
+ public:
+ Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
+ : attr( _attr )
+ {
+ std::string wrappableChars = " [({.,/|\\-";
+ std::size_t indent = _attr.initialIndent != std::string::npos
+ ? _attr.initialIndent
+ : _attr.indent;
+ std::string remainder = _str;
+
+ while( !remainder.empty() ) {
+ if( lines.size() >= 1000 ) {
+ lines.push_back( "... message truncated due to excessive size" );
+ return;
+ }
+ std::size_t tabPos = std::string::npos;
+ std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
+ std::size_t pos = remainder.find_first_of( '\n' );
+ if( pos <= width ) {
+ width = pos;
+ }
+ pos = remainder.find_last_of( _attr.tabChar, width );
+ if( pos != std::string::npos ) {
+ tabPos = pos;
+ if( remainder[width] == '\n' )
+ width--;
+ remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
+ }
+
+ if( width == remainder.size() ) {
+ spliceLine( indent, remainder, width );
+ }
+ else if( remainder[width] == '\n' ) {
+ spliceLine( indent, remainder, width );
+ if( width <= 1 || remainder.size() != 1 )
+ remainder = remainder.substr( 1 );
+ indent = _attr.indent;
+ }
+ else {
+ pos = remainder.find_last_of( wrappableChars, width );
+ if( pos != std::string::npos && pos > 0 ) {
+ spliceLine( indent, remainder, pos );
+ if( remainder[0] == ' ' )
+ remainder = remainder.substr( 1 );
+ }
+ else {
+ spliceLine( indent, remainder, width-1 );
+ lines.back() += "-";
+ }
+ if( lines.size() == 1 )
+ indent = _attr.indent;
+ if( tabPos != std::string::npos )
+ indent += tabPos;
+ }
+ }
+ }
+
+ void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
+ lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
+ _remainder = _remainder.substr( _pos );
+ }
+
+ typedef std::vector<std::string>::const_iterator const_iterator;
+
+ const_iterator begin() const { return lines.begin(); }
+ const_iterator end() const { return lines.end(); }
+ std::string const& last() const { return lines.back(); }
+ std::size_t size() const { return lines.size(); }
+ std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
+ std::string toString() const {
+ std::ostringstream oss;
+ oss << *this;
+ return oss.str();
+ }
+
+ inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
+ for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
+ it != itEnd; ++it ) {
+ if( it != _text.begin() )
+ _stream << "\n";
+ _stream << *it;
+ }
+ return _stream;
+ }
+
+ private:
+ std::string str;
+ TextAttributes attr;
+ std::vector<std::string> lines;
+ };
+
+} // end namespace Tbc
+
+#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+} // end outer namespace
+#endif
+
+#endif // TBC_TEXT_FORMAT_H_INCLUDED
+
+// ----------- end of #include from tbc_text_format.h -----------
+// ........... back in /Users/philnash/Dev/OSS/Clara/srcs/clara.h
+
+#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
+
+#include <map>
+#include <algorithm>
+#include <stdexcept>
+#include <memory>
+
+// Use optional outer namespace
+#ifdef STITCH_CLARA_OPEN_NAMESPACE
+STITCH_CLARA_OPEN_NAMESPACE
+#endif
+
+namespace Clara {
+
+ struct UnpositionalTag {};
+
+ extern UnpositionalTag _;
+
+#ifdef CLARA_CONFIG_MAIN
+ UnpositionalTag _;
+#endif
+
+ namespace Detail {
+
+#ifdef CLARA_CONSOLE_WIDTH
+ const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
+#else
+ const unsigned int consoleWidth = 80;
+#endif
+
+ using namespace Tbc;
+
+ inline bool startsWith( std::string const& str, std::string const& prefix ) {
+ return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
+ }
+
+ template<typename T> struct RemoveConstRef{ typedef T type; };
+ template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
+ template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
+ template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
+
+ template<typename T> struct IsBool { static const bool value = false; };
+ template<> struct IsBool<bool> { static const bool value = true; };
+
+ template<typename T>
+ void convertInto( std::string const& _source, T& _dest ) {
+ std::stringstream ss;
+ ss << _source;
+ ss >> _dest;
+ if( ss.fail() )
+ throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
+ }
+ inline void convertInto( std::string const& _source, std::string& _dest ) {
+ _dest = _source;
+ }
+ inline void convertInto( std::string const& _source, bool& _dest ) {
+ std::string sourceLC = _source;
+ std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
+ if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
+ _dest = true;
+ else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
+ _dest = false;
+ else
+ throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" );
+ }
+ inline void convertInto( bool _source, bool& _dest ) {
+ _dest = _source;
+ }
+ template<typename T>
+ inline void convertInto( bool, T& ) {
+ throw std::runtime_error( "Invalid conversion" );
+ }
+
+ template<typename ConfigT>
+ struct IArgFunction {
+ virtual ~IArgFunction() {}
+# ifdef CATCH_CPP11_OR_GREATER
+ IArgFunction() = default;
+ IArgFunction( IArgFunction const& ) = default;
+# endif
+ virtual void set( ConfigT& config, std::string const& value ) const = 0;
+ virtual void setFlag( ConfigT& config ) const = 0;
+ virtual bool takesArg() const = 0;
+ virtual IArgFunction* clone() const = 0;
+ };
+
+ template<typename ConfigT>
+ class BoundArgFunction {
+ public:
+ BoundArgFunction() : functionObj( NULL ) {}
+ BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
+ BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : NULL ) {}
+ BoundArgFunction& operator = ( BoundArgFunction const& other ) {
+ IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : NULL;
+ delete functionObj;
+ functionObj = newFunctionObj;
+ return *this;
+ }
+ ~BoundArgFunction() { delete functionObj; }
+
+ void set( ConfigT& config, std::string const& value ) const {
+ functionObj->set( config, value );
+ }
+ void setFlag( ConfigT& config ) const {
+ functionObj->setFlag( config );
+ }
+ bool takesArg() const { return functionObj->takesArg(); }
+
+ bool isSet() const {
+ return functionObj != NULL;
+ }
+ private:
+ IArgFunction<ConfigT>* functionObj;
+ };
+
+ template<typename C>
+ struct NullBinder : IArgFunction<C>{
+ virtual void set( C&, std::string const& ) const {}
+ virtual void setFlag( C& ) const {}
+ virtual bool takesArg() const { return true; }
+ virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
+ };
+
+ template<typename C, typename M>
+ struct BoundDataMember : IArgFunction<C>{
+ BoundDataMember( M C::* _member ) : member( _member ) {}
+ virtual void set( C& p, std::string const& stringValue ) const {
+ convertInto( stringValue, p.*member );
+ }
+ virtual void setFlag( C& p ) const {
+ convertInto( true, p.*member );
+ }
+ virtual bool takesArg() const { return !IsBool<M>::value; }
+ virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
+ M C::* member;
+ };
+ template<typename C, typename M>
+ struct BoundUnaryMethod : IArgFunction<C>{
+ BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
+ virtual void set( C& p, std::string const& stringValue ) const {
+ typename RemoveConstRef<M>::type value;
+ convertInto( stringValue, value );
+ (p.*member)( value );
+ }
+ virtual void setFlag( C& p ) const {
+ typename RemoveConstRef<M>::type value;
+ convertInto( true, value );
+ (p.*member)( value );
+ }
+ virtual bool takesArg() const { return !IsBool<M>::value; }
+ virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
+ void (C::*member)( M );
+ };
+ template<typename C>
+ struct BoundNullaryMethod : IArgFunction<C>{
+ BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
+ virtual void set( C& p, std::string const& stringValue ) const {
+ bool value;
+ convertInto( stringValue, value );
+ if( value )
+ (p.*member)();
+ }
+ virtual void setFlag( C& p ) const {
+ (p.*member)();
+ }
+ virtual bool takesArg() const { return false; }
+ virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
+ void (C::*member)();
+ };
+
+ template<typename C>
+ struct BoundUnaryFunction : IArgFunction<C>{
+ BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
+ virtual void set( C& obj, std::string const& stringValue ) const {
+ bool value;
+ convertInto( stringValue, value );
+ if( value )
+ function( obj );
+ }
+ virtual void setFlag( C& p ) const {
+ function( p );
+ }
+ virtual bool takesArg() const { return false; }
+ virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
+ void (*function)( C& );
+ };
+
+ template<typename C, typename T>
+ struct BoundBinaryFunction : IArgFunction<C>{
+ BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
+ virtual void set( C& obj, std::string const& stringValue ) const {
+ typename RemoveConstRef<T>::type value;
+ convertInto( stringValue, value );
+ function( obj, value );
+ }
+ virtual void setFlag( C& obj ) const {
+ typename RemoveConstRef<T>::type value;
+ convertInto( true, value );
+ function( obj, value );
+ }
+ virtual bool takesArg() const { return !IsBool<T>::value; }
+ virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
+ void (*function)( C&, T );
+ };
+
+ } // namespace Detail
+
+ struct Parser {
+ Parser() : separators( " \t=:" ) {}
+
+ struct Token {
+ enum Type { Positional, ShortOpt, LongOpt };
+ Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
+ Type type;
+ std::string data;
+ };
+
+ void parseIntoTokens( int argc, char const * const * argv, std::vector<Parser::Token>& tokens ) const {
+ const std::string doubleDash = "--";
+ for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
+ parseIntoTokens( argv[i] , tokens);
+ }
+ void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const {
+ while( !arg.empty() ) {
+ Parser::Token token( Parser::Token::Positional, arg );
+ arg = "";
+ if( token.data[0] == '-' ) {
+ if( token.data.size() > 1 && token.data[1] == '-' ) {
+ token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
+ }
+ else {
+ token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
+ if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
+ arg = "-" + token.data.substr( 1 );
+ token.data = token.data.substr( 0, 1 );
+ }
+ }
+ }
+ if( token.type != Parser::Token::Positional ) {
+ std::size_t pos = token.data.find_first_of( separators );
+ if( pos != std::string::npos ) {
+ arg = token.data.substr( pos+1 );
+ token.data = token.data.substr( 0, pos );
+ }
+ }
+ tokens.push_back( token );
+ }
+ }
+ std::string separators;
+ };
+
+ template<typename ConfigT>
+ struct CommonArgProperties {
+ CommonArgProperties() {}
+ CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
+
+ Detail::BoundArgFunction<ConfigT> boundField;
+ std::string description;
+ std::string detail;
+ std::string placeholder; // Only value if boundField takes an arg
+
+ bool takesArg() const {
+ return !placeholder.empty();
+ }
+ void validate() const {
+ if( !boundField.isSet() )
+ throw std::logic_error( "option not bound" );
+ }
+ };
+ struct OptionArgProperties {
+ std::vector<std::string> shortNames;
+ std::string longName;
+
+ bool hasShortName( std::string const& shortName ) const {
+ return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
+ }
+ bool hasLongName( std::string const& _longName ) const {
+ return _longName == longName;
+ }
+ };
+ struct PositionalArgProperties {
+ PositionalArgProperties() : position( -1 ) {}
+ int position; // -1 means non-positional (floating)
+
+ bool isFixedPositional() const {
+ return position != -1;
+ }
+ };
+
+ template<typename ConfigT>
+ class CommandLine {
+
+ struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
+ Arg() {}
+ Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
+
+ using CommonArgProperties<ConfigT>::placeholder; // !TBD
+
+ std::string dbgName() const {
+ if( !longName.empty() )
+ return "--" + longName;
+ if( !shortNames.empty() )
+ return "-" + shortNames[0];
+ return "positional args";
+ }
+ std::string commands() const {
+ std::ostringstream oss;
+ bool first = true;
+ std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
+ for(; it != itEnd; ++it ) {
+ if( first )
+ first = false;
+ else
+ oss << ", ";
+ oss << "-" << *it;
+ }
+ if( !longName.empty() ) {
+ if( !first )
+ oss << ", ";
+ oss << "--" << longName;
+ }
+ if( !placeholder.empty() )
+ oss << " <" << placeholder << ">";
+ return oss.str();
+ }
+ };
+
+ // NOTE: std::auto_ptr is deprecated in c++11/c++0x
+#if defined(__cplusplus) && __cplusplus > 199711L
+ typedef std::unique_ptr<Arg> ArgAutoPtr;
+#else
+ typedef std::auto_ptr<Arg> ArgAutoPtr;
+#endif
+
+ friend void addOptName( Arg& arg, std::string const& optName )
+ {
+ if( optName.empty() )
+ return;
+ if( Detail::startsWith( optName, "--" ) ) {
+ if( !arg.longName.empty() )
+ throw std::logic_error( "Only one long opt may be specified. '"
+ + arg.longName
+ + "' already specified, now attempting to add '"
+ + optName + "'" );
+ arg.longName = optName.substr( 2 );
+ }
+ else if( Detail::startsWith( optName, "-" ) )
+ arg.shortNames.push_back( optName.substr( 1 ) );
+ else
+ throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
+ }
+ friend void setPositionalArg( Arg& arg, int position )
+ {
+ arg.position = position;
+ }
+
+ class ArgBuilder {
+ public:
+ ArgBuilder( Arg* arg ) : m_arg( arg ) {}
+
+ // Bind a non-boolean data member (requires placeholder string)
+ template<typename C, typename M>
+ void bind( M C::* field, std::string const& placeholder ) {
+ m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
+ m_arg->placeholder = placeholder;
+ }
+ // Bind a boolean data member (no placeholder required)
+ template<typename C>
+ void bind( bool C::* field ) {
+ m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
+ }
+
+ // Bind a method taking a single, non-boolean argument (requires a placeholder string)
+ template<typename C, typename M>
+ void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
+ m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
+ m_arg->placeholder = placeholder;
+ }
+
+ // Bind a method taking a single, boolean argument (no placeholder string required)
+ template<typename C>
+ void bind( void (C::* unaryMethod)( bool ) ) {
+ m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
+ }
+
+ // Bind a method that takes no arguments (will be called if opt is present)
+ template<typename C>
+ void bind( void (C::* nullaryMethod)() ) {
+ m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
+ }
+
+ // Bind a free function taking a single argument - the object to operate on (no placeholder string required)
+ template<typename C>
+ void bind( void (* unaryFunction)( C& ) ) {
+ m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
+ }
+
+ // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)
+ template<typename C, typename T>
+ void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
+ m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
+ m_arg->placeholder = placeholder;
+ }
+
+ ArgBuilder& describe( std::string const& description ) {
+ m_arg->description = description;
+ return *this;
+ }
+ ArgBuilder& detail( std::string const& detail ) {
+ m_arg->detail = detail;
+ return *this;
+ }
+
+ protected:
+ Arg* m_arg;
+ };
+
+ class OptBuilder : public ArgBuilder {
+ public:
+ OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
+ OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
+
+ OptBuilder& operator[]( std::string const& optName ) {
+ addOptName( *ArgBuilder::m_arg, optName );
+ return *this;
+ }
+ };
+
+ public:
+
+ CommandLine()
+ : m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
+ m_highestSpecifiedArgPosition( 0 ),
+ m_throwOnUnrecognisedTokens( false )
+ {}
+ CommandLine( CommandLine const& other )
+ : m_boundProcessName( other.m_boundProcessName ),
+ m_options ( other.m_options ),
+ m_positionalArgs( other.m_positionalArgs ),
+ m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
+ m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
+ {
+ if( other.m_floatingArg.get() )
+ m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
+ }
+
+ CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
+ m_throwOnUnrecognisedTokens = shouldThrow;
+ return *this;
+ }
+
+ OptBuilder operator[]( std::string const& optName ) {
+ m_options.push_back( Arg() );
+ addOptName( m_options.back(), optName );
+ OptBuilder builder( &m_options.back() );
+ return builder;
+ }
+
+ ArgBuilder operator[]( int position ) {
+ m_positionalArgs.insert( std::make_pair( position, Arg() ) );
+ if( position > m_highestSpecifiedArgPosition )
+ m_highestSpecifiedArgPosition = position;
+ setPositionalArg( m_positionalArgs[position], position );
+ ArgBuilder builder( &m_positionalArgs[position] );
+ return builder;
+ }
+
+ // Invoke this with the _ instance
+ ArgBuilder operator[]( UnpositionalTag ) {
+ if( m_floatingArg.get() )
+ throw std::logic_error( "Only one unpositional argument can be added" );
+ m_floatingArg.reset( new Arg() );
+ ArgBuilder builder( m_floatingArg.get() );
+ return builder;
+ }
+
+ template<typename C, typename M>
+ void bindProcessName( M C::* field ) {
+ m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
+ }
+ template<typename C, typename M>
+ void bindProcessName( void (C::*_unaryMethod)( M ) ) {
+ m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
+ }
+
+ void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
+ typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
+ std::size_t maxWidth = 0;
+ for( it = itBegin; it != itEnd; ++it )
+ maxWidth = (std::max)( maxWidth, it->commands().size() );
+
+ for( it = itBegin; it != itEnd; ++it ) {
+ Detail::Text usage( it->commands(), Detail::TextAttributes()
+ .setWidth( maxWidth+indent )
+ .setIndent( indent ) );
+ Detail::Text desc( it->description, Detail::TextAttributes()
+ .setWidth( width - maxWidth - 3 ) );
+
+ for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
+ std::string usageCol = i < usage.size() ? usage[i] : "";
+ os << usageCol;
+
+ if( i < desc.size() && !desc[i].empty() )
+ os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
+ << desc[i];
+ os << "\n";
+ }
+ }
+ }
+ std::string optUsage() const {
+ std::ostringstream oss;
+ optUsage( oss );
+ return oss.str();
+ }
+
+ void argSynopsis( std::ostream& os ) const {
+ for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
+ if( i > 1 )
+ os << " ";
+ typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
+ if( it != m_positionalArgs.end() )
+ os << "<" << it->second.placeholder << ">";
+ else if( m_floatingArg.get() )
+ os << "<" << m_floatingArg->placeholder << ">";
+ else
+ throw std::logic_error( "non consecutive positional arguments with no floating args" );
+ }
+ // !TBD No indication of mandatory args
+ if( m_floatingArg.get() ) {
+ if( m_highestSpecifiedArgPosition > 1 )
+ os << " ";
+ os << "[<" << m_floatingArg->placeholder << "> ...]";
+ }
+ }
+ std::string argSynopsis() const {
+ std::ostringstream oss;
+ argSynopsis( oss );
+ return oss.str();
+ }
+
+ void usage( std::ostream& os, std::string const& procName ) const {
+ validate();
+ os << "usage:\n " << procName << " ";
+ argSynopsis( os );
+ if( !m_options.empty() ) {
+ os << " [options]\n\nwhere options are: \n";
+ optUsage( os, 2 );
+ }
+ os << "\n";
+ }
+ std::string usage( std::string const& procName ) const {
+ std::ostringstream oss;
+ usage( oss, procName );
+ return oss.str();
+ }
+
+ ConfigT parse( int argc, char const * const * argv ) const {
+ ConfigT config;
+ parseInto( argc, argv, config );
+ return config;
+ }
+
+ std::vector<Parser::Token> parseInto( int argc, char const * const * argv, ConfigT& config ) const {
+ std::string processName = argv[0];
+ std::size_t lastSlash = processName.find_last_of( "/\\" );
+ if( lastSlash != std::string::npos )
+ processName = processName.substr( lastSlash+1 );
+ m_boundProcessName.set( config, processName );
+ std::vector<Parser::Token> tokens;
+ Parser parser;
+ parser.parseIntoTokens( argc, argv, tokens );
+ return populate( tokens, config );
+ }
+
+ std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ validate();
+ std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
+ unusedTokens = populateFixedArgs( unusedTokens, config );
+ unusedTokens = populateFloatingArgs( unusedTokens, config );
+ return unusedTokens;
+ }
+
+ std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ std::vector<Parser::Token> unusedTokens;
+ std::vector<std::string> errors;
+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
+ Parser::Token const& token = tokens[i];
+ typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
+ for(; it != itEnd; ++it ) {
+ Arg const& arg = *it;
+
+ try {
+ if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
+ ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
+ if( arg.takesArg() ) {
+ if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
+ errors.push_back( "Expected argument to option: " + token.data );
+ else
+ arg.boundField.set( config, tokens[++i].data );
+ }
+ else {
+ arg.boundField.setFlag( config );
+ }
+ break;
+ }
+ }
+ catch( std::exception& ex ) {
+ errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
+ }
+ }
+ if( it == itEnd ) {
+ if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
+ unusedTokens.push_back( token );
+ else if( errors.empty() && m_throwOnUnrecognisedTokens )
+ errors.push_back( "unrecognised option: " + token.data );
+ }
+ }
+ if( !errors.empty() ) {
+ std::ostringstream oss;
+ for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
+ it != itEnd;
+ ++it ) {
+ if( it != errors.begin() )
+ oss << "\n";
+ oss << *it;
+ }
+ throw std::runtime_error( oss.str() );
+ }
+ return unusedTokens;
+ }
+ std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ std::vector<Parser::Token> unusedTokens;
+ int position = 1;
+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
+ Parser::Token const& token = tokens[i];
+ typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
+ if( it != m_positionalArgs.end() )
+ it->second.boundField.set( config, token.data );
+ else
+ unusedTokens.push_back( token );
+ if( token.type == Parser::Token::Positional )
+ position++;
+ }
+ return unusedTokens;
+ }
+ std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ if( !m_floatingArg.get() )
+ return tokens;
+ std::vector<Parser::Token> unusedTokens;
+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
+ Parser::Token const& token = tokens[i];
+ if( token.type == Parser::Token::Positional )
+ m_floatingArg->boundField.set( config, token.data );
+ else
+ unusedTokens.push_back( token );
+ }
+ return unusedTokens;
+ }
+
+ void validate() const
+ {
+ if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
+ throw std::logic_error( "No options or arguments specified" );
+
+ for( typename std::vector<Arg>::const_iterator it = m_options.begin(),
+ itEnd = m_options.end();
+ it != itEnd; ++it )
+ it->validate();
+ }
+
+ private:
+ Detail::BoundArgFunction<ConfigT> m_boundProcessName;
+ std::vector<Arg> m_options;
+ std::map<int, Arg> m_positionalArgs;
+ ArgAutoPtr m_floatingArg;
+ int m_highestSpecifiedArgPosition;
+ bool m_throwOnUnrecognisedTokens;
+ };
+
+} // end namespace Clara
+
+STITCH_CLARA_CLOSE_NAMESPACE
+#undef STITCH_CLARA_OPEN_NAMESPACE
+#undef STITCH_CLARA_CLOSE_NAMESPACE
+
+#endif // TWOBLUECUBES_CLARA_H_INCLUDED
+#undef STITCH_CLARA_OPEN_NAMESPACE
+
+// Restore Clara's value for console width, if present
+#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#endif
+
+#include <fstream>
+
+namespace Catch {
+
+ inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
+ inline void abortAfterX( ConfigData& config, int x ) {
+ if( x < 1 )
+ throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
+ config.abortAfter = x;
+ }
+ inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
+
+ inline void addWarning( ConfigData& config, std::string const& _warning ) {
+ if( _warning == "NoAssertions" )
+ config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
+ else
+ throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
+ }
+ inline void setOrder( ConfigData& config, std::string const& order ) {
+ if( startsWith( "declared", order ) )
+ config.runOrder = RunTests::InDeclarationOrder;
+ else if( startsWith( "lexical", order ) )
+ config.runOrder = RunTests::InLexicographicalOrder;
+ else if( startsWith( "random", order ) )
+ config.runOrder = RunTests::InRandomOrder;
+ else
+ throw std::runtime_error( "Unrecognised ordering: '" + order + "'" );
+ }
+ inline void setRngSeed( ConfigData& config, std::string const& seed ) {
+ if( seed == "time" ) {
+ config.rngSeed = static_cast<unsigned int>( std::time(0) );
+ }
+ else {
+ std::stringstream ss;
+ ss << seed;
+ ss >> config.rngSeed;
+ if( ss.fail() )
+ throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" );
+ }
+ }
+ inline void setVerbosity( ConfigData& config, int level ) {
+ // !TBD: accept strings?
+ config.verbosity = static_cast<Verbosity::Level>( level );
+ }
+ inline void setShowDurations( ConfigData& config, bool _showDurations ) {
+ config.showDurations = _showDurations
+ ? ShowDurations::Always
+ : ShowDurations::Never;
+ }
+ inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
+ std::ifstream f( _filename.c_str() );
+ if( !f.is_open() )
+ throw std::domain_error( "Unable to load input file: " + _filename );
+
+ std::string line;
+ while( std::getline( f, line ) ) {
+ line = trim(line);
+ if( !line.empty() && !startsWith( line, "#" ) )
+ addTestOrTags( config, "\"" + line + "\"," );
+ }
+ }
+
+ inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
+
+ using namespace Clara;
+ CommandLine<ConfigData> cli;
+
+ cli.bindProcessName( &ConfigData::processName );
+
+ cli["-?"]["-h"]["--help"]
+ .describe( "display usage information" )
+ .bind( &ConfigData::showHelp );
+
+ cli["-l"]["--list-tests"]
+ .describe( "list all/matching test cases" )
+ .bind( &ConfigData::listTests );
+
+ cli["-t"]["--list-tags"]
+ .describe( "list all/matching tags" )
+ .bind( &ConfigData::listTags );
+
+ cli["-s"]["--success"]
+ .describe( "include successful tests in output" )
+ .bind( &ConfigData::showSuccessfulTests );
+
+ cli["-b"]["--break"]
+ .describe( "break into debugger on failure" )
+ .bind( &ConfigData::shouldDebugBreak );
+
+ cli["-e"]["--nothrow"]
+ .describe( "skip exception tests" )
+ .bind( &ConfigData::noThrow );
+
+ cli["-i"]["--invisibles"]
+ .describe( "show invisibles (tabs, newlines)" )
+ .bind( &ConfigData::showInvisibles );
+
+ cli["-o"]["--out"]
+ .describe( "output filename" )
+ .bind( &ConfigData::outputFilename, "filename" );
+
+ cli["-r"]["--reporter"]
+// .placeholder( "name[:filename]" )
+ .describe( "reporter to use (defaults to console)" )
+ .bind( &ConfigData::reporterName, "name" );
+
+ cli["-n"]["--name"]
+ .describe( "suite name" )
+ .bind( &ConfigData::name, "name" );
+
+ cli["-a"]["--abort"]
+ .describe( "abort at first failure" )
+ .bind( &abortAfterFirst );
+
+ cli["-x"]["--abortx"]
+ .describe( "abort after x failures" )
+ .bind( &abortAfterX, "no. failures" );
+
+ cli["-w"]["--warn"]
+ .describe( "enable warnings" )
+ .bind( &addWarning, "warning name" );
+
+// - needs updating if reinstated
+// cli.into( &setVerbosity )
+// .describe( "level of verbosity (0=no output)" )
+// .shortOpt( "v")
+// .longOpt( "verbosity" )
+// .placeholder( "level" );
+
+ cli[_]
+ .describe( "which test or tests to use" )
+ .bind( &addTestOrTags, "test name, pattern or tags" );
+
+ cli["-d"]["--durations"]
+ .describe( "show test durations" )
+ .bind( &setShowDurations, "yes/no" );
+
+ cli["-f"]["--input-file"]
+ .describe( "load test names to run from a file" )
+ .bind( &loadTestNamesFromFile, "filename" );
+
+ // Less common commands which don't have a short form
+ cli["--list-test-names-only"]
+ .describe( "list all/matching test cases names only" )
+ .bind( &ConfigData::listTestNamesOnly );
+
+ cli["--list-reporters"]
+ .describe( "list all reporters" )
+ .bind( &ConfigData::listReporters );
+
+ cli["--order"]
+ .describe( "test case order (defaults to decl)" )
+ .bind( &setOrder, "decl|lex|rand" );
+
+ cli["--rng-seed"]
+ .describe( "set a specific seed for random numbers" )
+ .bind( &setRngSeed, "'time'|number" );
+
+ cli["--force-colour"]
+ .describe( "force colourised output" )
+ .bind( &ConfigData::forceColour );
+
+ return cli;
+ }
+
+} // end namespace Catch
+
+// #included from: internal/catch_list.hpp
+#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
+
+// #included from: catch_text.h
+#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
+
+#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
+
+#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
+// #included from: ../external/tbc_text_format.h
+// Only use header guard if we are not using an outer namespace
+#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
+# ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+# define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+# endif
+# else
+# define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
+# endif
+#endif
+#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+#include <string>
+#include <vector>
+#include <sstream>
+
+// Use optional outer namespace
+#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
+#endif
+
+namespace Tbc {
+
+#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
+ const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
+#else
+ const unsigned int consoleWidth = 80;
+#endif
+
+ struct TextAttributes {
+ TextAttributes()
+ : initialIndent( std::string::npos ),
+ indent( 0 ),
+ width( consoleWidth-1 ),
+ tabChar( '\t' )
+ {}
+
+ TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
+ TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
+ TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
+ TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
+
+ std::size_t initialIndent; // indent of first line, or npos
+ std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
+ std::size_t width; // maximum width of text, including indent. Longer text will wrap
+ char tabChar; // If this char is seen the indent is changed to current pos
+ };
+
+ class Text {
+ public:
+ Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
+ : attr( _attr )
+ {
+ std::string wrappableChars = " [({.,/|\\-";
+ std::size_t indent = _attr.initialIndent != std::string::npos
+ ? _attr.initialIndent
+ : _attr.indent;
+ std::string remainder = _str;
+
+ while( !remainder.empty() ) {
+ if( lines.size() >= 1000 ) {
+ lines.push_back( "... message truncated due to excessive size" );
+ return;
+ }
+ std::size_t tabPos = std::string::npos;
+ std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
+ std::size_t pos = remainder.find_first_of( '\n' );
+ if( pos <= width ) {
+ width = pos;
+ }
+ pos = remainder.find_last_of( _attr.tabChar, width );
+ if( pos != std::string::npos ) {
+ tabPos = pos;
+ if( remainder[width] == '\n' )
+ width--;
+ remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
+ }
+
+ if( width == remainder.size() ) {
+ spliceLine( indent, remainder, width );
+ }
+ else if( remainder[width] == '\n' ) {
+ spliceLine( indent, remainder, width );
+ if( width <= 1 || remainder.size() != 1 )
+ remainder = remainder.substr( 1 );
+ indent = _attr.indent;
+ }
+ else {
+ pos = remainder.find_last_of( wrappableChars, width );
+ if( pos != std::string::npos && pos > 0 ) {
+ spliceLine( indent, remainder, pos );
+ if( remainder[0] == ' ' )
+ remainder = remainder.substr( 1 );
+ }
+ else {
+ spliceLine( indent, remainder, width-1 );
+ lines.back() += "-";
+ }
+ if( lines.size() == 1 )
+ indent = _attr.indent;
+ if( tabPos != std::string::npos )
+ indent += tabPos;
+ }
+ }
+ }
+
+ void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
+ lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
+ _remainder = _remainder.substr( _pos );
+ }
+
+ typedef std::vector<std::string>::const_iterator const_iterator;
+
+ const_iterator begin() const { return lines.begin(); }
+ const_iterator end() const { return lines.end(); }
+ std::string const& last() const { return lines.back(); }
+ std::size_t size() const { return lines.size(); }
+ std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
+ std::string toString() const {
+ std::ostringstream oss;
+ oss << *this;
+ return oss.str();
+ }
+
+ inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
+ for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
+ it != itEnd; ++it ) {
+ if( it != _text.begin() )
+ _stream << "\n";
+ _stream << *it;
+ }
+ return _stream;
+ }
+
+ private:
+ std::string str;
+ TextAttributes attr;
+ std::vector<std::string> lines;
+ };
+
+} // end namespace Tbc
+
+#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+} // end outer namespace
+#endif
+
+#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+
+namespace Catch {
+ using Tbc::Text;
+ using Tbc::TextAttributes;
+}
+
+// #included from: catch_console_colour.hpp
+#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
+
+namespace Catch {
+
+ struct Colour {
+ enum Code {
+ None = 0,
+
+ White,
+ Red,
+ Green,
+ Blue,
+ Cyan,
+ Yellow,
+ Grey,
+
+ Bright = 0x10,
+
+ BrightRed = Bright | Red,
+ BrightGreen = Bright | Green,
+ LightGrey = Bright | Grey,
+ BrightWhite = Bright | White,
+
+ // By intention
+ FileName = Grey,
+ Warning = Yellow,
+ ResultError = BrightRed,
+ ResultSuccess = BrightGreen,
+ ResultExpectedFailure = Warning,
+
+ Error = BrightRed,
+ Success = Green,
+
+ OriginalExpression = Cyan,
+ ReconstructedExpression = Blue,
+
+ SecondaryText = Grey,
+ Headers = White
+ };
+
+ // Use constructed object for RAII guard
+ Colour( Code _colourCode );
+ Colour( Colour const& other );
+ ~Colour();
+
+ // Use static method for one-shot changes
+ static void use( Code _colourCode );
+
+ private:
+ bool m_moved;
+ };
+
+ inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
+
+} // end namespace Catch
+
+// #included from: catch_interfaces_reporter.h
+#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
+
+#include <string>
+#include <ostream>
+#include <map>
+#include <assert.h>
+
+namespace Catch
+{
+ struct ReporterConfig {
+ explicit ReporterConfig( Ptr<IConfig> const& _fullConfig )
+ : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
+
+ ReporterConfig( Ptr<IConfig> const& _fullConfig, std::ostream& _stream )
+ : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
+
+ std::ostream& stream() const { return *m_stream; }
+ Ptr<IConfig> fullConfig() const { return m_fullConfig; }
+
+ private:
+ std::ostream* m_stream;
+ Ptr<IConfig> m_fullConfig;
+ };
+
+ struct ReporterPreferences {
+ ReporterPreferences()
+ : shouldRedirectStdOut( false )
+ {}
+
+ bool shouldRedirectStdOut;
+ };
+
+ template<typename T>
+ struct LazyStat : Option<T> {
+ LazyStat() : used( false ) {}
+ LazyStat& operator=( T const& _value ) {
+ Option<T>::operator=( _value );
+ used = false;
+ return *this;
+ }
+ void reset() {
+ Option<T>::reset();
+ used = false;
+ }
+ bool used;
+ };
+
+ struct TestRunInfo {
+ TestRunInfo( std::string const& _name ) : name( _name ) {}
+ std::string name;
+ };
+ struct GroupInfo {
+ GroupInfo( std::string const& _name,
+ std::size_t _groupIndex,
+ std::size_t _groupsCount )
+ : name( _name ),
+ groupIndex( _groupIndex ),
+ groupsCounts( _groupsCount )
+ {}
+
+ std::string name;
+ std::size_t groupIndex;
+ std::size_t groupsCounts;
+ };
+
+ struct AssertionStats {
+ AssertionStats( AssertionResult const& _assertionResult,
+ std::vector<MessageInfo> const& _infoMessages,
+ Totals const& _totals )
+ : assertionResult( _assertionResult ),
+ infoMessages( _infoMessages ),
+ totals( _totals )
+ {
+ if( assertionResult.hasMessage() ) {
+ // Copy message into messages list.
+ // !TBD This should have been done earlier, somewhere
+ MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
+ builder << assertionResult.getMessage();
+ builder.m_info.message = builder.m_stream.str();
+
+ infoMessages.push_back( builder.m_info );
+ }
+ }
+ virtual ~AssertionStats();
+
+# ifdef CATCH_CPP11_OR_GREATER
+ AssertionStats( AssertionStats const& ) = default;
+ AssertionStats( AssertionStats && ) = default;
+ AssertionStats& operator = ( AssertionStats const& ) = default;
+ AssertionStats& operator = ( AssertionStats && ) = default;
+# endif
+
+ AssertionResult assertionResult;
+ std::vector<MessageInfo> infoMessages;
+ Totals totals;
+ };
+
+ struct SectionStats {
+ SectionStats( SectionInfo const& _sectionInfo,
+ Counts const& _assertions,
+ double _durationInSeconds,
+ bool _missingAssertions )
+ : sectionInfo( _sectionInfo ),
+ assertions( _assertions ),
+ durationInSeconds( _durationInSeconds ),
+ missingAssertions( _missingAssertions )
+ {}
+ virtual ~SectionStats();
+# ifdef CATCH_CPP11_OR_GREATER
+ SectionStats( SectionStats const& ) = default;
+ SectionStats( SectionStats && ) = default;
+ SectionStats& operator = ( SectionStats const& ) = default;
+ SectionStats& operator = ( SectionStats && ) = default;
+# endif
+
+ SectionInfo sectionInfo;
+ Counts assertions;
+ double durationInSeconds;
+ bool missingAssertions;
+ };
+
+ struct TestCaseStats {
+ TestCaseStats( TestCaseInfo const& _testInfo,
+ Totals const& _totals,
+ std::string const& _stdOut,
+ std::string const& _stdErr,
+ bool _aborting )
+ : testInfo( _testInfo ),
+ totals( _totals ),
+ stdOut( _stdOut ),
+ stdErr( _stdErr ),
+ aborting( _aborting )
+ {}
+ virtual ~TestCaseStats();
+
+# ifdef CATCH_CPP11_OR_GREATER
+ TestCaseStats( TestCaseStats const& ) = default;
+ TestCaseStats( TestCaseStats && ) = default;
+ TestCaseStats& operator = ( TestCaseStats const& ) = default;
+ TestCaseStats& operator = ( TestCaseStats && ) = default;
+# endif
+
+ TestCaseInfo testInfo;
+ Totals totals;
+ std::string stdOut;
+ std::string stdErr;
+ bool aborting;
+ };
+
+ struct TestGroupStats {
+ TestGroupStats( GroupInfo const& _groupInfo,
+ Totals const& _totals,
+ bool _aborting )
+ : groupInfo( _groupInfo ),
+ totals( _totals ),
+ aborting( _aborting )
+ {}
+ TestGroupStats( GroupInfo const& _groupInfo )
+ : groupInfo( _groupInfo ),
+ aborting( false )
+ {}
+ virtual ~TestGroupStats();
+
+# ifdef CATCH_CPP11_OR_GREATER
+ TestGroupStats( TestGroupStats const& ) = default;
+ TestGroupStats( TestGroupStats && ) = default;
+ TestGroupStats& operator = ( TestGroupStats const& ) = default;
+ TestGroupStats& operator = ( TestGroupStats && ) = default;
+# endif
+
+ GroupInfo groupInfo;
+ Totals totals;
+ bool aborting;
+ };
+
+ struct TestRunStats {
+ TestRunStats( TestRunInfo const& _runInfo,
+ Totals const& _totals,
+ bool _aborting )
+ : runInfo( _runInfo ),
+ totals( _totals ),
+ aborting( _aborting )
+ {}
+ virtual ~TestRunStats();
+
+# ifndef CATCH_CPP11_OR_GREATER
+ TestRunStats( TestRunStats const& _other )
+ : runInfo( _other.runInfo ),
+ totals( _other.totals ),
+ aborting( _other.aborting )
+ {}
+# else
+ TestRunStats( TestRunStats const& ) = default;
+ TestRunStats( TestRunStats && ) = default;
+ TestRunStats& operator = ( TestRunStats const& ) = default;
+ TestRunStats& operator = ( TestRunStats && ) = default;
+# endif
+
+ TestRunInfo runInfo;
+ Totals totals;
+ bool aborting;
+ };
+
+ struct IStreamingReporter : IShared {
+ virtual ~IStreamingReporter();
+
+ // Implementing class must also provide the following static method:
+ // static std::string getDescription();
+
+ virtual ReporterPreferences getPreferences() const = 0;
+
+ virtual void noMatchingTestCases( std::string const& spec ) = 0;
+
+ virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
+
+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
+
+ virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
+
+ // The return value indicates if the messages buffer should be cleared:
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
+ virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
+ virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
+
+ virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
+ };
+
+ struct IReporterFactory {
+ virtual ~IReporterFactory();
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
+ virtual std::string getDescription() const = 0;
+ };
+
+ struct IReporterRegistry {
+ typedef std::map<std::string, IReporterFactory*> FactoryMap;
+
+ virtual ~IReporterRegistry();
+ virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const = 0;
+ virtual FactoryMap const& getFactories() const = 0;
+ };
+
+}
+
+#include <limits>
+#include <algorithm>
+
+namespace Catch {
+
+ inline std::size_t listTests( Config const& config ) {
+
+ TestSpec testSpec = config.testSpec();
+ if( config.testSpec().hasFilters() )
+ Catch::cout() << "Matching test cases:\n";
+ else {
+ Catch::cout() << "All available test cases:\n";
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+ }
+
+ std::size_t matchedTests = 0;
+ TextAttributes nameAttr, tagsAttr;
+ nameAttr.setInitialIndent( 2 ).setIndent( 4 );
+ tagsAttr.setIndent( 6 );
+
+ std::vector<TestCase> matchedTestCases;
+ getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+ it != itEnd;
+ ++it ) {
+ matchedTests++;
+ TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
+ Colour::Code colour = testCaseInfo.isHidden()
+ ? Colour::SecondaryText
+ : Colour::None;
+ Colour colourGuard( colour );
+
+ Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
+ if( !testCaseInfo.tags.empty() )
+ Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
+ }
+
+ if( !config.testSpec().hasFilters() )
+ Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
+ else
+ Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
+ return matchedTests;
+ }
+
+ inline std::size_t listTestsNamesOnly( Config const& config ) {
+ TestSpec testSpec = config.testSpec();
+ if( !config.testSpec().hasFilters() )
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+ std::size_t matchedTests = 0;
+ std::vector<TestCase> matchedTestCases;
+ getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+ it != itEnd;
+ ++it ) {
+ matchedTests++;
+ TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
+ Catch::cout() << testCaseInfo.name << std::endl;
+ }
+ return matchedTests;
+ }
+
+ struct TagInfo {
+ TagInfo() : count ( 0 ) {}
+ void add( std::string const& spelling ) {
+ ++count;
+ spellings.insert( spelling );
+ }
+ std::string all() const {
+ std::string out;
+ for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
+ it != itEnd;
+ ++it )
+ out += "[" + *it + "]";
+ return out;
+ }
+ std::set<std::string> spellings;
+ std::size_t count;
+ };
+
+ inline std::size_t listTags( Config const& config ) {
+ TestSpec testSpec = config.testSpec();
+ if( config.testSpec().hasFilters() )
+ Catch::cout() << "Tags for matching test cases:\n";
+ else {
+ Catch::cout() << "All available tags:\n";
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+ }
+
+ std::map<std::string, TagInfo> tagCounts;
+
+ std::vector<TestCase> matchedTestCases;
+ getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+ it != itEnd;
+ ++it ) {
+ for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
+ tagItEnd = it->getTestCaseInfo().tags.end();
+ tagIt != tagItEnd;
+ ++tagIt ) {
+ std::string tagName = *tagIt;
+ std::string lcaseTagName = toLower( tagName );
+ std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
+ if( countIt == tagCounts.end() )
+ countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
+ countIt->second.add( tagName );
+ }
+ }
+
+ for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
+ countItEnd = tagCounts.end();
+ countIt != countItEnd;
+ ++countIt ) {
+ std::ostringstream oss;
+ oss << " " << std::setw(2) << countIt->second.count << " ";
+ Text wrapper( countIt->second.all(), TextAttributes()
+ .setInitialIndent( 0 )
+ .setIndent( oss.str().size() )
+ .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
+ Catch::cout() << oss.str() << wrapper << "\n";
+ }
+ Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl;
+ return tagCounts.size();
+ }
+
+ inline std::size_t listReporters( Config const& /*config*/ ) {
+ Catch::cout() << "Available reporters:\n";
+ IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
+ IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
+ std::size_t maxNameLen = 0;
+ for(it = itBegin; it != itEnd; ++it )
+ maxNameLen = (std::max)( maxNameLen, it->first.size() );
+
+ for(it = itBegin; it != itEnd; ++it ) {
+ Text wrapper( it->second->getDescription(), TextAttributes()
+ .setInitialIndent( 0 )
+ .setIndent( 7+maxNameLen )
+ .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
+ Catch::cout() << " "
+ << it->first
+ << ":"
+ << std::string( maxNameLen - it->first.size() + 2, ' ' )
+ << wrapper << "\n";
+ }
+ Catch::cout() << std::endl;
+ return factories.size();
+ }
+
+ inline Option<std::size_t> list( Config const& config ) {
+ Option<std::size_t> listedCount;
+ if( config.listTests() )
+ listedCount = listedCount.valueOr(0) + listTests( config );
+ if( config.listTestNamesOnly() )
+ listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
+ if( config.listTags() )
+ listedCount = listedCount.valueOr(0) + listTags( config );
+ if( config.listReporters() )
+ listedCount = listedCount.valueOr(0) + listReporters( config );
+ return listedCount;
+ }
+
+} // end namespace Catch
+
+// #included from: internal/catch_runner_impl.hpp
+#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
+
+// #included from: catch_test_case_tracker.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
+
+#include <map>
+#include <string>
+#include <assert.h>
+
+namespace Catch {
+namespace SectionTracking {
+
+ class TrackedSection {
+
+ typedef std::map<std::string, TrackedSection> TrackedSections;
+
+ public:
+ enum RunState {
+ NotStarted,
+ Executing,
+ ExecutingChildren,
+ Completed
+ };
+
+ TrackedSection( std::string const& name, TrackedSection* parent )
+ : m_name( name ), m_runState( NotStarted ), m_parent( parent )
+ {}
+
+ RunState runState() const { return m_runState; }
+
+ TrackedSection* findChild( std::string const& childName ) {
+ TrackedSections::iterator it = m_children.find( childName );
+ return it != m_children.end()
+ ? &it->second
+ : NULL;
+ }
+ TrackedSection* acquireChild( std::string const& childName ) {
+ if( TrackedSection* child = findChild( childName ) )
+ return child;
+ m_children.insert( std::make_pair( childName, TrackedSection( childName, this ) ) );
+ return findChild( childName );
+ }
+ void enter() {
+ if( m_runState == NotStarted )
+ m_runState = Executing;
+ }
+ void leave() {
+ for( TrackedSections::const_iterator it = m_children.begin(), itEnd = m_children.end();
+ it != itEnd;
+ ++it )
+ if( it->second.runState() != Completed ) {
+ m_runState = ExecutingChildren;
+ return;
+ }
+ m_runState = Completed;
+ }
+ TrackedSection* getParent() {
+ return m_parent;
+ }
+ bool hasChildren() const {
+ return !m_children.empty();
+ }
+
+ private:
+ std::string m_name;
+ RunState m_runState;
+ TrackedSections m_children;
+ TrackedSection* m_parent;
+
+ };
+
+ class TestCaseTracker {
+ public:
+ TestCaseTracker( std::string const& testCaseName )
+ : m_testCase( testCaseName, NULL ),
+ m_currentSection( &m_testCase ),
+ m_completedASectionThisRun( false )
+ {}
+
+ bool enterSection( std::string const& name ) {
+ TrackedSection* child = m_currentSection->acquireChild( name );
+ if( m_completedASectionThisRun || child->runState() == TrackedSection::Completed )
+ return false;
+
+ m_currentSection = child;
+ m_currentSection->enter();
+ return true;
+ }
+ void leaveSection() {
+ m_currentSection->leave();
+ m_currentSection = m_currentSection->getParent();
+ assert( m_currentSection != NULL );
+ m_completedASectionThisRun = true;
+ }
+
+ bool currentSectionHasChildren() const {
+ return m_currentSection->hasChildren();
+ }
+ bool isCompleted() const {
+ return m_testCase.runState() == TrackedSection::Completed;
+ }
+
+ class Guard {
+ public:
+ Guard( TestCaseTracker& tracker ) : m_tracker( tracker ) {
+ m_tracker.enterTestCase();
+ }
+ ~Guard() {
+ m_tracker.leaveTestCase();
+ }
+ private:
+ Guard( Guard const& );
+ void operator = ( Guard const& );
+ TestCaseTracker& m_tracker;
+ };
+
+ private:
+ void enterTestCase() {
+ m_currentSection = &m_testCase;
+ m_completedASectionThisRun = false;
+ m_testCase.enter();
+ }
+ void leaveTestCase() {
+ m_testCase.leave();
+ }
+
+ TrackedSection m_testCase;
+ TrackedSection* m_currentSection;
+ bool m_completedASectionThisRun;
+ };
+
+} // namespace SectionTracking
+
+using SectionTracking::TestCaseTracker;
+
+} // namespace Catch
+
+// #included from: catch_fatal_condition.hpp
+#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
+
+namespace Catch {
+
+ // Report the error condition then exit the process
+ inline void fatal( std::string const& message, int exitCode ) {
+ IContext& context = Catch::getCurrentContext();
+ IResultCapture* resultCapture = context.getResultCapture();
+ resultCapture->handleFatalErrorCondition( message );
+
+ if( Catch::alwaysTrue() ) // avoids "no return" warnings
+ exit( exitCode );
+ }
+
+} // namespace Catch
+
+#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
+
+namespace Catch {
+
+ struct FatalConditionHandler {
+ void reset() {}
+ };
+
+} // namespace Catch
+
+#else // Not Windows - assumed to be POSIX compatible //////////////////////////
+
+#include <signal.h>
+
+namespace Catch {
+
+ struct SignalDefs { int id; const char* name; };
+ extern SignalDefs signalDefs[];
+ SignalDefs signalDefs[] = {
+ { SIGINT, "SIGINT - Terminal interrupt signal" },
+ { SIGILL, "SIGILL - Illegal instruction signal" },
+ { SIGFPE, "SIGFPE - Floating point error signal" },
+ { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
+ { SIGTERM, "SIGTERM - Termination request signal" },
+ { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
+ };
+
+ struct FatalConditionHandler {
+
+ static void handleSignal( int sig ) {
+ for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+ if( sig == signalDefs[i].id )
+ fatal( signalDefs[i].name, -sig );
+ fatal( "<unknown signal>", -sig );
+ }
+
+ FatalConditionHandler() : m_isSet( true ) {
+ for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+ signal( signalDefs[i].id, handleSignal );
+ }
+ ~FatalConditionHandler() {
+ reset();
+ }
+ void reset() {
+ if( m_isSet ) {
+ for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+ signal( signalDefs[i].id, SIG_DFL );
+ m_isSet = false;
+ }
+ }
+
+ bool m_isSet;
+ };
+
+} // namespace Catch
+
+#endif // not Windows
+
+#include <set>
+#include <string>
+
+namespace Catch {
+
+ class StreamRedirect {
+
+ public:
+ StreamRedirect( std::ostream& stream, std::string& targetString )
+ : m_stream( stream ),
+ m_prevBuf( stream.rdbuf() ),
+ m_targetString( targetString )
+ {
+ stream.rdbuf( m_oss.rdbuf() );
+ }
+
+ ~StreamRedirect() {
+ m_targetString += m_oss.str();
+ m_stream.rdbuf( m_prevBuf );
+ }
+
+ private:
+ std::ostream& m_stream;
+ std::streambuf* m_prevBuf;
+ std::ostringstream m_oss;
+ std::string& m_targetString;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class RunContext : public IResultCapture, public IRunner {
+
+ RunContext( RunContext const& );
+ void operator =( RunContext const& );
+
+ public:
+
+ explicit RunContext( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> const& reporter )
+ : m_runInfo( config->name() ),
+ m_context( getCurrentMutableContext() ),
+ m_activeTestCase( NULL ),
+ m_config( config ),
+ m_reporter( reporter ),
+ m_prevRunner( m_context.getRunner() ),
+ m_prevResultCapture( m_context.getResultCapture() ),
+ m_prevConfig( m_context.getConfig() )
+ {
+ m_context.setRunner( this );
+ m_context.setConfig( m_config );
+ m_context.setResultCapture( this );
+ m_reporter->testRunStarting( m_runInfo );
+ }
+
+ virtual ~RunContext() {
+ m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
+ m_context.setRunner( m_prevRunner );
+ m_context.setConfig( NULL );
+ m_context.setResultCapture( m_prevResultCapture );
+ m_context.setConfig( m_prevConfig );
+ }
+
+ void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
+ m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
+ }
+ void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
+ m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
+ }
+
+ Totals runTest( TestCase const& testCase ) {
+ Totals prevTotals = m_totals;
+
+ std::string redirectedCout;
+ std::string redirectedCerr;
+
+ TestCaseInfo testInfo = testCase.getTestCaseInfo();
+
+ m_reporter->testCaseStarting( testInfo );
+
+ m_activeTestCase = &testCase;
+ m_testCaseTracker = TestCaseTracker( testInfo.name );
+
+ do {
+ do {
+ runCurrentTest( redirectedCout, redirectedCerr );
+ }
+ while( !m_testCaseTracker->isCompleted() && !aborting() );
+ }
+ while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
+
+ Totals deltaTotals = m_totals.delta( prevTotals );
+ m_totals.testCases += deltaTotals.testCases;
+ m_reporter->testCaseEnded( TestCaseStats( testInfo,
+ deltaTotals,
+ redirectedCout,
+ redirectedCerr,
+ aborting() ) );
+
+ m_activeTestCase = NULL;
+ m_testCaseTracker.reset();
+
+ return deltaTotals;
+ }
+
+ Ptr<IConfig const> config() const {
+ return m_config;
+ }
+
+ private: // IResultCapture
+
+ virtual void assertionEnded( AssertionResult const& result ) {
+ if( result.getResultType() == ResultWas::Ok ) {
+ m_totals.assertions.passed++;
+ }
+ else if( !result.isOk() ) {
+ m_totals.assertions.failed++;
+ }
+
+ if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
+ m_messages.clear();
+
+ // Reset working state
+ m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
+ m_lastResult = result;
+ }
+
+ virtual bool sectionStarted (
+ SectionInfo const& sectionInfo,
+ Counts& assertions
+ )
+ {
+ std::ostringstream oss;
+ oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
+
+ if( !m_testCaseTracker->enterSection( oss.str() ) )
+ return false;
+
+ m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
+
+ m_reporter->sectionStarting( sectionInfo );
+
+ assertions = m_totals.assertions;
+
+ return true;
+ }
+ bool testForMissingAssertions( Counts& assertions ) {
+ if( assertions.total() != 0 ||
+ !m_config->warnAboutMissingAssertions() ||
+ m_testCaseTracker->currentSectionHasChildren() )
+ return false;
+ m_totals.assertions.failed++;
+ assertions.failed++;
+ return true;
+ }
+
+ virtual void sectionEnded( SectionInfo const& info, Counts const& prevAssertions, double _durationInSeconds ) {
+ if( std::uncaught_exception() ) {
+ m_unfinishedSections.push_back( UnfinishedSections( info, prevAssertions, _durationInSeconds ) );
+ return;
+ }
+
+ Counts assertions = m_totals.assertions - prevAssertions;
+ bool missingAssertions = testForMissingAssertions( assertions );
+
+ m_testCaseTracker->leaveSection();
+
+ m_reporter->sectionEnded( SectionStats( info, assertions, _durationInSeconds, missingAssertions ) );
+ m_messages.clear();
+ }
+
+ virtual void pushScopedMessage( MessageInfo const& message ) {
+ m_messages.push_back( message );
+ }
+
+ virtual void popScopedMessage( MessageInfo const& message ) {
+ m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
+ }
+
+ virtual std::string getCurrentTestName() const {
+ return m_activeTestCase
+ ? m_activeTestCase->getTestCaseInfo().name
+ : "";
+ }
+
+ virtual const AssertionResult* getLastResult() const {
+ return &m_lastResult;
+ }
+
+ virtual void handleFatalErrorCondition( std::string const& message ) {
+ ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
+ resultBuilder.setResultType( ResultWas::FatalErrorCondition );
+ resultBuilder << message;
+ resultBuilder.captureExpression();
+
+ handleUnfinishedSections();
+
+ // Recreate section for test case (as we will lose the one that was in scope)
+ TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
+ SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
+
+ Counts assertions;
+ assertions.failed = 1;
+ SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
+ m_reporter->sectionEnded( testCaseSectionStats );
+
+ TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
+
+ Totals deltaTotals;
+ deltaTotals.testCases.failed = 1;
+ m_reporter->testCaseEnded( TestCaseStats( testInfo,
+ deltaTotals,
+ "",
+ "",
+ false ) );
+ m_totals.testCases.failed++;
+ testGroupEnded( "", m_totals, 1, 1 );
+ m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
+ }
+
+ public:
+ // !TBD We need to do this another way!
+ bool aborting() const {
+ return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
+ }
+
+ private:
+
+ void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
+ TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
+ SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
+ m_reporter->sectionStarting( testCaseSection );
+ Counts prevAssertions = m_totals.assertions;
+ double duration = 0;
+ try {
+ m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
+ TestCaseTracker::Guard guard( *m_testCaseTracker );
+
+ Timer timer;
+ timer.start();
+ if( m_reporter->getPreferences().shouldRedirectStdOut ) {
+ StreamRedirect coutRedir( Catch::cout(), redirectedCout );
+ StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
+ invokeActiveTestCase();
+ }
+ else {
+ invokeActiveTestCase();
+ }
+ duration = timer.getElapsedSeconds();
+ }
+ catch( TestFailureException& ) {
+ // This just means the test was aborted due to failure
+ }
+ catch(...) {
+ makeUnexpectedResultBuilder().useActiveException();
+ }
+ handleUnfinishedSections();
+ m_messages.clear();
+
+ Counts assertions = m_totals.assertions - prevAssertions;
+ bool missingAssertions = testForMissingAssertions( assertions );
+
+ if( testCaseInfo.okToFail() ) {
+ std::swap( assertions.failedButOk, assertions.failed );
+ m_totals.assertions.failed -= assertions.failedButOk;
+ m_totals.assertions.failedButOk += assertions.failedButOk;
+ }
+
+ SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
+ m_reporter->sectionEnded( testCaseSectionStats );
+ }
+
+ void invokeActiveTestCase() {
+ FatalConditionHandler fatalConditionHandler; // Handle signals
+ m_activeTestCase->invoke();
+ fatalConditionHandler.reset();
+ }
+
+ private:
+
+ ResultBuilder makeUnexpectedResultBuilder() const {
+ return ResultBuilder( m_lastAssertionInfo.macroName.c_str(),
+ m_lastAssertionInfo.lineInfo,
+ m_lastAssertionInfo.capturedExpression.c_str(),
+ m_lastAssertionInfo.resultDisposition );
+ }
+
+ void handleUnfinishedSections() {
+ // If sections ended prematurely due to an exception we stored their
+ // infos here so we can tear them down outside the unwind process.
+ for( std::vector<UnfinishedSections>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
+ itEnd = m_unfinishedSections.rend();
+ it != itEnd;
+ ++it )
+ sectionEnded( it->info, it->prevAssertions, it->durationInSeconds );
+ m_unfinishedSections.clear();
+ }
+
+ struct UnfinishedSections {
+ UnfinishedSections( SectionInfo const& _info, Counts const& _prevAssertions, double _durationInSeconds )
+ : info( _info ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
+ {}
+
+ SectionInfo info;
+ Counts prevAssertions;
+ double durationInSeconds;
+ };
+
+ TestRunInfo m_runInfo;
+ IMutableContext& m_context;
+ TestCase const* m_activeTestCase;
+ Option<TestCaseTracker> m_testCaseTracker;
+ AssertionResult m_lastResult;
+
+ Ptr<IConfig const> m_config;
+ Totals m_totals;
+ Ptr<IStreamingReporter> m_reporter;
+ std::vector<MessageInfo> m_messages;
+ IRunner* m_prevRunner;
+ IResultCapture* m_prevResultCapture;
+ Ptr<IConfig const> m_prevConfig;
+ AssertionInfo m_lastAssertionInfo;
+ std::vector<UnfinishedSections> m_unfinishedSections;
+ };
+
+ IResultCapture& getResultCapture() {
+ if( IResultCapture* capture = getCurrentContext().getResultCapture() )
+ return *capture;
+ else
+ throw std::logic_error( "No result capture instance" );
+ }
+
+} // end namespace Catch
+
+// #included from: internal/catch_version.h
+#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
+
+namespace Catch {
+
+ // Versioning information
+ struct Version {
+ Version( unsigned int _majorVersion,
+ unsigned int _minorVersion,
+ unsigned int _buildNumber,
+ char const* const _branchName )
+ : majorVersion( _majorVersion ),
+ minorVersion( _minorVersion ),
+ buildNumber( _buildNumber ),
+ branchName( _branchName )
+ {}
+
+ unsigned int const majorVersion;
+ unsigned int const minorVersion;
+ unsigned int const buildNumber;
+ char const* const branchName;
+
+ private:
+ void operator=( Version const& );
+ };
+
+ extern Version libraryVersion;
+}
+
+#include <fstream>
+#include <stdlib.h>
+#include <limits>
+
+namespace Catch {
+
+ class Runner {
+
+ public:
+ Runner( Ptr<Config> const& config )
+ : m_config( config )
+ {
+ openStream();
+ makeReporter();
+ }
+
+ Totals runTests() {
+
+ RunContext context( m_config.get(), m_reporter );
+
+ Totals totals;
+
+ context.testGroupStarting( "all tests", 1, 1 ); // deprecated?
+
+ TestSpec testSpec = m_config->testSpec();
+ if( !testSpec.hasFilters() )
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
+
+ std::vector<TestCase> testCases;
+ getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, testCases );
+
+ int testsRunForGroup = 0;
+ for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
+ it != itEnd;
+ ++it ) {
+ testsRunForGroup++;
+ if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) {
+
+ if( context.aborting() )
+ break;
+
+ totals += context.runTest( *it );
+ m_testsAlreadyRun.insert( *it );
+ }
+ }
+ std::vector<TestCase> skippedTestCases;
+ getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, skippedTestCases, true );
+
+ for( std::vector<TestCase>::const_iterator it = skippedTestCases.begin(), itEnd = skippedTestCases.end();
+ it != itEnd;
+ ++it )
+ m_reporter->skipTest( *it );
+
+ context.testGroupEnded( "all tests", totals, 1, 1 );
+ return totals;
+ }
+
+ private:
+ void openStream() {
+ // Open output file, if specified
+ if( !m_config->getFilename().empty() ) {
+ m_ofs.open( m_config->getFilename().c_str() );
+ if( m_ofs.fail() ) {
+ std::ostringstream oss;
+ oss << "Unable to open file: '" << m_config->getFilename() << "'";
+ throw std::domain_error( oss.str() );
+ }
+ m_config->setStreamBuf( m_ofs.rdbuf() );
+ }
+ }
+ void makeReporter() {
+ std::string reporterName = m_config->getReporterName().empty()
+ ? "console"
+ : m_config->getReporterName();
+
+ m_reporter = getRegistryHub().getReporterRegistry().create( reporterName, m_config.get() );
+ if( !m_reporter ) {
+ std::ostringstream oss;
+ oss << "No reporter registered with name: '" << reporterName << "'";
+ throw std::domain_error( oss.str() );
+ }
+ }
+
+ private:
+ Ptr<Config> m_config;
+ std::ofstream m_ofs;
+ Ptr<IStreamingReporter> m_reporter;
+ std::set<TestCase> m_testsAlreadyRun;
+ };
+
+ class Session : NonCopyable {
+ static bool alreadyInstantiated;
+
+ public:
+
+ struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
+
+ Session()
+ : m_cli( makeCommandLineParser() ) {
+ if( alreadyInstantiated ) {
+ std::string msg = "Only one instance of Catch::Session can ever be used";
+ Catch::cerr() << msg << std::endl;
+ throw std::logic_error( msg );
+ }
+ alreadyInstantiated = true;
+ }
+ ~Session() {
+ Catch::cleanUp();
+ }
+
+ void showHelp( std::string const& processName ) {
+ Catch::cout() << "\nCatch v" << libraryVersion.majorVersion << "."
+ << libraryVersion.minorVersion << " build "
+ << libraryVersion.buildNumber;
+ if( libraryVersion.branchName != std::string( "master" ) )
+ Catch::cout() << " (" << libraryVersion.branchName << " branch)";
+ Catch::cout() << "\n";
+
+ m_cli.usage( Catch::cout(), processName );
+ Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
+ }
+
+ int applyCommandLine( int argc, char* const argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
+ try {
+ m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
+ m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
+ if( m_configData.showHelp )
+ showHelp( m_configData.processName );
+ m_config.reset();
+ }
+ catch( std::exception& ex ) {
+ {
+ Colour colourGuard( Colour::Red );
+ Catch::cerr() << "\nError(s) in input:\n"
+ << Text( ex.what(), TextAttributes().setIndent(2) )
+ << "\n\n";
+ }
+ m_cli.usage( Catch::cout(), m_configData.processName );
+ return (std::numeric_limits<int>::max)();
+ }
+ return 0;
+ }
+
+ void useConfigData( ConfigData const& _configData ) {
+ m_configData = _configData;
+ m_config.reset();
+ }
+
+ int run( int argc, char* const argv[] ) {
+
+ int returnCode = applyCommandLine( argc, argv );
+ if( returnCode == 0 )
+ returnCode = run();
+ return returnCode;
+ }
+
+ int run() {
+ if( m_configData.showHelp )
+ return 0;
+
+ try
+ {
+ config(); // Force config to be constructed
+
+ std::srand( m_configData.rngSeed );
+
+ Runner runner( m_config );
+
+ // Handle list request
+ if( Option<std::size_t> listed = list( config() ) )
+ return static_cast<int>( *listed );
+
+ return static_cast<int>( runner.runTests().assertions.failed );
+ }
+ catch( std::exception& ex ) {
+ Catch::cerr() << ex.what() << std::endl;
+ return (std::numeric_limits<int>::max)();
+ }
+ }
+
+ Clara::CommandLine<ConfigData> const& cli() const {
+ return m_cli;
+ }
+ std::vector<Clara::Parser::Token> const& unusedTokens() const {
+ return m_unusedTokens;
+ }
+ ConfigData& configData() {
+ return m_configData;
+ }
+ Config& config() {
+ if( !m_config )
+ m_config = new Config( m_configData );
+ return *m_config;
+ }
+
+ private:
+ Clara::CommandLine<ConfigData> m_cli;
+ std::vector<Clara::Parser::Token> m_unusedTokens;
+ ConfigData m_configData;
+ Ptr<Config> m_config;
+ };
+
+ bool Session::alreadyInstantiated = false;
+
+} // end namespace Catch
+
+// #included from: catch_registry_hub.hpp
+#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
+
+// #included from: catch_test_case_registry_impl.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
+
+#include <vector>
+#include <set>
+#include <sstream>
+#include <iostream>
+#include <algorithm>
+
+namespace Catch {
+
+ class TestRegistry : public ITestCaseRegistry {
+ struct LexSort {
+ bool operator() (TestCase i,TestCase j) const { return (i<j);}
+ };
+ struct RandomNumberGenerator {
+ int operator()( int n ) const { return std::rand() % n; }
+ };
+
+ public:
+ TestRegistry() : m_unnamedCount( 0 ) {}
+ virtual ~TestRegistry();
+
+ virtual void registerTest( TestCase const& testCase ) {
+ std::string name = testCase.getTestCaseInfo().name;
+ if( name == "" ) {
+ std::ostringstream oss;
+ oss << "Anonymous test case " << ++m_unnamedCount;
+ return registerTest( testCase.withName( oss.str() ) );
+ }
+
+ if( m_functions.find( testCase ) == m_functions.end() ) {
+ m_functions.insert( testCase );
+ m_functionsInOrder.push_back( testCase );
+ if( !testCase.isHidden() )
+ m_nonHiddenFunctions.push_back( testCase );
+ }
+ else {
+ TestCase const& prev = *m_functions.find( testCase );
+ {
+ Colour colourGuard( Colour::Red );
+ Catch::cerr() << "error: TEST_CASE( \"" << name << "\" ) already defined.\n"
+ << "\tFirst seen at " << prev.getTestCaseInfo().lineInfo << "\n"
+ << "\tRedefined at " << testCase.getTestCaseInfo().lineInfo << std::endl;
+ }
+ exit(1);
+ }
+ }
+
+ virtual std::vector<TestCase> const& getAllTests() const {
+ return m_functionsInOrder;
+ }
+
+ virtual std::vector<TestCase> const& getAllNonHiddenTests() const {
+ return m_nonHiddenFunctions;
+ }
+
+ virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const {
+
+ for( std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin(),
+ itEnd = m_functionsInOrder.end();
+ it != itEnd;
+ ++it ) {
+ bool includeTest = testSpec.matches( *it ) && ( config.allowThrows() || !it->throws() );
+ if( includeTest != negated )
+ matchingTestCases.push_back( *it );
+ }
+ sortTests( config, matchingTestCases );
+ }
+
+ private:
+
+ static void sortTests( IConfig const& config, std::vector<TestCase>& matchingTestCases ) {
+
+ switch( config.runOrder() ) {
+ case RunTests::InLexicographicalOrder:
+ std::sort( matchingTestCases.begin(), matchingTestCases.end(), LexSort() );
+ break;
+ case RunTests::InRandomOrder:
+ {
+ RandomNumberGenerator rng;
+ std::random_shuffle( matchingTestCases.begin(), matchingTestCases.end(), rng );
+ }
+ break;
+ case RunTests::InDeclarationOrder:
+ // already in declaration order
+ break;
+ }
+ }
+ std::set<TestCase> m_functions;
+ std::vector<TestCase> m_functionsInOrder;
+ std::vector<TestCase> m_nonHiddenFunctions;
+ size_t m_unnamedCount;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class FreeFunctionTestCase : public SharedImpl<ITestCase> {
+ public:
+
+ FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
+
+ virtual void invoke() const {
+ m_fun();
+ }
+
+ private:
+ virtual ~FreeFunctionTestCase();
+
+ TestFunction m_fun;
+ };
+
+ inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
+ std::string className = classOrQualifiedMethodName;
+ if( startsWith( className, "&" ) )
+ {
+ std::size_t lastColons = className.rfind( "::" );
+ std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
+ if( penultimateColons == std::string::npos )
+ penultimateColons = 1;
+ className = className.substr( penultimateColons, lastColons-penultimateColons );
+ }
+ return className;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ AutoReg::AutoReg( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc ) {
+ registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
+ }
+
+ AutoReg::~AutoReg() {}
+
+ void AutoReg::registerTestCase( ITestCase* testCase,
+ char const* classOrQualifiedMethodName,
+ NameAndDesc const& nameAndDesc,
+ SourceLineInfo const& lineInfo ) {
+
+ getMutableRegistryHub().registerTest
+ ( makeTestCase( testCase,
+ extractClassName( classOrQualifiedMethodName ),
+ nameAndDesc.name,
+ nameAndDesc.description,
+ lineInfo ) );
+ }
+
+} // end namespace Catch
+
+// #included from: catch_reporter_registry.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
+
+#include <map>
+
+namespace Catch {
+
+ class ReporterRegistry : public IReporterRegistry {
+
+ public:
+
+ virtual ~ReporterRegistry() {
+ deleteAllValues( m_factories );
+ }
+
+ virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const {
+ FactoryMap::const_iterator it = m_factories.find( name );
+ if( it == m_factories.end() )
+ return NULL;
+ return it->second->create( ReporterConfig( config ) );
+ }
+
+ void registerReporter( std::string const& name, IReporterFactory* factory ) {
+ m_factories.insert( std::make_pair( name, factory ) );
+ }
+
+ FactoryMap const& getFactories() const {
+ return m_factories;
+ }
+
+ private:
+ FactoryMap m_factories;
+ };
+}
+
+// #included from: catch_exception_translator_registry.hpp
+#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
+
+#ifdef __OBJC__
+#import "Foundation/Foundation.h"
+#endif
+
+namespace Catch {
+
+ class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
+ public:
+ ~ExceptionTranslatorRegistry() {
+ deleteAll( m_translators );
+ }
+
+ virtual void registerTranslator( const IExceptionTranslator* translator ) {
+ m_translators.push_back( translator );
+ }
+
+ virtual std::string translateActiveException() const {
+ try {
+#ifdef __OBJC__
+ // In Objective-C try objective-c exceptions first
+ @try {
+ throw;
+ }
+ @catch (NSException *exception) {
+ return Catch::toString( [exception description] );
+ }
+#else
+ throw;
+#endif
+ }
+ catch( TestFailureException& ) {
+ throw;
+ }
+ catch( std::exception& ex ) {
+ return ex.what();
+ }
+ catch( std::string& msg ) {
+ return msg;
+ }
+ catch( const char* msg ) {
+ return msg;
+ }
+ catch(...) {
+ return tryTranslators( m_translators.begin() );
+ }
+ }
+
+ std::string tryTranslators( std::vector<const IExceptionTranslator*>::const_iterator it ) const {
+ if( it == m_translators.end() )
+ return "Unknown exception";
+
+ try {
+ return (*it)->translate();
+ }
+ catch(...) {
+ return tryTranslators( it+1 );
+ }
+ }
+
+ private:
+ std::vector<const IExceptionTranslator*> m_translators;
+ };
+}
+
+namespace Catch {
+
+ namespace {
+
+ class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
+
+ RegistryHub( RegistryHub const& );
+ void operator=( RegistryHub const& );
+
+ public: // IRegistryHub
+ RegistryHub() {
+ }
+ virtual IReporterRegistry const& getReporterRegistry() const {
+ return m_reporterRegistry;
+ }
+ virtual ITestCaseRegistry const& getTestCaseRegistry() const {
+ return m_testCaseRegistry;
+ }
+ virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() {
+ return m_exceptionTranslatorRegistry;
+ }
+
+ public: // IMutableRegistryHub
+ virtual void registerReporter( std::string const& name, IReporterFactory* factory ) {
+ m_reporterRegistry.registerReporter( name, factory );
+ }
+ virtual void registerTest( TestCase const& testInfo ) {
+ m_testCaseRegistry.registerTest( testInfo );
+ }
+ virtual void registerTranslator( const IExceptionTranslator* translator ) {
+ m_exceptionTranslatorRegistry.registerTranslator( translator );
+ }
+
+ private:
+ TestRegistry m_testCaseRegistry;
+ ReporterRegistry m_reporterRegistry;
+ ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
+ };
+
+ // Single, global, instance
+ inline RegistryHub*& getTheRegistryHub() {
+ static RegistryHub* theRegistryHub = NULL;
+ if( !theRegistryHub )
+ theRegistryHub = new RegistryHub();
+ return theRegistryHub;
+ }
+ }
+
+ IRegistryHub& getRegistryHub() {
+ return *getTheRegistryHub();
+ }
+ IMutableRegistryHub& getMutableRegistryHub() {
+ return *getTheRegistryHub();
+ }
+ void cleanUp() {
+ delete getTheRegistryHub();
+ getTheRegistryHub() = NULL;
+ cleanUpContext();
+ }
+ std::string translateActiveException() {
+ return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
+ }
+
+} // end namespace Catch
+
+// #included from: catch_notimplemented_exception.hpp
+#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
+
+#include <ostream>
+
+namespace Catch {
+
+ NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
+ : m_lineInfo( lineInfo ) {
+ std::ostringstream oss;
+ oss << lineInfo << ": function ";
+ oss << "not implemented";
+ m_what = oss.str();
+ }
+
+ const char* NotImplementedException::what() const CATCH_NOEXCEPT {
+ return m_what.c_str();
+ }
+
+} // end namespace Catch
+
+// #included from: catch_context_impl.hpp
+#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
+
+// #included from: catch_stream.hpp
+#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
+
+// #included from: catch_streambuf.h
+#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
+
+#include <streambuf>
+
+namespace Catch {
+
+ class StreamBufBase : public std::streambuf {
+ public:
+ virtual ~StreamBufBase() CATCH_NOEXCEPT;
+ };
+}
+
+#include <stdexcept>
+#include <cstdio>
+#include <iostream>
+
+namespace Catch {
+
+ template<typename WriterF, size_t bufferSize=256>
+ class StreamBufImpl : public StreamBufBase {
+ char data[bufferSize];
+ WriterF m_writer;
+
+ public:
+ StreamBufImpl() {
+ setp( data, data + sizeof(data) );
+ }
+
+ ~StreamBufImpl() CATCH_NOEXCEPT {
+ sync();
+ }
+
+ private:
+ int overflow( int c ) {
+ sync();
+
+ if( c != EOF ) {
+ if( pbase() == epptr() )
+ m_writer( std::string( 1, static_cast<char>( c ) ) );
+ else
+ sputc( static_cast<char>( c ) );
+ }
+ return 0;
+ }
+
+ int sync() {
+ if( pbase() != pptr() ) {
+ m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
+ setp( pbase(), epptr() );
+ }
+ return 0;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ struct OutputDebugWriter {
+
+ void operator()( std::string const&str ) {
+ writeToDebugConsole( str );
+ }
+ };
+
+ Stream::Stream()
+ : streamBuf( NULL ), isOwned( false )
+ {}
+
+ Stream::Stream( std::streambuf* _streamBuf, bool _isOwned )
+ : streamBuf( _streamBuf ), isOwned( _isOwned )
+ {}
+
+ void Stream::release() {
+ if( isOwned ) {
+ delete streamBuf;
+ streamBuf = NULL;
+ isOwned = false;
+ }
+ }
+
+#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement this functions
+ std::ostream& cout() {
+ return std::cout;
+ }
+ std::ostream& cerr() {
+ return std::cerr;
+ }
+#endif
+}
+
+namespace Catch {
+
+ class Context : public IMutableContext {
+
+ Context() : m_config( NULL ), m_runner( NULL ), m_resultCapture( NULL ) {}
+ Context( Context const& );
+ void operator=( Context const& );
+
+ public: // IContext
+ virtual IResultCapture* getResultCapture() {
+ return m_resultCapture;
+ }
+ virtual IRunner* getRunner() {
+ return m_runner;
+ }
+ virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
+ return getGeneratorsForCurrentTest()
+ .getGeneratorInfo( fileInfo, totalSize )
+ .getCurrentIndex();
+ }
+ virtual bool advanceGeneratorsForCurrentTest() {
+ IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
+ return generators && generators->moveNext();
+ }
+
+ virtual Ptr<IConfig const> getConfig() const {
+ return m_config;
+ }
+
+ public: // IMutableContext
+ virtual void setResultCapture( IResultCapture* resultCapture ) {
+ m_resultCapture = resultCapture;
+ }
+ virtual void setRunner( IRunner* runner ) {
+ m_runner = runner;
+ }
+ virtual void setConfig( Ptr<IConfig const> const& config ) {
+ m_config = config;
+ }
+
+ friend IMutableContext& getCurrentMutableContext();
+
+ private:
+ IGeneratorsForTest* findGeneratorsForCurrentTest() {
+ std::string testName = getResultCapture()->getCurrentTestName();
+
+ std::map<std::string, IGeneratorsForTest*>::const_iterator it =
+ m_generatorsByTestName.find( testName );
+ return it != m_generatorsByTestName.end()
+ ? it->second
+ : NULL;
+ }
+
+ IGeneratorsForTest& getGeneratorsForCurrentTest() {
+ IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
+ if( !generators ) {
+ std::string testName = getResultCapture()->getCurrentTestName();
+ generators = createGeneratorsForTest();
+ m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
+ }
+ return *generators;
+ }
+
+ private:
+ Ptr<IConfig const> m_config;
+ IRunner* m_runner;
+ IResultCapture* m_resultCapture;
+ std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
+ };
+
+ namespace {
+ Context* currentContext = NULL;
+ }
+ IMutableContext& getCurrentMutableContext() {
+ if( !currentContext )
+ currentContext = new Context();
+ return *currentContext;
+ }
+ IContext& getCurrentContext() {
+ return getCurrentMutableContext();
+ }
+
+ Stream createStream( std::string const& streamName ) {
+ if( streamName == "stdout" ) return Stream( Catch::cout().rdbuf(), false );
+ if( streamName == "stderr" ) return Stream( Catch::cerr().rdbuf(), false );
+ if( streamName == "debug" ) return Stream( new StreamBufImpl<OutputDebugWriter>, true );
+
+ throw std::domain_error( "Unknown stream: " + streamName );
+ }
+
+ void cleanUpContext() {
+ delete currentContext;
+ currentContext = NULL;
+ }
+}
+
+// #included from: catch_console_colour_impl.hpp
+#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
+
+namespace Catch {
+ namespace {
+
+ struct IColourImpl {
+ virtual ~IColourImpl() {}
+ virtual void use( Colour::Code _colourCode ) = 0;
+ };
+
+ struct NoColourImpl : IColourImpl {
+ void use( Colour::Code ) {}
+
+ static IColourImpl* instance() {
+ static NoColourImpl s_instance;
+ return &s_instance;
+ }
+ };
+
+ } // anon namespace
+} // namespace Catch
+
+#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
+# ifdef CATCH_PLATFORM_WINDOWS
+# define CATCH_CONFIG_COLOUR_WINDOWS
+# else
+# define CATCH_CONFIG_COLOUR_ANSI
+# endif
+#endif
+
+#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+
+#ifdef __AFXDLL
+#include <AfxWin.h>
+#else
+#include <windows.h>
+#endif
+
+namespace Catch {
+namespace {
+
+ class Win32ColourImpl : public IColourImpl {
+ public:
+ Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
+ {
+ CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
+ GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
+ originalAttributes = csbiInfo.wAttributes;
+ }
+
+ virtual void use( Colour::Code _colourCode ) {
+ switch( _colourCode ) {
+ case Colour::None: return setTextAttribute( originalAttributes );
+ case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
+ case Colour::Red: return setTextAttribute( FOREGROUND_RED );
+ case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
+ case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
+ case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
+ case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
+ case Colour::Grey: return setTextAttribute( 0 );
+
+ case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
+ case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
+ case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
+ case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
+
+ case Colour::Bright: throw std::logic_error( "not a colour" );
+ }
+ }
+
+ private:
+ void setTextAttribute( WORD _textAttribute ) {
+ SetConsoleTextAttribute( stdoutHandle, _textAttribute );
+ }
+ HANDLE stdoutHandle;
+ WORD originalAttributes;
+ };
+
+ IColourImpl* platformColourInstance() {
+ static Win32ColourImpl s_instance;
+ return &s_instance;
+ }
+
+} // end anon namespace
+} // end namespace Catch
+
+#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
+
+#include <unistd.h>
+
+namespace Catch {
+namespace {
+
+ // use POSIX/ ANSI console terminal codes
+ // Thanks to Adam Strzelecki for original contribution
+ // (http://github.com/nanoant)
+ // https://github.com/philsquared/Catch/pull/131
+ class PosixColourImpl : public IColourImpl {
+ public:
+ virtual void use( Colour::Code _colourCode ) {
+ switch( _colourCode ) {
+ case Colour::None:
+ case Colour::White: return setColour( "[0m" );
+ case Colour::Red: return setColour( "[0;31m" );
+ case Colour::Green: return setColour( "[0;32m" );
+ case Colour::Blue: return setColour( "[0;34m" );
+ case Colour::Cyan: return setColour( "[0;36m" );
+ case Colour::Yellow: return setColour( "[0;33m" );
+ case Colour::Grey: return setColour( "[1;30m" );
+
+ case Colour::LightGrey: return setColour( "[0;37m" );
+ case Colour::BrightRed: return setColour( "[1;31m" );
+ case Colour::BrightGreen: return setColour( "[1;32m" );
+ case Colour::BrightWhite: return setColour( "[1;37m" );
+
+ case Colour::Bright: throw std::logic_error( "not a colour" );
+ }
+ }
+ static IColourImpl* instance() {
+ static PosixColourImpl s_instance;
+ return &s_instance;
+ }
+
+ private:
+ void setColour( const char* _escapeCode ) {
+ Catch::cout() << '\033' << _escapeCode;
+ }
+ };
+
+ IColourImpl* platformColourInstance() {
+ Ptr<IConfig const> config = getCurrentContext().getConfig();
+ return (config && config->forceColour()) || isatty(STDOUT_FILENO)
+ ? PosixColourImpl::instance()
+ : NoColourImpl::instance();
+ }
+
+} // end anon namespace
+} // end namespace Catch
+
+#else // not Windows or ANSI ///////////////////////////////////////////////
+
+namespace Catch {
+
+ static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
+
+} // end namespace Catch
+
+#endif // Windows/ ANSI/ None
+
+namespace Catch {
+
+ Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
+ Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
+ Colour::~Colour(){ if( !m_moved ) use( None ); }
+
+ void Colour::use( Code _colourCode ) {
+ static IColourImpl* impl = isDebuggerActive()
+ ? NoColourImpl::instance()
+ : platformColourInstance();
+ impl->use( _colourCode );
+ }
+
+} // end namespace Catch
+
+// #included from: catch_generators_impl.hpp
+#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
+
+#include <vector>
+#include <string>
+#include <map>
+
+namespace Catch {
+
+ struct GeneratorInfo : IGeneratorInfo {
+
+ GeneratorInfo( std::size_t size )
+ : m_size( size ),
+ m_currentIndex( 0 )
+ {}
+
+ bool moveNext() {
+ if( ++m_currentIndex == m_size ) {
+ m_currentIndex = 0;
+ return false;
+ }
+ return true;
+ }
+
+ std::size_t getCurrentIndex() const {
+ return m_currentIndex;
+ }
+
+ std::size_t m_size;
+ std::size_t m_currentIndex;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class GeneratorsForTest : public IGeneratorsForTest {
+
+ public:
+ ~GeneratorsForTest() {
+ deleteAll( m_generatorsInOrder );
+ }
+
+ IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
+ std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
+ if( it == m_generatorsByName.end() ) {
+ IGeneratorInfo* info = new GeneratorInfo( size );
+ m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
+ m_generatorsInOrder.push_back( info );
+ return *info;
+ }
+ return *it->second;
+ }
+
+ bool moveNext() {
+ std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
+ std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
+ for(; it != itEnd; ++it ) {
+ if( (*it)->moveNext() )
+ return true;
+ }
+ return false;
+ }
+
+ private:
+ std::map<std::string, IGeneratorInfo*> m_generatorsByName;
+ std::vector<IGeneratorInfo*> m_generatorsInOrder;
+ };
+
+ IGeneratorsForTest* createGeneratorsForTest()
+ {
+ return new GeneratorsForTest();
+ }
+
+} // end namespace Catch
+
+// #included from: catch_assertionresult.hpp
+#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
+
+namespace Catch {
+
+ AssertionInfo::AssertionInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ std::string const& _capturedExpression,
+ ResultDisposition::Flags _resultDisposition )
+ : macroName( _macroName ),
+ lineInfo( _lineInfo ),
+ capturedExpression( _capturedExpression ),
+ resultDisposition( _resultDisposition )
+ {}
+
+ AssertionResult::AssertionResult() {}
+
+ AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
+ : m_info( info ),
+ m_resultData( data )
+ {}
+
+ AssertionResult::~AssertionResult() {}
+
+ // Result was a success
+ bool AssertionResult::succeeded() const {
+ return Catch::isOk( m_resultData.resultType );
+ }
+
+ // Result was a success, or failure is suppressed
+ bool AssertionResult::isOk() const {
+ return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
+ }
+
+ ResultWas::OfType AssertionResult::getResultType() const {
+ return m_resultData.resultType;
+ }
+
+ bool AssertionResult::hasExpression() const {
+ return !m_info.capturedExpression.empty();
+ }
+
+ bool AssertionResult::hasMessage() const {
+ return !m_resultData.message.empty();
+ }
+
+ std::string AssertionResult::getExpression() const {
+ if( isFalseTest( m_info.resultDisposition ) )
+ return "!" + m_info.capturedExpression;
+ else
+ return m_info.capturedExpression;
+ }
+ std::string AssertionResult::getExpressionInMacro() const {
+ if( m_info.macroName.empty() )
+ return m_info.capturedExpression;
+ else
+ return m_info.macroName + "( " + m_info.capturedExpression + " )";
+ }
+
+ bool AssertionResult::hasExpandedExpression() const {
+ return hasExpression() && getExpandedExpression() != getExpression();
+ }
+
+ std::string AssertionResult::getExpandedExpression() const {
+ return m_resultData.reconstructedExpression;
+ }
+
+ std::string AssertionResult::getMessage() const {
+ return m_resultData.message;
+ }
+ SourceLineInfo AssertionResult::getSourceInfo() const {
+ return m_info.lineInfo;
+ }
+
+ std::string AssertionResult::getTestMacroName() const {
+ return m_info.macroName;
+ }
+
+} // end namespace Catch
+
+// #included from: catch_test_case_info.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
+
+namespace Catch {
+
+ inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
+ if( startsWith( tag, "." ) ||
+ tag == "hide" ||
+ tag == "!hide" )
+ return TestCaseInfo::IsHidden;
+ else if( tag == "!throws" )
+ return TestCaseInfo::Throws;
+ else if( tag == "!shouldfail" )
+ return TestCaseInfo::ShouldFail;
+ else if( tag == "!mayfail" )
+ return TestCaseInfo::MayFail;
+ else
+ return TestCaseInfo::None;
+ }
+ inline bool isReservedTag( std::string const& tag ) {
+ return TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
+ }
+ inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
+ if( isReservedTag( tag ) ) {
+ {
+ Colour colourGuard( Colour::Red );
+ Catch::cerr()
+ << "Tag name [" << tag << "] not allowed.\n"
+ << "Tag names starting with non alpha-numeric characters are reserved\n";
+ }
+ {
+ Colour colourGuard( Colour::FileName );
+ Catch::cerr() << _lineInfo << std::endl;
+ }
+ exit(1);
+ }
+ }
+
+ TestCase makeTestCase( ITestCase* _testCase,
+ std::string const& _className,
+ std::string const& _name,
+ std::string const& _descOrTags,
+ SourceLineInfo const& _lineInfo )
+ {
+ bool isHidden( startsWith( _name, "./" ) ); // Legacy support
+
+ // Parse out tags
+ std::set<std::string> tags;
+ std::string desc, tag;
+ bool inTag = false;
+ for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
+ char c = _descOrTags[i];
+ if( !inTag ) {
+ if( c == '[' )
+ inTag = true;
+ else
+ desc += c;
+ }
+ else {
+ if( c == ']' ) {
+ TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
+ if( prop == TestCaseInfo::IsHidden )
+ isHidden = true;
+ else if( prop == TestCaseInfo::None )
+ enforceNotReservedTag( tag, _lineInfo );
+
+ tags.insert( tag );
+ tag.clear();
+ inTag = false;
+ }
+ else
+ tag += c;
+ }
+ }
+ if( isHidden ) {
+ tags.insert( "hide" );
+ tags.insert( "." );
+ }
+
+ TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
+ return TestCase( _testCase, info );
+ }
+
+ TestCaseInfo::TestCaseInfo( std::string const& _name,
+ std::string const& _className,
+ std::string const& _description,
+ std::set<std::string> const& _tags,
+ SourceLineInfo const& _lineInfo )
+ : name( _name ),
+ className( _className ),
+ description( _description ),
+ tags( _tags ),
+ lineInfo( _lineInfo ),
+ properties( None )
+ {
+ std::ostringstream oss;
+ for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it ) {
+ oss << "[" << *it << "]";
+ std::string lcaseTag = toLower( *it );
+ properties = static_cast<SpecialProperties>( properties | parseSpecialTag( lcaseTag ) );
+ lcaseTags.insert( lcaseTag );
+ }
+ tagsAsString = oss.str();
+ }
+
+ TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
+ : name( other.name ),
+ className( other.className ),
+ description( other.description ),
+ tags( other.tags ),
+ lcaseTags( other.lcaseTags ),
+ tagsAsString( other.tagsAsString ),
+ lineInfo( other.lineInfo ),
+ properties( other.properties )
+ {}
+
+ bool TestCaseInfo::isHidden() const {
+ return ( properties & IsHidden ) != 0;
+ }
+ bool TestCaseInfo::throws() const {
+ return ( properties & Throws ) != 0;
+ }
+ bool TestCaseInfo::okToFail() const {
+ return ( properties & (ShouldFail | MayFail ) ) != 0;
+ }
+ bool TestCaseInfo::expectedToFail() const {
+ return ( properties & (ShouldFail ) ) != 0;
+ }
+
+ TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
+
+ TestCase::TestCase( TestCase const& other )
+ : TestCaseInfo( other ),
+ test( other.test )
+ {}
+
+ TestCase TestCase::withName( std::string const& _newName ) const {
+ TestCase other( *this );
+ other.name = _newName;
+ return other;
+ }
+
+ void TestCase::swap( TestCase& other ) {
+ test.swap( other.test );
+ name.swap( other.name );
+ className.swap( other.className );
+ description.swap( other.description );
+ tags.swap( other.tags );
+ lcaseTags.swap( other.lcaseTags );
+ tagsAsString.swap( other.tagsAsString );
+ std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
+ std::swap( lineInfo, other.lineInfo );
+ }
+
+ void TestCase::invoke() const {
+ test->invoke();
+ }
+
+ bool TestCase::operator == ( TestCase const& other ) const {
+ return test.get() == other.test.get() &&
+ name == other.name &&
+ className == other.className;
+ }
+
+ bool TestCase::operator < ( TestCase const& other ) const {
+ return name < other.name;
+ }
+ TestCase& TestCase::operator = ( TestCase const& other ) {
+ TestCase temp( other );
+ swap( temp );
+ return *this;
+ }
+
+ TestCaseInfo const& TestCase::getTestCaseInfo() const
+ {
+ return *this;
+ }
+
+} // end namespace Catch
+
+// #included from: catch_version.hpp
+#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
+
+namespace Catch {
+
+ // These numbers are maintained by a script
+ Version libraryVersion( 1, 1, 14, "develop" );
+}
+
+// #included from: catch_message.hpp
+#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
+
+namespace Catch {
+
+ MessageInfo::MessageInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ ResultWas::OfType _type )
+ : macroName( _macroName ),
+ lineInfo( _lineInfo ),
+ type( _type ),
+ sequence( ++globalCount )
+ {}
+
+ // This may need protecting if threading support is added
+ unsigned int MessageInfo::globalCount = 0;
+
+ ////////////////////////////////////////////////////////////////////////////
+
+ ScopedMessage::ScopedMessage( MessageBuilder const& builder )
+ : m_info( builder.m_info )
+ {
+ m_info.message = builder.m_stream.str();
+ getResultCapture().pushScopedMessage( m_info );
+ }
+ ScopedMessage::ScopedMessage( ScopedMessage const& other )
+ : m_info( other.m_info )
+ {}
+
+ ScopedMessage::~ScopedMessage() {
+ getResultCapture().popScopedMessage( m_info );
+ }
+
+} // end namespace Catch
+
+// #included from: catch_legacy_reporter_adapter.hpp
+#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
+
+// #included from: catch_legacy_reporter_adapter.h
+#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
+
+namespace Catch
+{
+ // Deprecated
+ struct IReporter : IShared {
+ virtual ~IReporter();
+
+ virtual bool shouldRedirectStdout() const = 0;
+
+ virtual void StartTesting() = 0;
+ virtual void EndTesting( Totals const& totals ) = 0;
+ virtual void StartGroup( std::string const& groupName ) = 0;
+ virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
+ virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
+ virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
+ virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
+ virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
+ virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
+ virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
+ virtual void Aborted() = 0;
+ virtual void Result( AssertionResult const& result ) = 0;
+ };
+
+ class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
+ {
+ public:
+ LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
+ virtual ~LegacyReporterAdapter();
+
+ virtual ReporterPreferences getPreferences() const;
+ virtual void noMatchingTestCases( std::string const& );
+ virtual void testRunStarting( TestRunInfo const& );
+ virtual void testGroupStarting( GroupInfo const& groupInfo );
+ virtual void testCaseStarting( TestCaseInfo const& testInfo );
+ virtual void sectionStarting( SectionInfo const& sectionInfo );
+ virtual void assertionStarting( AssertionInfo const& );
+ virtual bool assertionEnded( AssertionStats const& assertionStats );
+ virtual void sectionEnded( SectionStats const& sectionStats );
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats );
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats );
+ virtual void testRunEnded( TestRunStats const& testRunStats );
+ virtual void skipTest( TestCaseInfo const& );
+
+ private:
+ Ptr<IReporter> m_legacyReporter;
+ };
+}
+
+namespace Catch
+{
+ LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
+ : m_legacyReporter( legacyReporter )
+ {}
+ LegacyReporterAdapter::~LegacyReporterAdapter() {}
+
+ ReporterPreferences LegacyReporterAdapter::getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
+ return prefs;
+ }
+
+ void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
+ void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
+ m_legacyReporter->StartTesting();
+ }
+ void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
+ m_legacyReporter->StartGroup( groupInfo.name );
+ }
+ void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
+ m_legacyReporter->StartTestCase( testInfo );
+ }
+ void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
+ m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
+ }
+ void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
+ // Not on legacy interface
+ }
+
+ bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
+ if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
+ for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
+ it != itEnd;
+ ++it ) {
+ if( it->type == ResultWas::Info ) {
+ ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
+ rb << it->message;
+ rb.setResultType( ResultWas::Info );
+ AssertionResult result = rb.build();
+ m_legacyReporter->Result( result );
+ }
+ }
+ }
+ m_legacyReporter->Result( assertionStats.assertionResult );
+ return true;
+ }
+ void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
+ if( sectionStats.missingAssertions )
+ m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
+ m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
+ }
+ void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
+ m_legacyReporter->EndTestCase
+ ( testCaseStats.testInfo,
+ testCaseStats.totals,
+ testCaseStats.stdOut,
+ testCaseStats.stdErr );
+ }
+ void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
+ if( testGroupStats.aborting )
+ m_legacyReporter->Aborted();
+ m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
+ }
+ void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
+ m_legacyReporter->EndTesting( testRunStats.totals );
+ }
+ void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
+ }
+}
+
+// #included from: catch_timer.hpp
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc++11-long-long"
+#endif
+
+#ifdef CATCH_PLATFORM_WINDOWS
+#include <windows.h>
+#else
+#include <sys/time.h>
+#endif
+
+namespace Catch {
+
+ namespace {
+#ifdef CATCH_PLATFORM_WINDOWS
+ uint64_t getCurrentTicks() {
+ static uint64_t hz=0, hzo=0;
+ if (!hz) {
+ QueryPerformanceFrequency((LARGE_INTEGER*)&hz);
+ QueryPerformanceCounter((LARGE_INTEGER*)&hzo);
+ }
+ uint64_t t;
+ QueryPerformanceCounter((LARGE_INTEGER*)&t);
+ return ((t-hzo)*1000000)/hz;
+ }
+#else
+ uint64_t getCurrentTicks() {
+ timeval t;
+ gettimeofday(&t,NULL);
+ return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
+ }
+#endif
+ }
+
+ void Timer::start() {
+ m_ticks = getCurrentTicks();
+ }
+ unsigned int Timer::getElapsedMicroseconds() const {
+ return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
+ }
+ unsigned int Timer::getElapsedMilliseconds() const {
+ return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
+ }
+ double Timer::getElapsedSeconds() const {
+ return getElapsedMicroseconds()/1000000.0;
+ }
+
+} // namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+// #included from: catch_common.hpp
+#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
+
+namespace Catch {
+
+ bool startsWith( std::string const& s, std::string const& prefix ) {
+ return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
+ }
+ bool endsWith( std::string const& s, std::string const& suffix ) {
+ return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
+ }
+ bool contains( std::string const& s, std::string const& infix ) {
+ return s.find( infix ) != std::string::npos;
+ }
+ void toLowerInPlace( std::string& s ) {
+ std::transform( s.begin(), s.end(), s.begin(), ::tolower );
+ }
+ std::string toLower( std::string const& s ) {
+ std::string lc = s;
+ toLowerInPlace( lc );
+ return lc;
+ }
+ std::string trim( std::string const& str ) {
+ static char const* whitespaceChars = "\n\r\t ";
+ std::string::size_type start = str.find_first_not_of( whitespaceChars );
+ std::string::size_type end = str.find_last_not_of( whitespaceChars );
+
+ return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
+ }
+
+ bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
+ bool replaced = false;
+ std::size_t i = str.find( replaceThis );
+ while( i != std::string::npos ) {
+ replaced = true;
+ str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
+ if( i < str.size()-withThis.size() )
+ i = str.find( replaceThis, i+withThis.size() );
+ else
+ i = std::string::npos;
+ }
+ return replaced;
+ }
+
+ pluralise::pluralise( std::size_t count, std::string const& label )
+ : m_count( count ),
+ m_label( label )
+ {}
+
+ std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
+ os << pluraliser.m_count << " " << pluraliser.m_label;
+ if( pluraliser.m_count != 1 )
+ os << "s";
+ return os;
+ }
+
+ SourceLineInfo::SourceLineInfo() : line( 0 ){}
+ SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
+ : file( _file ),
+ line( _line )
+ {}
+ SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
+ : file( other.file ),
+ line( other.line )
+ {}
+ bool SourceLineInfo::empty() const {
+ return file.empty();
+ }
+ bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
+ return line == other.line && file == other.file;
+ }
+ bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
+ return line < other.line || ( line == other.line && file < other.file );
+ }
+
+ std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
+#ifndef __GNUG__
+ os << info.file << "(" << info.line << ")";
+#else
+ os << info.file << ":" << info.line;
+#endif
+ return os;
+ }
+
+ void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
+ std::ostringstream oss;
+ oss << locationInfo << ": Internal Catch error: '" << message << "'";
+ if( alwaysTrue() )
+ throw std::logic_error( oss.str() );
+ }
+}
+
+// #included from: catch_section.hpp
+#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
+
+namespace Catch {
+
+ SectionInfo::SectionInfo
+ ( SourceLineInfo const& _lineInfo,
+ std::string const& _name,
+ std::string const& _description )
+ : name( _name ),
+ description( _description ),
+ lineInfo( _lineInfo )
+ {}
+
+ Section::Section( SectionInfo const& info )
+ : m_info( info ),
+ m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
+ {
+ m_timer.start();
+ }
+
+ Section::~Section() {
+ if( m_sectionIncluded )
+ getResultCapture().sectionEnded( m_info, m_assertions, m_timer.getElapsedSeconds() );
+ }
+
+ // This indicates whether the section should be executed or not
+ Section::operator bool() const {
+ return m_sectionIncluded;
+ }
+
+} // end namespace Catch
+
+// #included from: catch_debugger.hpp
+#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
+
+#include <iostream>
+
+#ifdef CATCH_PLATFORM_MAC
+
+ #include <assert.h>
+ #include <stdbool.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <sys/sysctl.h>
+
+ namespace Catch{
+
+ // The following function is taken directly from the following technical note:
+ // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
+
+ // Returns true if the current process is being debugged (either
+ // running under the debugger or has a debugger attached post facto).
+ bool isDebuggerActive(){
+
+ int mib[4];
+ struct kinfo_proc info;
+ size_t size;
+
+ // Initialize the flags so that, if sysctl fails for some bizarre
+ // reason, we get a predictable result.
+
+ info.kp_proc.p_flag = 0;
+
+ // Initialize mib, which tells sysctl the info we want, in this case
+ // we're looking for information about a specific process ID.
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = getpid();
+
+ // Call sysctl.
+
+ size = sizeof(info);
+ if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0) != 0 ) {
+ Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
+ return false;
+ }
+
+ // We're being debugged if the P_TRACED flag is set.
+
+ return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
+ }
+ } // namespace Catch
+
+#elif defined(_MSC_VER)
+ extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
+ namespace Catch {
+ bool isDebuggerActive() {
+ return IsDebuggerPresent() != 0;
+ }
+ }
+#elif defined(__MINGW32__)
+ extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
+ namespace Catch {
+ bool isDebuggerActive() {
+ return IsDebuggerPresent() != 0;
+ }
+ }
+#else
+ namespace Catch {
+ inline bool isDebuggerActive() { return false; }
+ }
+#endif // Platform
+
+#ifdef CATCH_PLATFORM_WINDOWS
+ extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
+ namespace Catch {
+ void writeToDebugConsole( std::string const& text ) {
+ ::OutputDebugStringA( text.c_str() );
+ }
+ }
+#else
+ namespace Catch {
+ void writeToDebugConsole( std::string const& text ) {
+ // !TBD: Need a version for Mac/ XCode and other IDEs
+ Catch::cout() << text;
+ }
+ }
+#endif // Platform
+
+// #included from: catch_tostring.hpp
+#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
+
+namespace Catch {
+
+namespace Detail {
+
+ std::string unprintableString = "{?}";
+
+ namespace {
+ struct Endianness {
+ enum Arch { Big, Little };
+
+ static Arch which() {
+ union _{
+ int asInt;
+ char asChar[sizeof (int)];
+ } u;
+
+ u.asInt = 1;
+ return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
+ }
+ };
+ }
+
+ std::string rawMemoryToString( const void *object, std::size_t size )
+ {
+ // Reverse order for little endian architectures
+ int i = 0, end = static_cast<int>( size ), inc = 1;
+ if( Endianness::which() == Endianness::Little ) {
+ i = end-1;
+ end = inc = -1;
+ }
+
+ unsigned char const *bytes = static_cast<unsigned char const *>(object);
+ std::ostringstream os;
+ os << "0x" << std::setfill('0') << std::hex;
+ for( ; i != end; i += inc )
+ os << std::setw(2) << static_cast<unsigned>(bytes[i]);
+ return os.str();
+ }
+}
+
+std::string toString( std::string const& value ) {
+ std::string s = value;
+ if( getCurrentContext().getConfig()->showInvisibles() ) {
+ for(size_t i = 0; i < s.size(); ++i ) {
+ std::string subs;
+ switch( s[i] ) {
+ case '\n': subs = "\\n"; break;
+ case '\t': subs = "\\t"; break;
+ default: break;
+ }
+ if( !subs.empty() ) {
+ s = s.substr( 0, i ) + subs + s.substr( i+1 );
+ ++i;
+ }
+ }
+ }
+ return "\"" + s + "\"";
+}
+std::string toString( std::wstring const& value ) {
+
+ std::string s;
+ s.reserve( value.size() );
+ for(size_t i = 0; i < value.size(); ++i )
+ s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
+ return Catch::toString( s );
+}
+
+std::string toString( const char* const value ) {
+ return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
+}
+
+std::string toString( char* const value ) {
+ return Catch::toString( static_cast<const char*>( value ) );
+}
+
+std::string toString( const wchar_t* const value )
+{
+ return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
+}
+
+std::string toString( wchar_t* const value )
+{
+ return Catch::toString( static_cast<const wchar_t*>( value ) );
+}
+
+std::string toString( int value ) {
+ std::ostringstream oss;
+ if( value > 8192 )
+ oss << "0x" << std::hex << value;
+ else
+ oss << value;
+ return oss.str();
+}
+
+std::string toString( unsigned long value ) {
+ std::ostringstream oss;
+ if( value > 8192 )
+ oss << "0x" << std::hex << value;
+ else
+ oss << value;
+ return oss.str();
+}
+
+std::string toString( unsigned int value ) {
+ return Catch::toString( static_cast<unsigned long>( value ) );
+}
+
+template<typename T>
+std::string fpToString( T value, int precision ) {
+ std::ostringstream oss;
+ oss << std::setprecision( precision )
+ << std::fixed
+ << value;
+ std::string d = oss.str();
+ std::size_t i = d.find_last_not_of( '0' );
+ if( i != std::string::npos && i != d.size()-1 ) {
+ if( d[i] == '.' )
+ i++;
+ d = d.substr( 0, i+1 );
+ }
+ return d;
+}
+
+std::string toString( const double value ) {
+ return fpToString( value, 10 );
+}
+std::string toString( const float value ) {
+ return fpToString( value, 5 ) + "f";
+}
+
+std::string toString( bool value ) {
+ return value ? "true" : "false";
+}
+
+std::string toString( char value ) {
+ return value < ' '
+ ? toString( static_cast<unsigned int>( value ) )
+ : Detail::makeString( value );
+}
+
+std::string toString( signed char value ) {
+ return toString( static_cast<char>( value ) );
+}
+
+std::string toString( unsigned char value ) {
+ return toString( static_cast<char>( value ) );
+}
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+std::string toString( std::nullptr_t ) {
+ return "nullptr";
+}
+#endif
+
+#ifdef __OBJC__
+ std::string toString( NSString const * const& nsstring ) {
+ if( !nsstring )
+ return "nil";
+ return "@" + toString([nsstring UTF8String]);
+ }
+ std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
+ if( !nsstring )
+ return "nil";
+ return "@" + toString([nsstring UTF8String]);
+ }
+ std::string toString( NSObject* const& nsObject ) {
+ return toString( [nsObject description] );
+ }
+#endif
+
+} // end namespace Catch
+
+// #included from: catch_result_builder.hpp
+#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
+
+namespace Catch {
+
+ ResultBuilder::ResultBuilder( char const* macroName,
+ SourceLineInfo const& lineInfo,
+ char const* capturedExpression,
+ ResultDisposition::Flags resultDisposition )
+ : m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition ),
+ m_shouldDebugBreak( false ),
+ m_shouldThrow( false )
+ {}
+
+ ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
+ m_data.resultType = result;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setResultType( bool result ) {
+ m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {
+ m_exprComponents.lhs = lhs;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {
+ m_exprComponents.rhs = rhs;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setOp( std::string const& op ) {
+ m_exprComponents.op = op;
+ return *this;
+ }
+
+ void ResultBuilder::endExpression() {
+ m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );
+ captureExpression();
+ }
+
+ void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
+ m_assertionInfo.resultDisposition = resultDisposition;
+ m_stream.oss << Catch::translateActiveException();
+ captureResult( ResultWas::ThrewException );
+ }
+
+ void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
+ setResultType( resultType );
+ captureExpression();
+ }
+
+ void ResultBuilder::captureExpression() {
+ AssertionResult result = build();
+ getResultCapture().assertionEnded( result );
+
+ if( !result.isOk() ) {
+ if( getCurrentContext().getConfig()->shouldDebugBreak() )
+ m_shouldDebugBreak = true;
+ if( getCurrentContext().getRunner()->aborting() || m_assertionInfo.resultDisposition == ResultDisposition::Normal )
+ m_shouldThrow = true;
+ }
+ }
+ void ResultBuilder::react() {
+ if( m_shouldThrow )
+ throw Catch::TestFailureException();
+ }
+
+ bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
+ bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
+
+ AssertionResult ResultBuilder::build() const
+ {
+ assert( m_data.resultType != ResultWas::Unknown );
+
+ AssertionResultData data = m_data;
+
+ // Flip bool results if testFalse is set
+ if( m_exprComponents.testFalse ) {
+ if( data.resultType == ResultWas::Ok )
+ data.resultType = ResultWas::ExpressionFailed;
+ else if( data.resultType == ResultWas::ExpressionFailed )
+ data.resultType = ResultWas::Ok;
+ }
+
+ data.message = m_stream.oss.str();
+ data.reconstructedExpression = reconstructExpression();
+ if( m_exprComponents.testFalse ) {
+ if( m_exprComponents.op == "" )
+ data.reconstructedExpression = "!" + data.reconstructedExpression;
+ else
+ data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
+ }
+ return AssertionResult( m_assertionInfo, data );
+ }
+ std::string ResultBuilder::reconstructExpression() const {
+ if( m_exprComponents.op == "" )
+ return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
+ else if( m_exprComponents.op == "matches" )
+ return m_exprComponents.lhs + " " + m_exprComponents.rhs;
+ else if( m_exprComponents.op != "!" ) {
+ if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
+ m_exprComponents.lhs.find("\n") == std::string::npos &&
+ m_exprComponents.rhs.find("\n") == std::string::npos )
+ return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
+ else
+ return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
+ }
+ else
+ return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}";
+ }
+
+} // end namespace Catch
+
+// #included from: catch_tag_alias_registry.hpp
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
+
+// #included from: catch_tag_alias_registry.h
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
+
+#include <map>
+
+namespace Catch {
+
+ class TagAliasRegistry : public ITagAliasRegistry {
+ public:
+ virtual ~TagAliasRegistry();
+ virtual Option<TagAlias> find( std::string const& alias ) const;
+ virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
+ void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
+ static TagAliasRegistry& get();
+
+ private:
+ std::map<std::string, TagAlias> m_registry;
+ };
+
+} // end namespace Catch
+
+#include <map>
+#include <iostream>
+
+namespace Catch {
+
+ TagAliasRegistry::~TagAliasRegistry() {}
+
+ Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
+ std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
+ if( it != m_registry.end() )
+ return it->second;
+ else
+ return Option<TagAlias>();
+ }
+
+ std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
+ std::string expandedTestSpec = unexpandedTestSpec;
+ for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
+ it != itEnd;
+ ++it ) {
+ std::size_t pos = expandedTestSpec.find( it->first );
+ if( pos != std::string::npos ) {
+ expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
+ it->second.tag +
+ expandedTestSpec.substr( pos + it->first.size() );
+ }
+ }
+ return expandedTestSpec;
+ }
+
+ void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
+
+ if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) {
+ std::ostringstream oss;
+ oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
+ throw std::domain_error( oss.str().c_str() );
+ }
+ if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
+ std::ostringstream oss;
+ oss << "error: tag alias, \"" << alias << "\" already registered.\n"
+ << "\tFirst seen at " << find(alias)->lineInfo << "\n"
+ << "\tRedefined at " << lineInfo;
+ throw std::domain_error( oss.str().c_str() );
+ }
+ }
+
+ TagAliasRegistry& TagAliasRegistry::get() {
+ static TagAliasRegistry instance;
+ return instance;
+
+ }
+
+ ITagAliasRegistry::~ITagAliasRegistry() {}
+ ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
+
+ RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
+ try {
+ TagAliasRegistry::get().add( alias, tag, lineInfo );
+ }
+ catch( std::exception& ex ) {
+ Colour colourGuard( Colour::Red );
+ Catch::cerr() << ex.what() << std::endl;
+ exit(1);
+ }
+ }
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_xml.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
+
+// #included from: catch_reporter_bases.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
+
+#include <cstring>
+
+namespace Catch {
+
+ struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
+
+ StreamingReporterBase( ReporterConfig const& _config )
+ : m_config( _config.fullConfig() ),
+ stream( _config.stream() )
+ {}
+
+ virtual ~StreamingReporterBase();
+
+ virtual void noMatchingTestCases( std::string const& ) {}
+
+ virtual void testRunStarting( TestRunInfo const& _testRunInfo ) {
+ currentTestRunInfo = _testRunInfo;
+ }
+ virtual void testGroupStarting( GroupInfo const& _groupInfo ) {
+ currentGroupInfo = _groupInfo;
+ }
+
+ virtual void testCaseStarting( TestCaseInfo const& _testInfo ) {
+ currentTestCaseInfo = _testInfo;
+ }
+ virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
+ m_sectionStack.push_back( _sectionInfo );
+ }
+
+ virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) {
+ m_sectionStack.pop_back();
+ }
+ virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) {
+ currentTestCaseInfo.reset();
+ }
+ virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) {
+ currentGroupInfo.reset();
+ }
+ virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) {
+ currentTestCaseInfo.reset();
+ currentGroupInfo.reset();
+ currentTestRunInfo.reset();
+ }
+
+ virtual void skipTest( TestCaseInfo const& ) {
+ // Don't do anything with this by default.
+ // It can optionally be overridden in the derived class.
+ }
+
+ Ptr<IConfig> m_config;
+ std::ostream& stream;
+
+ LazyStat<TestRunInfo> currentTestRunInfo;
+ LazyStat<GroupInfo> currentGroupInfo;
+ LazyStat<TestCaseInfo> currentTestCaseInfo;
+
+ std::vector<SectionInfo> m_sectionStack;
+ };
+
+ struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
+ template<typename T, typename ChildNodeT>
+ struct Node : SharedImpl<> {
+ explicit Node( T const& _value ) : value( _value ) {}
+ virtual ~Node() {}
+
+ typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
+ T value;
+ ChildNodes children;
+ };
+ struct SectionNode : SharedImpl<> {
+ explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
+ virtual ~SectionNode();
+
+ bool operator == ( SectionNode const& other ) const {
+ return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
+ }
+ bool operator == ( Ptr<SectionNode> const& other ) const {
+ return operator==( *other );
+ }
+
+ SectionStats stats;
+ typedef std::vector<Ptr<SectionNode> > ChildSections;
+ typedef std::vector<AssertionStats> Assertions;
+ ChildSections childSections;
+ Assertions assertions;
+ std::string stdOut;
+ std::string stdErr;
+ };
+
+ struct BySectionInfo {
+ BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
+ BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
+ bool operator() ( Ptr<SectionNode> const& node ) const {
+ return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
+ }
+ private:
+ void operator=( BySectionInfo const& );
+ SectionInfo const& m_other;
+ };
+
+ typedef Node<TestCaseStats, SectionNode> TestCaseNode;
+ typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
+ typedef Node<TestRunStats, TestGroupNode> TestRunNode;
+
+ CumulativeReporterBase( ReporterConfig const& _config )
+ : m_config( _config.fullConfig() ),
+ stream( _config.stream() )
+ {}
+ ~CumulativeReporterBase();
+
+ virtual void testRunStarting( TestRunInfo const& ) {}
+ virtual void testGroupStarting( GroupInfo const& ) {}
+
+ virtual void testCaseStarting( TestCaseInfo const& ) {}
+
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) {
+ SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
+ Ptr<SectionNode> node;
+ if( m_sectionStack.empty() ) {
+ if( !m_rootSection )
+ m_rootSection = new SectionNode( incompleteStats );
+ node = m_rootSection;
+ }
+ else {
+ SectionNode& parentNode = *m_sectionStack.back();
+ SectionNode::ChildSections::const_iterator it =
+ std::find_if( parentNode.childSections.begin(),
+ parentNode.childSections.end(),
+ BySectionInfo( sectionInfo ) );
+ if( it == parentNode.childSections.end() ) {
+ node = new SectionNode( incompleteStats );
+ parentNode.childSections.push_back( node );
+ }
+ else
+ node = *it;
+ }
+ m_sectionStack.push_back( node );
+ m_deepestSection = node;
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) {}
+
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) {
+ assert( !m_sectionStack.empty() );
+ SectionNode& sectionNode = *m_sectionStack.back();
+ sectionNode.assertions.push_back( assertionStats );
+ return true;
+ }
+ virtual void sectionEnded( SectionStats const& sectionStats ) {
+ assert( !m_sectionStack.empty() );
+ SectionNode& node = *m_sectionStack.back();
+ node.stats = sectionStats;
+ m_sectionStack.pop_back();
+ }
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
+ Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
+ assert( m_sectionStack.size() == 0 );
+ node->children.push_back( m_rootSection );
+ m_testCases.push_back( node );
+ m_rootSection.reset();
+
+ assert( m_deepestSection );
+ m_deepestSection->stdOut = testCaseStats.stdOut;
+ m_deepestSection->stdErr = testCaseStats.stdErr;
+ }
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
+ Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
+ node->children.swap( m_testCases );
+ m_testGroups.push_back( node );
+ }
+ virtual void testRunEnded( TestRunStats const& testRunStats ) {
+ Ptr<TestRunNode> node = new TestRunNode( testRunStats );
+ node->children.swap( m_testGroups );
+ m_testRuns.push_back( node );
+ testRunEndedCumulative();
+ }
+ virtual void testRunEndedCumulative() = 0;
+
+ virtual void skipTest( TestCaseInfo const& ) {}
+
+ Ptr<IConfig> m_config;
+ std::ostream& stream;
+ std::vector<AssertionStats> m_assertions;
+ std::vector<std::vector<Ptr<SectionNode> > > m_sections;
+ std::vector<Ptr<TestCaseNode> > m_testCases;
+ std::vector<Ptr<TestGroupNode> > m_testGroups;
+
+ std::vector<Ptr<TestRunNode> > m_testRuns;
+
+ Ptr<SectionNode> m_rootSection;
+ Ptr<SectionNode> m_deepestSection;
+ std::vector<Ptr<SectionNode> > m_sectionStack;
+
+ };
+
+ template<char C>
+ char const* getLineOfChars() {
+ static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
+ if( !*line ) {
+ memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
+ line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
+ }
+ return line;
+ }
+
+} // end namespace Catch
+
+// #included from: ../internal/catch_reporter_registrars.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
+
+namespace Catch {
+
+ template<typename T>
+ class LegacyReporterRegistrar {
+
+ class ReporterFactory : public IReporterFactory {
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const {
+ return new LegacyReporterAdapter( new T( config ) );
+ }
+
+ virtual std::string getDescription() const {
+ return T::getDescription();
+ }
+ };
+
+ public:
+
+ LegacyReporterRegistrar( std::string const& name ) {
+ getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
+ }
+ };
+
+ template<typename T>
+ class ReporterRegistrar {
+
+ class ReporterFactory : public IReporterFactory {
+
+ // *** Please Note ***:
+ // - If you end up here looking at a compiler error because it's trying to register
+ // your custom reporter class be aware that the native reporter interface has changed
+ // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
+ // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
+ // However please consider updating to the new interface as the old one is now
+ // deprecated and will probably be removed quite soon!
+ // Please contact me via github if you have any questions at all about this.
+ // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
+ // no idea who is actually using custom reporters at all (possibly no-one!).
+ // The new interface is designed to minimise exposure to interface changes in the future.
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const {
+ return new T( config );
+ }
+
+ virtual std::string getDescription() const {
+ return T::getDescription();
+ }
+ };
+
+ public:
+
+ ReporterRegistrar( std::string const& name ) {
+ getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
+ }
+ };
+}
+
+#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
+ namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
+#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
+ namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
+
+// #included from: ../internal/catch_xmlwriter.hpp
+#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+namespace Catch {
+
+ class XmlWriter {
+ public:
+
+ class ScopedElement {
+ public:
+ ScopedElement( XmlWriter* writer )
+ : m_writer( writer )
+ {}
+
+ ScopedElement( ScopedElement const& other )
+ : m_writer( other.m_writer ){
+ other.m_writer = NULL;
+ }
+
+ ~ScopedElement() {
+ if( m_writer )
+ m_writer->endElement();
+ }
+
+ ScopedElement& writeText( std::string const& text, bool indent = true ) {
+ m_writer->writeText( text, indent );
+ return *this;
+ }
+
+ template<typename T>
+ ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
+ m_writer->writeAttribute( name, attribute );
+ return *this;
+ }
+
+ private:
+ mutable XmlWriter* m_writer;
+ };
+
+ XmlWriter()
+ : m_tagIsOpen( false ),
+ m_needsNewline( false ),
+ m_os( &Catch::cout() )
+ {}
+
+ XmlWriter( std::ostream& os )
+ : m_tagIsOpen( false ),
+ m_needsNewline( false ),
+ m_os( &os )
+ {}
+
+ ~XmlWriter() {
+ while( !m_tags.empty() )
+ endElement();
+ }
+
+//# ifndef CATCH_CPP11_OR_GREATER
+// XmlWriter& operator = ( XmlWriter const& other ) {
+// XmlWriter temp( other );
+// swap( temp );
+// return *this;
+// }
+//# else
+// XmlWriter( XmlWriter const& ) = default;
+// XmlWriter( XmlWriter && ) = default;
+// XmlWriter& operator = ( XmlWriter const& ) = default;
+// XmlWriter& operator = ( XmlWriter && ) = default;
+//# endif
+//
+// void swap( XmlWriter& other ) {
+// std::swap( m_tagIsOpen, other.m_tagIsOpen );
+// std::swap( m_needsNewline, other.m_needsNewline );
+// std::swap( m_tags, other.m_tags );
+// std::swap( m_indent, other.m_indent );
+// std::swap( m_os, other.m_os );
+// }
+
+ XmlWriter& startElement( std::string const& name ) {
+ ensureTagClosed();
+ newlineIfNecessary();
+ stream() << m_indent << "<" << name;
+ m_tags.push_back( name );
+ m_indent += " ";
+ m_tagIsOpen = true;
+ return *this;
+ }
+
+ ScopedElement scopedElement( std::string const& name ) {
+ ScopedElement scoped( this );
+ startElement( name );
+ return scoped;
+ }
+
+ XmlWriter& endElement() {
+ newlineIfNecessary();
+ m_indent = m_indent.substr( 0, m_indent.size()-2 );
+ if( m_tagIsOpen ) {
+ stream() << "/>\n";
+ m_tagIsOpen = false;
+ }
+ else {
+ stream() << m_indent << "</" << m_tags.back() << ">\n";
+ }
+ m_tags.pop_back();
+ return *this;
+ }
+
+ XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
+ if( !name.empty() && !attribute.empty() ) {
+ stream() << " " << name << "=\"";
+ writeEncodedText( attribute );
+ stream() << "\"";
+ }
+ return *this;
+ }
+
+ XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
+ stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
+ return *this;
+ }
+
+ template<typename T>
+ XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
+ if( !name.empty() )
+ stream() << " " << name << "=\"" << attribute << "\"";
+ return *this;
+ }
+
+ XmlWriter& writeText( std::string const& text, bool indent = true ) {
+ if( !text.empty() ){
+ bool tagWasOpen = m_tagIsOpen;
+ ensureTagClosed();
+ if( tagWasOpen && indent )
+ stream() << m_indent;
+ writeEncodedText( text );
+ m_needsNewline = true;
+ }
+ return *this;
+ }
+
+ XmlWriter& writeComment( std::string const& text ) {
+ ensureTagClosed();
+ stream() << m_indent << "<!--" << text << "-->";
+ m_needsNewline = true;
+ return *this;
+ }
+
+ XmlWriter& writeBlankLine() {
+ ensureTagClosed();
+ stream() << "\n";
+ return *this;
+ }
+
+ void setStream( std::ostream& os ) {
+ m_os = &os;
+ }
+
+ private:
+ XmlWriter( XmlWriter const& );
+ void operator=( XmlWriter const& );
+
+ std::ostream& stream() {
+ return *m_os;
+ }
+
+ void ensureTagClosed() {
+ if( m_tagIsOpen ) {
+ stream() << ">\n";
+ m_tagIsOpen = false;
+ }
+ }
+
+ void newlineIfNecessary() {
+ if( m_needsNewline ) {
+ stream() << "\n";
+ m_needsNewline = false;
+ }
+ }
+
+ void writeEncodedText( std::string const& text ) {
+ static const char* charsToEncode = "<&\"";
+ std::string mtext = text;
+ std::string::size_type pos = mtext.find_first_of( charsToEncode );
+ while( pos != std::string::npos ) {
+ stream() << mtext.substr( 0, pos );
+
+ switch( mtext[pos] ) {
+ case '<':
+ stream() << "&lt;";
+ break;
+ case '&':
+ stream() << "&amp;";
+ break;
+ case '\"':
+ stream() << "&quot;";
+ break;
+ }
+ mtext = mtext.substr( pos+1 );
+ pos = mtext.find_first_of( charsToEncode );
+ }
+ stream() << mtext;
+ }
+
+ bool m_tagIsOpen;
+ bool m_needsNewline;
+ std::vector<std::string> m_tags;
+ std::string m_indent;
+ std::ostream* m_os;
+ };
+
+}
+namespace Catch {
+ class XmlReporter : public StreamingReporterBase {
+ public:
+ XmlReporter( ReporterConfig const& _config )
+ : StreamingReporterBase( _config ),
+ m_sectionDepth( 0 )
+ {}
+
+ virtual ~XmlReporter();
+
+ static std::string getDescription() {
+ return "Reports test results as an XML document";
+ }
+
+ public: // StreamingReporterBase
+ virtual ReporterPreferences getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = true;
+ return prefs;
+ }
+
+ virtual void noMatchingTestCases( std::string const& s ) {
+ StreamingReporterBase::noMatchingTestCases( s );
+ }
+
+ virtual void testRunStarting( TestRunInfo const& testInfo ) {
+ StreamingReporterBase::testRunStarting( testInfo );
+ m_xml.setStream( stream );
+ m_xml.startElement( "Catch" );
+ if( !m_config->name().empty() )
+ m_xml.writeAttribute( "name", m_config->name() );
+ }
+
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) {
+ StreamingReporterBase::testGroupStarting( groupInfo );
+ m_xml.startElement( "Group" )
+ .writeAttribute( "name", groupInfo.name );
+ }
+
+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) {
+ StreamingReporterBase::testCaseStarting(testInfo);
+ m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ m_testCaseTimer.start();
+ }
+
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) {
+ StreamingReporterBase::sectionStarting( sectionInfo );
+ if( m_sectionDepth++ > 0 ) {
+ m_xml.startElement( "Section" )
+ .writeAttribute( "name", trim( sectionInfo.name ) )
+ .writeAttribute( "description", sectionInfo.description );
+ }
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) { }
+
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) {
+ const AssertionResult& assertionResult = assertionStats.assertionResult;
+
+ // Print any info messages in <Info> tags.
+ if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
+ for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
+ it != itEnd;
+ ++it ) {
+ if( it->type == ResultWas::Info ) {
+ m_xml.scopedElement( "Info" )
+ .writeText( it->message );
+ } else if ( it->type == ResultWas::Warning ) {
+ m_xml.scopedElement( "Warning" )
+ .writeText( it->message );
+ }
+ }
+ }
+
+ // Drop out if result was successful but we're not printing them.
+ if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
+ return true;
+
+ // Print the expression if there is one.
+ if( assertionResult.hasExpression() ) {
+ m_xml.startElement( "Expression" )
+ .writeAttribute( "success", assertionResult.succeeded() )
+ .writeAttribute( "type", assertionResult.getTestMacroName() )
+ .writeAttribute( "filename", assertionResult.getSourceInfo().file )
+ .writeAttribute( "line", assertionResult.getSourceInfo().line );
+
+ m_xml.scopedElement( "Original" )
+ .writeText( assertionResult.getExpression() );
+ m_xml.scopedElement( "Expanded" )
+ .writeText( assertionResult.getExpandedExpression() );
+ }
+
+ // And... Print a result applicable to each result type.
+ switch( assertionResult.getResultType() ) {
+ case ResultWas::ThrewException:
+ m_xml.scopedElement( "Exception" )
+ .writeAttribute( "filename", assertionResult.getSourceInfo().file )
+ .writeAttribute( "line", assertionResult.getSourceInfo().line )
+ .writeText( assertionResult.getMessage() );
+ break;
+ case ResultWas::FatalErrorCondition:
+ m_xml.scopedElement( "Fatal Error Condition" )
+ .writeAttribute( "filename", assertionResult.getSourceInfo().file )
+ .writeAttribute( "line", assertionResult.getSourceInfo().line )
+ .writeText( assertionResult.getMessage() );
+ break;
+ case ResultWas::Info:
+ m_xml.scopedElement( "Info" )
+ .writeText( assertionResult.getMessage() );
+ break;
+ case ResultWas::Warning:
+ // Warning will already have been written
+ break;
+ case ResultWas::ExplicitFailure:
+ m_xml.scopedElement( "Failure" )
+ .writeText( assertionResult.getMessage() );
+ break;
+ default:
+ break;
+ }
+
+ if( assertionResult.hasExpression() )
+ m_xml.endElement();
+
+ return true;
+ }
+
+ virtual void sectionEnded( SectionStats const& sectionStats ) {
+ StreamingReporterBase::sectionEnded( sectionStats );
+ if( --m_sectionDepth > 0 ) {
+ XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
+ e.writeAttribute( "successes", sectionStats.assertions.passed );
+ e.writeAttribute( "failures", sectionStats.assertions.failed );
+ e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
+
+ m_xml.endElement();
+ }
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
+ StreamingReporterBase::testCaseEnded( testCaseStats );
+ XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
+ e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
+
+ m_xml.endElement();
+ }
+
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
+ StreamingReporterBase::testGroupEnded( testGroupStats );
+ // TODO: Check testGroupStats.aborting and act accordingly.
+ m_xml.scopedElement( "OverallResults" )
+ .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
+ .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
+ .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
+ m_xml.endElement();
+ }
+
+ virtual void testRunEnded( TestRunStats const& testRunStats ) {
+ StreamingReporterBase::testRunEnded( testRunStats );
+ m_xml.scopedElement( "OverallResults" )
+ .writeAttribute( "successes", testRunStats.totals.assertions.passed )
+ .writeAttribute( "failures", testRunStats.totals.assertions.failed )
+ .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
+ m_xml.endElement();
+ }
+
+ private:
+ Timer m_testCaseTimer;
+ XmlWriter m_xml;
+ int m_sectionDepth;
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_junit.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
+
+#include <assert.h>
+
+namespace Catch {
+
+ class JunitReporter : public CumulativeReporterBase {
+ public:
+ JunitReporter( ReporterConfig const& _config )
+ : CumulativeReporterBase( _config ),
+ xml( _config.stream() )
+ {}
+
+ ~JunitReporter();
+
+ static std::string getDescription() {
+ return "Reports test results in an XML format that looks like Ant's junitreport target";
+ }
+
+ virtual void noMatchingTestCases( std::string const& /*spec*/ ) {}
+
+ virtual ReporterPreferences getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = true;
+ return prefs;
+ }
+
+ virtual void testRunStarting( TestRunInfo const& runInfo ) {
+ CumulativeReporterBase::testRunStarting( runInfo );
+ xml.startElement( "testsuites" );
+ }
+
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) {
+ suiteTimer.start();
+ stdOutForSuite.str("");
+ stdErrForSuite.str("");
+ unexpectedExceptions = 0;
+ CumulativeReporterBase::testGroupStarting( groupInfo );
+ }
+
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) {
+ if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
+ unexpectedExceptions++;
+ return CumulativeReporterBase::assertionEnded( assertionStats );
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
+ stdOutForSuite << testCaseStats.stdOut;
+ stdErrForSuite << testCaseStats.stdErr;
+ CumulativeReporterBase::testCaseEnded( testCaseStats );
+ }
+
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
+ double suiteTime = suiteTimer.getElapsedSeconds();
+ CumulativeReporterBase::testGroupEnded( testGroupStats );
+ writeGroup( *m_testGroups.back(), suiteTime );
+ }
+
+ virtual void testRunEndedCumulative() {
+ xml.endElement();
+ }
+
+ void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
+ XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
+ TestGroupStats const& stats = groupNode.value;
+ xml.writeAttribute( "name", stats.groupInfo.name );
+ xml.writeAttribute( "errors", unexpectedExceptions );
+ xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
+ xml.writeAttribute( "tests", stats.totals.assertions.total() );
+ xml.writeAttribute( "hostname", "tbd" ); // !TBD
+ if( m_config->showDurations() == ShowDurations::Never )
+ xml.writeAttribute( "time", "" );
+ else
+ xml.writeAttribute( "time", suiteTime );
+ xml.writeAttribute( "timestamp", "tbd" ); // !TBD
+
+ // Write test cases
+ for( TestGroupNode::ChildNodes::const_iterator
+ it = groupNode.children.begin(), itEnd = groupNode.children.end();
+ it != itEnd;
+ ++it )
+ writeTestCase( **it );
+
+ xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
+ xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
+ }
+
+ void writeTestCase( TestCaseNode const& testCaseNode ) {
+ TestCaseStats const& stats = testCaseNode.value;
+
+ // All test cases have exactly one section - which represents the
+ // test case itself. That section may have 0-n nested sections
+ assert( testCaseNode.children.size() == 1 );
+ SectionNode const& rootSection = *testCaseNode.children.front();
+
+ std::string className = stats.testInfo.className;
+
+ if( className.empty() ) {
+ if( rootSection.childSections.empty() )
+ className = "global";
+ }
+ writeSection( className, "", rootSection );
+ }
+
+ void writeSection( std::string const& className,
+ std::string const& rootName,
+ SectionNode const& sectionNode ) {
+ std::string name = trim( sectionNode.stats.sectionInfo.name );
+ if( !rootName.empty() )
+ name = rootName + "/" + name;
+
+ if( !sectionNode.assertions.empty() ||
+ !sectionNode.stdOut.empty() ||
+ !sectionNode.stdErr.empty() ) {
+ XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
+ if( className.empty() ) {
+ xml.writeAttribute( "classname", name );
+ xml.writeAttribute( "name", "root" );
+ }
+ else {
+ xml.writeAttribute( "classname", className );
+ xml.writeAttribute( "name", name );
+ }
+ xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
+
+ writeAssertions( sectionNode );
+
+ if( !sectionNode.stdOut.empty() )
+ xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
+ if( !sectionNode.stdErr.empty() )
+ xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
+ }
+ for( SectionNode::ChildSections::const_iterator
+ it = sectionNode.childSections.begin(),
+ itEnd = sectionNode.childSections.end();
+ it != itEnd;
+ ++it )
+ if( className.empty() )
+ writeSection( name, "", **it );
+ else
+ writeSection( className, name, **it );
+ }
+
+ void writeAssertions( SectionNode const& sectionNode ) {
+ for( SectionNode::Assertions::const_iterator
+ it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
+ it != itEnd;
+ ++it )
+ writeAssertion( *it );
+ }
+ void writeAssertion( AssertionStats const& stats ) {
+ AssertionResult const& result = stats.assertionResult;
+ if( !result.isOk() ) {
+ std::string elementName;
+ switch( result.getResultType() ) {
+ case ResultWas::ThrewException:
+ case ResultWas::FatalErrorCondition:
+ elementName = "error";
+ break;
+ case ResultWas::ExplicitFailure:
+ elementName = "failure";
+ break;
+ case ResultWas::ExpressionFailed:
+ elementName = "failure";
+ break;
+ case ResultWas::DidntThrowException:
+ elementName = "failure";
+ break;
+
+ // We should never see these here:
+ case ResultWas::Info:
+ case ResultWas::Warning:
+ case ResultWas::Ok:
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ elementName = "internalError";
+ break;
+ }
+
+ XmlWriter::ScopedElement e = xml.scopedElement( elementName );
+
+ xml.writeAttribute( "message", result.getExpandedExpression() );
+ xml.writeAttribute( "type", result.getTestMacroName() );
+
+ std::ostringstream oss;
+ if( !result.getMessage().empty() )
+ oss << result.getMessage() << "\n";
+ for( std::vector<MessageInfo>::const_iterator
+ it = stats.infoMessages.begin(),
+ itEnd = stats.infoMessages.end();
+ it != itEnd;
+ ++it )
+ if( it->type == ResultWas::Info )
+ oss << it->message << "\n";
+
+ oss << "at " << result.getSourceInfo();
+ xml.writeText( oss.str(), false );
+ }
+ }
+
+ XmlWriter xml;
+ Timer suiteTimer;
+ std::ostringstream stdOutForSuite;
+ std::ostringstream stdErrForSuite;
+ unsigned int unexpectedExceptions;
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_console.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
+
+namespace Catch {
+
+ struct ConsoleReporter : StreamingReporterBase {
+ ConsoleReporter( ReporterConfig const& _config )
+ : StreamingReporterBase( _config ),
+ m_headerPrinted( false )
+ {}
+
+ virtual ~ConsoleReporter();
+ static std::string getDescription() {
+ return "Reports test results as plain lines of text";
+ }
+ virtual ReporterPreferences getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = false;
+ return prefs;
+ }
+
+ virtual void noMatchingTestCases( std::string const& spec ) {
+ stream << "No test cases matched '" << spec << "'" << std::endl;
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) {
+ }
+
+ virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
+ AssertionResult const& result = _assertionStats.assertionResult;
+
+ bool printInfoMessages = true;
+
+ // Drop out if result was successful and we're not printing those
+ if( !m_config->includeSuccessfulResults() && result.isOk() ) {
+ if( result.getResultType() != ResultWas::Warning )
+ return false;
+ printInfoMessages = false;
+ }
+
+ lazyPrint();
+
+ AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
+ printer.print();
+ stream << std::endl;
+ return true;
+ }
+
+ virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
+ m_headerPrinted = false;
+ StreamingReporterBase::sectionStarting( _sectionInfo );
+ }
+ virtual void sectionEnded( SectionStats const& _sectionStats ) {
+ if( _sectionStats.missingAssertions ) {
+ lazyPrint();
+ Colour colour( Colour::ResultError );
+ if( m_sectionStack.size() > 1 )
+ stream << "\nNo assertions in section";
+ else
+ stream << "\nNo assertions in test case";
+ stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
+ }
+ if( m_headerPrinted ) {
+ if( m_config->showDurations() == ShowDurations::Always )
+ stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
+ m_headerPrinted = false;
+ }
+ else {
+ if( m_config->showDurations() == ShowDurations::Always )
+ stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
+ }
+ StreamingReporterBase::sectionEnded( _sectionStats );
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) {
+ StreamingReporterBase::testCaseEnded( _testCaseStats );
+ m_headerPrinted = false;
+ }
+ virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) {
+ if( currentGroupInfo.used ) {
+ printSummaryDivider();
+ stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
+ printTotals( _testGroupStats.totals );
+ stream << "\n" << std::endl;
+ }
+ StreamingReporterBase::testGroupEnded( _testGroupStats );
+ }
+ virtual void testRunEnded( TestRunStats const& _testRunStats ) {
+ printTotalsDivider( _testRunStats.totals );
+ printTotals( _testRunStats.totals );
+ stream << std::endl;
+ StreamingReporterBase::testRunEnded( _testRunStats );
+ }
+
+ private:
+
+ class AssertionPrinter {
+ void operator= ( AssertionPrinter const& );
+ public:
+ AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
+ : stream( _stream ),
+ stats( _stats ),
+ result( _stats.assertionResult ),
+ colour( Colour::None ),
+ message( result.getMessage() ),
+ messages( _stats.infoMessages ),
+ printInfoMessages( _printInfoMessages )
+ {
+ switch( result.getResultType() ) {
+ case ResultWas::Ok:
+ colour = Colour::Success;
+ passOrFail = "PASSED";
+ //if( result.hasMessage() )
+ if( _stats.infoMessages.size() == 1 )
+ messageLabel = "with message";
+ if( _stats.infoMessages.size() > 1 )
+ messageLabel = "with messages";
+ break;
+ case ResultWas::ExpressionFailed:
+ if( result.isOk() ) {
+ colour = Colour::Success;
+ passOrFail = "FAILED - but was ok";
+ }
+ else {
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ }
+ if( _stats.infoMessages.size() == 1 )
+ messageLabel = "with message";
+ if( _stats.infoMessages.size() > 1 )
+ messageLabel = "with messages";
+ break;
+ case ResultWas::ThrewException:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "due to unexpected exception with message";
+ break;
+ case ResultWas::FatalErrorCondition:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "due to a fatal error condition";
+ break;
+ case ResultWas::DidntThrowException:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "because no exception was thrown where one was expected";
+ break;
+ case ResultWas::Info:
+ messageLabel = "info";
+ break;
+ case ResultWas::Warning:
+ messageLabel = "warning";
+ break;
+ case ResultWas::ExplicitFailure:
+ passOrFail = "FAILED";
+ colour = Colour::Error;
+ if( _stats.infoMessages.size() == 1 )
+ messageLabel = "explicitly with message";
+ if( _stats.infoMessages.size() > 1 )
+ messageLabel = "explicitly with messages";
+ break;
+ // These cases are here to prevent compiler warnings
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ passOrFail = "** internal error **";
+ colour = Colour::Error;
+ break;
+ }
+ }
+
+ void print() const {
+ printSourceInfo();
+ if( stats.totals.assertions.total() > 0 ) {
+ if( result.isOk() )
+ stream << "\n";
+ printResultType();
+ printOriginalExpression();
+ printReconstructedExpression();
+ }
+ else {
+ stream << "\n";
+ }
+ printMessage();
+ }
+
+ private:
+ void printResultType() const {
+ if( !passOrFail.empty() ) {
+ Colour colourGuard( colour );
+ stream << passOrFail << ":\n";
+ }
+ }
+ void printOriginalExpression() const {
+ if( result.hasExpression() ) {
+ Colour colourGuard( Colour::OriginalExpression );
+ stream << " ";
+ stream << result.getExpressionInMacro();
+ stream << "\n";
+ }
+ }
+ void printReconstructedExpression() const {
+ if( result.hasExpandedExpression() ) {
+ stream << "with expansion:\n";
+ Colour colourGuard( Colour::ReconstructedExpression );
+ stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n";
+ }
+ }
+ void printMessage() const {
+ if( !messageLabel.empty() )
+ stream << messageLabel << ":" << "\n";
+ for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
+ it != itEnd;
+ ++it ) {
+ // If this assertion is a warning ignore any INFO messages
+ if( printInfoMessages || it->type != ResultWas::Info )
+ stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n";
+ }
+ }
+ void printSourceInfo() const {
+ Colour colourGuard( Colour::FileName );
+ stream << result.getSourceInfo() << ": ";
+ }
+
+ std::ostream& stream;
+ AssertionStats const& stats;
+ AssertionResult const& result;
+ Colour::Code colour;
+ std::string passOrFail;
+ std::string messageLabel;
+ std::string message;
+ std::vector<MessageInfo> messages;
+ bool printInfoMessages;
+ };
+
+ void lazyPrint() {
+
+ if( !currentTestRunInfo.used )
+ lazyPrintRunInfo();
+ if( !currentGroupInfo.used )
+ lazyPrintGroupInfo();
+
+ if( !m_headerPrinted ) {
+ printTestCaseAndSectionHeader();
+ m_headerPrinted = true;
+ }
+ }
+ void lazyPrintRunInfo() {
+ stream << "\n" << getLineOfChars<'~'>() << "\n";
+ Colour colour( Colour::SecondaryText );
+ stream << currentTestRunInfo->name
+ << " is a Catch v" << libraryVersion.majorVersion << "."
+ << libraryVersion.minorVersion << " b"
+ << libraryVersion.buildNumber;
+ if( libraryVersion.branchName != std::string( "master" ) )
+ stream << " (" << libraryVersion.branchName << ")";
+ stream << " host application.\n"
+ << "Run with -? for options\n\n";
+
+ if( m_config->rngSeed() != 0 )
+ stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
+
+ currentTestRunInfo.used = true;
+ }
+ void lazyPrintGroupInfo() {
+ if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
+ printClosedHeader( "Group: " + currentGroupInfo->name );
+ currentGroupInfo.used = true;
+ }
+ }
+ void printTestCaseAndSectionHeader() {
+ assert( !m_sectionStack.empty() );
+ printOpenHeader( currentTestCaseInfo->name );
+
+ if( m_sectionStack.size() > 1 ) {
+ Colour colourGuard( Colour::Headers );
+
+ std::vector<SectionInfo>::const_iterator
+ it = m_sectionStack.begin()+1, // Skip first section (test case)
+ itEnd = m_sectionStack.end();
+ for( ; it != itEnd; ++it )
+ printHeaderString( it->name, 2 );
+ }
+
+ SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
+
+ if( !lineInfo.empty() ){
+ stream << getLineOfChars<'-'>() << "\n";
+ Colour colourGuard( Colour::FileName );
+ stream << lineInfo << "\n";
+ }
+ stream << getLineOfChars<'.'>() << "\n" << std::endl;
+ }
+
+ void printClosedHeader( std::string const& _name ) {
+ printOpenHeader( _name );
+ stream << getLineOfChars<'.'>() << "\n";
+ }
+ void printOpenHeader( std::string const& _name ) {
+ stream << getLineOfChars<'-'>() << "\n";
+ {
+ Colour colourGuard( Colour::Headers );
+ printHeaderString( _name );
+ }
+ }
+
+ // if string has a : in first line will set indent to follow it on
+ // subsequent lines
+ void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
+ std::size_t i = _string.find( ": " );
+ if( i != std::string::npos )
+ i+=2;
+ else
+ i = 0;
+ stream << Text( _string, TextAttributes()
+ .setIndent( indent+i)
+ .setInitialIndent( indent ) ) << "\n";
+ }
+
+ struct SummaryColumn {
+
+ SummaryColumn( std::string const& _label, Colour::Code _colour )
+ : label( _label ),
+ colour( _colour )
+ {}
+ SummaryColumn addRow( std::size_t count ) {
+ std::ostringstream oss;
+ oss << count;
+ std::string row = oss.str();
+ for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
+ while( it->size() < row.size() )
+ *it = " " + *it;
+ while( it->size() > row.size() )
+ row = " " + row;
+ }
+ rows.push_back( row );
+ return *this;
+ }
+
+ std::string label;
+ Colour::Code colour;
+ std::vector<std::string> rows;
+
+ };
+
+ void printTotals( Totals const& totals ) {
+ if( totals.testCases.total() == 0 ) {
+ stream << Colour( Colour::Warning ) << "No tests ran\n";
+ }
+ else if( totals.assertions.total() > 0 && totals.assertions.allPassed() ) {
+ stream << Colour( Colour::ResultSuccess ) << "All tests passed";
+ stream << " ("
+ << pluralise( totals.assertions.passed, "assertion" ) << " in "
+ << pluralise( totals.testCases.passed, "test case" ) << ")"
+ << "\n";
+ }
+ else {
+
+ std::vector<SummaryColumn> columns;
+ columns.push_back( SummaryColumn( "", Colour::None )
+ .addRow( totals.testCases.total() )
+ .addRow( totals.assertions.total() ) );
+ columns.push_back( SummaryColumn( "passed", Colour::Success )
+ .addRow( totals.testCases.passed )
+ .addRow( totals.assertions.passed ) );
+ columns.push_back( SummaryColumn( "failed", Colour::ResultError )
+ .addRow( totals.testCases.failed )
+ .addRow( totals.assertions.failed ) );
+ columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
+ .addRow( totals.testCases.failedButOk )
+ .addRow( totals.assertions.failedButOk ) );
+
+ printSummaryRow( "test cases", columns, 0 );
+ printSummaryRow( "assertions", columns, 1 );
+ }
+ }
+ void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
+ for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
+ std::string value = it->rows[row];
+ if( it->label.empty() ) {
+ stream << label << ": ";
+ if( value != "0" )
+ stream << value;
+ else
+ stream << Colour( Colour::Warning ) << "- none -";
+ }
+ else if( value != "0" ) {
+ stream << Colour( Colour::LightGrey ) << " | ";
+ stream << Colour( it->colour )
+ << value << " " << it->label;
+ }
+ }
+ stream << "\n";
+ }
+
+ static std::size_t makeRatio( std::size_t number, std::size_t total ) {
+ std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
+ return ( ratio == 0 && number > 0 ) ? 1 : ratio;
+ }
+ static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
+ if( i > j && i > k )
+ return i;
+ else if( j > k )
+ return j;
+ else
+ return k;
+ }
+
+ void printTotalsDivider( Totals const& totals ) {
+ if( totals.testCases.total() > 0 ) {
+ std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
+ std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
+ std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
+ while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
+ findMax( failedRatio, failedButOkRatio, passedRatio )++;
+ while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
+ findMax( failedRatio, failedButOkRatio, passedRatio )--;
+
+ stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
+ stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
+ if( totals.testCases.allPassed() )
+ stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
+ else
+ stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
+ }
+ else {
+ stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
+ }
+ stream << "\n";
+ }
+ void printSummaryDivider() {
+ stream << getLineOfChars<'-'>() << "\n";
+ }
+
+ private:
+ bool m_headerPrinted;
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_compact.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
+
+namespace Catch {
+
+ struct CompactReporter : StreamingReporterBase {
+
+ CompactReporter( ReporterConfig const& _config )
+ : StreamingReporterBase( _config )
+ {}
+
+ virtual ~CompactReporter();
+
+ static std::string getDescription() {
+ return "Reports test results on a single line, suitable for IDEs";
+ }
+
+ virtual ReporterPreferences getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = false;
+ return prefs;
+ }
+
+ virtual void noMatchingTestCases( std::string const& spec ) {
+ stream << "No test cases matched '" << spec << "'" << std::endl;
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) {
+ }
+
+ virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
+ AssertionResult const& result = _assertionStats.assertionResult;
+
+ bool printInfoMessages = true;
+
+ // Drop out if result was successful and we're not printing those
+ if( !m_config->includeSuccessfulResults() && result.isOk() ) {
+ if( result.getResultType() != ResultWas::Warning )
+ return false;
+ printInfoMessages = false;
+ }
+
+ AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
+ printer.print();
+
+ stream << std::endl;
+ return true;
+ }
+
+ virtual void testRunEnded( TestRunStats const& _testRunStats ) {
+ printTotals( _testRunStats.totals );
+ stream << "\n" << std::endl;
+ StreamingReporterBase::testRunEnded( _testRunStats );
+ }
+
+ private:
+ class AssertionPrinter {
+ void operator= ( AssertionPrinter const& );
+ public:
+ AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
+ : stream( _stream )
+ , stats( _stats )
+ , result( _stats.assertionResult )
+ , messages( _stats.infoMessages )
+ , itMessage( _stats.infoMessages.begin() )
+ , printInfoMessages( _printInfoMessages )
+ {}
+
+ void print() {
+ printSourceInfo();
+
+ itMessage = messages.begin();
+
+ switch( result.getResultType() ) {
+ case ResultWas::Ok:
+ printResultType( Colour::ResultSuccess, passedString() );
+ printOriginalExpression();
+ printReconstructedExpression();
+ if ( ! result.hasExpression() )
+ printRemainingMessages( Colour::None );
+ else
+ printRemainingMessages();
+ break;
+ case ResultWas::ExpressionFailed:
+ if( result.isOk() )
+ printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
+ else
+ printResultType( Colour::Error, failedString() );
+ printOriginalExpression();
+ printReconstructedExpression();
+ printRemainingMessages();
+ break;
+ case ResultWas::ThrewException:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "unexpected exception with message:" );
+ printMessage();
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::FatalErrorCondition:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "fatal error condition with message:" );
+ printMessage();
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::DidntThrowException:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "expected exception, got none" );
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::Info:
+ printResultType( Colour::None, "info" );
+ printMessage();
+ printRemainingMessages();
+ break;
+ case ResultWas::Warning:
+ printResultType( Colour::None, "warning" );
+ printMessage();
+ printRemainingMessages();
+ break;
+ case ResultWas::ExplicitFailure:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "explicitly" );
+ printRemainingMessages( Colour::None );
+ break;
+ // These cases are here to prevent compiler warnings
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ printResultType( Colour::Error, "** internal error **" );
+ break;
+ }
+ }
+
+ private:
+ // Colour::LightGrey
+
+ static Colour::Code dimColour() { return Colour::FileName; }
+
+#ifdef CATCH_PLATFORM_MAC
+ static const char* failedString() { return "FAILED"; }
+ static const char* passedString() { return "PASSED"; }
+#else
+ static const char* failedString() { return "failed"; }
+ static const char* passedString() { return "passed"; }
+#endif
+
+ void printSourceInfo() const {
+ Colour colourGuard( Colour::FileName );
+ stream << result.getSourceInfo() << ":";
+ }
+
+ void printResultType( Colour::Code colour, std::string passOrFail ) const {
+ if( !passOrFail.empty() ) {
+ {
+ Colour colourGuard( colour );
+ stream << " " << passOrFail;
+ }
+ stream << ":";
+ }
+ }
+
+ void printIssue( std::string issue ) const {
+ stream << " " << issue;
+ }
+
+ void printExpressionWas() {
+ if( result.hasExpression() ) {
+ stream << ";";
+ {
+ Colour colour( dimColour() );
+ stream << " expression was:";
+ }
+ printOriginalExpression();
+ }
+ }
+
+ void printOriginalExpression() const {
+ if( result.hasExpression() ) {
+ stream << " " << result.getExpression();
+ }
+ }
+
+ void printReconstructedExpression() const {
+ if( result.hasExpandedExpression() ) {
+ {
+ Colour colour( dimColour() );
+ stream << " for: ";
+ }
+ stream << result.getExpandedExpression();
+ }
+ }
+
+ void printMessage() {
+ if ( itMessage != messages.end() ) {
+ stream << " '" << itMessage->message << "'";
+ ++itMessage;
+ }
+ }
+
+ void printRemainingMessages( Colour::Code colour = dimColour() ) {
+ if ( itMessage == messages.end() )
+ return;
+
+ // using messages.end() directly yields compilation error:
+ std::vector<MessageInfo>::const_iterator itEnd = messages.end();
+ const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
+
+ {
+ Colour colourGuard( colour );
+ stream << " with " << pluralise( N, "message" ) << ":";
+ }
+
+ for(; itMessage != itEnd; ) {
+ // If this assertion is a warning ignore any INFO messages
+ if( printInfoMessages || itMessage->type != ResultWas::Info ) {
+ stream << " '" << itMessage->message << "'";
+ if ( ++itMessage != itEnd ) {
+ Colour colourGuard( dimColour() );
+ stream << " and";
+ }
+ }
+ }
+ }
+
+ private:
+ std::ostream& stream;
+ AssertionStats const& stats;
+ AssertionResult const& result;
+ std::vector<MessageInfo> messages;
+ std::vector<MessageInfo>::const_iterator itMessage;
+ bool printInfoMessages;
+ };
+
+ // Colour, message variants:
+ // - white: No tests ran.
+ // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
+ // - white: Passed [both/all] N test cases (no assertions).
+ // - red: Failed N tests cases, failed M assertions.
+ // - green: Passed [both/all] N tests cases with M assertions.
+
+ std::string bothOrAll( std::size_t count ) const {
+ return count == 1 ? "" : count == 2 ? "both " : "all " ;
+ }
+
+ void printTotals( const Totals& totals ) const {
+ if( totals.testCases.total() == 0 ) {
+ stream << "No tests ran.";
+ }
+ else if( totals.testCases.failed == totals.testCases.total() ) {
+ Colour colour( Colour::ResultError );
+ const std::string qualify_assertions_failed =
+ totals.assertions.failed == totals.assertions.total() ?
+ bothOrAll( totals.assertions.failed ) : "";
+ stream <<
+ "Failed " << bothOrAll( totals.testCases.failed )
+ << pluralise( totals.testCases.failed, "test case" ) << ", "
+ "failed " << qualify_assertions_failed <<
+ pluralise( totals.assertions.failed, "assertion" ) << ".";
+ }
+ else if( totals.assertions.total() == 0 ) {
+ stream <<
+ "Passed " << bothOrAll( totals.testCases.total() )
+ << pluralise( totals.testCases.total(), "test case" )
+ << " (no assertions).";
+ }
+ else if( totals.assertions.failed ) {
+ Colour colour( Colour::ResultError );
+ stream <<
+ "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", "
+ "failed " << pluralise( totals.assertions.failed, "assertion" ) << ".";
+ }
+ else {
+ Colour colour( Colour::ResultSuccess );
+ stream <<
+ "Passed " << bothOrAll( totals.testCases.passed )
+ << pluralise( totals.testCases.passed, "test case" ) <<
+ " with " << pluralise( totals.assertions.passed, "assertion" ) << ".";
+ }
+ }
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
+
+} // end namespace Catch
+
+namespace Catch {
+ NonCopyable::~NonCopyable() {}
+ IShared::~IShared() {}
+ StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
+ IContext::~IContext() {}
+ IResultCapture::~IResultCapture() {}
+ ITestCase::~ITestCase() {}
+ ITestCaseRegistry::~ITestCaseRegistry() {}
+ IRegistryHub::~IRegistryHub() {}
+ IMutableRegistryHub::~IMutableRegistryHub() {}
+ IExceptionTranslator::~IExceptionTranslator() {}
+ IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
+ IReporter::~IReporter() {}
+ IReporterFactory::~IReporterFactory() {}
+ IReporterRegistry::~IReporterRegistry() {}
+ IStreamingReporter::~IStreamingReporter() {}
+ AssertionStats::~AssertionStats() {}
+ SectionStats::~SectionStats() {}
+ TestCaseStats::~TestCaseStats() {}
+ TestGroupStats::~TestGroupStats() {}
+ TestRunStats::~TestRunStats() {}
+ CumulativeReporterBase::SectionNode::~SectionNode() {}
+ CumulativeReporterBase::~CumulativeReporterBase() {}
+
+ StreamingReporterBase::~StreamingReporterBase() {}
+ ConsoleReporter::~ConsoleReporter() {}
+ CompactReporter::~CompactReporter() {}
+ IRunner::~IRunner() {}
+ IMutableContext::~IMutableContext() {}
+ IConfig::~IConfig() {}
+ XmlReporter::~XmlReporter() {}
+ JunitReporter::~JunitReporter() {}
+ TestRegistry::~TestRegistry() {}
+ FreeFunctionTestCase::~FreeFunctionTestCase() {}
+ IGeneratorInfo::~IGeneratorInfo() {}
+ IGeneratorsForTest::~IGeneratorsForTest() {}
+ TestSpec::Pattern::~Pattern() {}
+ TestSpec::NamePattern::~NamePattern() {}
+ TestSpec::TagPattern::~TagPattern() {}
+ TestSpec::ExcludedPattern::~ExcludedPattern() {}
+
+ Matchers::Impl::StdString::Equals::~Equals() {}
+ Matchers::Impl::StdString::Contains::~Contains() {}
+ Matchers::Impl::StdString::StartsWith::~StartsWith() {}
+ Matchers::Impl::StdString::EndsWith::~EndsWith() {}
+
+ void Config::dummy() {}
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#endif
+
+#ifdef CATCH_CONFIG_MAIN
+// #included from: internal/catch_default_main.hpp
+#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
+
+#ifndef __OBJC__
+
+// Standard C/C++ main entry point
+int main (int argc, char * const argv[]) {
+ return Catch::Session().run( argc, argv );
+}
+
+#else // __OBJC__
+
+// Objective-C entry point
+int main (int argc, char * const argv[]) {
+#if !CATCH_ARC_ENABLED
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+#endif
+
+ Catch::registerTestMethods();
+ int result = Catch::Session().run( argc, (char* const*)argv );
+
+#if !CATCH_ARC_ENABLED
+ [pool drain];
+#endif
+
+ return result;
+}
+
+#endif // __OBJC__
+
+#endif
+
+#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
+# undef CLARA_CONFIG_MAIN
+#endif
+
+//////
+
+// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
+#ifdef CATCH_CONFIG_PREFIX_ALL
+
+#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
+#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
+
+#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS" )
+#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
+#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
+
+#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
+#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" )
+#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
+#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
+#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
+
+#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" )
+#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
+#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
+
+#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
+#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
+
+#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
+#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
+#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
+#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
+#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
+ #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
+ #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
+ #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+ #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
+ #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
+#else
+ #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
+ #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
+ #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
+ #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
+ #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
+ #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
+#endif
+#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
+
+#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
+#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
+
+#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
+
+// "BDD-style" convenience wrappers
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
+#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+#else
+#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
+#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
+#endif
+#define CATCH_GIVEN( desc ) CATCH_SECTION( "Given: " desc, "" )
+#define CATCH_WHEN( desc ) CATCH_SECTION( " When: " desc, "" )
+#define CATCH_AND_WHEN( desc ) CATCH_SECTION( " And: " desc, "" )
+#define CATCH_THEN( desc ) CATCH_SECTION( " Then: " desc, "" )
+#define CATCH_AND_THEN( desc ) CATCH_SECTION( " And: " desc, "" )
+
+// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
+#else
+
+#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
+#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
+
+#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "REQUIRE_THROWS" )
+#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
+#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
+
+#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
+#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" )
+#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
+#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
+#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
+
+#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS" )
+#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
+#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
+
+#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
+#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
+
+#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
+#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
+#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
+#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
+#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
+ #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
+ #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
+ #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+ #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
+ #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
+#else
+ #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
+ #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
+ #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
+ #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
+ #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
+ #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
+#endif
+#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
+
+#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
+#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
+
+#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
+
+#endif
+
+#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
+
+// "BDD-style" convenience wrappers
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
+#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+#else
+#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
+#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
+#endif
+#define GIVEN( desc ) SECTION( " Given: " desc, "" )
+#define WHEN( desc ) SECTION( " When: " desc, "" )
+#define AND_WHEN( desc ) SECTION( "And when: " desc, "" )
+#define THEN( desc ) SECTION( " Then: " desc, "" )
+#define AND_THEN( desc ) SECTION( " And: " desc, "" )
+
+using Catch::Detail::Approx;
+
+// #included from: internal/catch_reenable_warnings.h
+
+#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
+
+#ifdef __clang__
+# ifdef __ICC // icpc defines the __clang__ macro
+# pragma warning(pop)
+# else
+# pragma clang diagnostic pop
+# endif
+#elif defined __GNUC__
+# pragma GCC diagnostic pop
+#endif
+
+#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+
diff --git a/vendor/CppQuickCheck-2018-03-28/test/compact-check-tests.cpp b/vendor/CppQuickCheck-2018-03-28/test/compact-check-tests.cpp
new file mode 100644
index 00000000..910bc7b0
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/test/compact-check-tests.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016, Philipp Classen All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cppqc/Arbitrary.h"
+#include "catch.hpp"
+#include "cppqc/CompactCheck.h"
+
+using namespace cppqc;
+
+TEST_CASE("minimal passing example in compact check representation",
+ "[functional][compact]")
+{
+ const Result result = cppqc::gen<bool>()
+ .property("Dummy check (always passing)",
+ [](const bool &v)
+ {
+ return true;
+ })
+ .testWithOutput();
+
+ REQUIRE(result.result == QC_SUCCESS);
+}
+
+TEST_CASE("minimal failing example in compact check representation",
+ "[functional][compact]")
+{
+ const Result result = cppqc::gen<bool>()
+ .property("Dummy check (always failing)",
+ [](const bool &v)
+ {
+ return false; // Intended to fail
+ })
+ .testWithOutput();
+
+ REQUIRE(result.result == QC_FAILURE);
+}
+
+TEST_CASE("non-trivial example with std::sort should pass all tests",
+ "[functional][compact]")
+{
+ const Result result = cppqc::gen<std::vector<int>>()
+ .property("Should be sorted after calling std::sort",
+ [](const std::vector<int> &v)
+ {
+ std::vector<int> v_copy(v);
+ std::sort(std::begin(v_copy), std::end(v_copy));
+ return std::is_sorted(std::begin(v_copy), std::end(v_copy));
+ })
+ .classify([](const std::vector<int> &v)
+ {
+ return std::to_string(v.size());
+ })
+ .trivial([](const std::vector<int> &v)
+ {
+ return v.empty() || v.size() == 1;
+ })
+ .testWithOutput();
+
+ REQUIRE(result.result == QC_SUCCESS);
+}
diff --git a/vendor/CppQuickCheck-2018-03-28/test/functional-tests.cpp b/vendor/CppQuickCheck-2018-03-28/test/functional-tests.cpp
new file mode 100644
index 00000000..25661bbb
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/test/functional-tests.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2016, Philipp Classen All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cppqc.h"
+#include "catch.hpp"
+
+using namespace cppqc;
+
+namespace FunctionalTestsFixtures {
+
+struct MinimalPassingProperty : cppqc::Property<bool>
+{
+ bool check(const bool &v) const override
+ {
+ return true;
+ }
+ std::string name() const override
+ {
+ return "Dummy check (will always pass)";
+ }
+};
+
+struct MinimalFailingProperty : cppqc::Property<bool>
+{
+ bool check(const bool &v) const override
+ {
+ return false; // fails intentionally
+ }
+ std::string name() const override
+ {
+ return "Dummy check (will always fail)";
+ }
+};
+
+struct NontriviallyFailingProperty : cppqc::Property<std::vector<int>>
+{
+ bool check(const std::vector<int> &v) const override
+ {
+ if (v.size() >= 1 && (v[0] % 99) == 1) {
+ return false;
+ }
+
+ return true;
+ }
+};
+
+} // end FunctionalTestsFixtures
+
+TEST_CASE("minimal passing example",
+ "[functional]")
+{
+ const Result result =
+ quickCheckOutput(FunctionalTestsFixtures::MinimalPassingProperty{});
+
+ REQUIRE(result.result == QC_SUCCESS);
+}
+
+TEST_CASE("minimal failing example",
+ "[functional]")
+{
+ const Result result =
+ quickCheckOutput(FunctionalTestsFixtures::MinimalFailingProperty{});
+
+ REQUIRE(result.result == QC_FAILURE);
+}
+
+TEST_CASE("tests with fixed seeds must be repeatible",
+ "[functional][seed]")
+{
+ for (int i = 0; i < 100; i++) {
+ const auto seed = static_cast<SeedType>(i);
+
+ std::ostringstream output1;
+ const Result run1 =
+ quickCheckOutput(FunctionalTestsFixtures::NontriviallyFailingProperty{},
+ output1, 100, 0, 0, DISABLE_SHRINK_TIMEOUT, seed);
+ REQUIRE(run1.seed == seed);
+
+ std::ostringstream output2;
+ const Result run2 =
+ quickCheckOutput(FunctionalTestsFixtures::NontriviallyFailingProperty{},
+ output2, 100, 0, 0, DISABLE_SHRINK_TIMEOUT, seed);
+ REQUIRE(run2.seed == seed);
+
+ REQUIRE(run1.result == run2.result);
+ REQUIRE(output1.str() == output2.str());
+ }
+}
diff --git a/vendor/CppQuickCheck-2018-03-28/test/shrink-explosion-protection.cpp b/vendor/CppQuickCheck-2018-03-28/test/shrink-explosion-protection.cpp
new file mode 100644
index 00000000..d66b52e8
--- /dev/null
+++ b/vendor/CppQuickCheck-2018-03-28/test/shrink-explosion-protection.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2016, Philipp Classen All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cppqc/Arbitrary.h"
+#include "catch.hpp"
+
+#include "cppqc/cxx-prettyprint.h"
+
+using namespace cppqc;
+
+// Shrinking one value should eventually end, and the
+// intermediate state should not contain too many entries.
+template <typename T, typename ShrinkFunction,
+ int MAX_EXPECTED_RUNS = 1000, int MAX_EXPECTED_ENTRIES = 1000>
+void checkShrinkExplosions(T initialValue, ShrinkFunction shrinkFunction)
+{
+ std::vector<T> current = shrinkFunction(initialValue);
+ for (int i = 0; i < MAX_EXPECTED_RUNS; i++) {
+ std::vector<T> worstCase;
+ for (const auto& x : current) {
+ auto newValues = shrinkFunction(x);
+ REQUIRE(newValues.size() < MAX_EXPECTED_ENTRIES);
+
+ if (newValues.size() > worstCase.size()) {
+ worstCase = std::move(newValues);
+ }
+ }
+
+ current = std::move(worstCase);
+ if (current.empty()) {
+ return; // test passed
+ }
+ // std::cout << "current=" << current << '\n';
+ }
+ FAIL("should not be reached");
+}
+
+template <typename RealType>
+void checkShrinkExplosions_Real()
+{
+ for(RealType x : { RealType(0.0), RealType(0.5), RealType(1.0), RealType(-1.0),
+ RealType(1.75), RealType(100.0), RealType(-100.0), RealType(NAN),
+ std::numeric_limits<RealType>::min(),
+ std::numeric_limits<RealType>::max(),
+ std::numeric_limits<RealType>::infinity(),
+ -std::numeric_limits<RealType>::infinity() })
+ {
+ checkShrinkExplosions<RealType>(x, [](RealType x) { return shrinkReal(x); });
+ }
+}
+
+TEST_CASE("Number of elements should not explode during shrinking (float)",
+ "[shrinkReal][float]")
+{
+ checkShrinkExplosions_Real<float>();
+}
+
+TEST_CASE("Number of elements should not explode during shrinking (double)",
+ "[shrinkReal][double]")
+{
+ checkShrinkExplosions_Real<double>();
+}
+
+TEST_CASE("Number of elements should not explode during shrinking (long double)",
+ "[shrinkReal][long double]")
+{
+ checkShrinkExplosions_Real<long double>();
+}
+
+template <typename IntegralType>
+void checkShrinkExplosions_IntegralType()
+{
+ for (IntegralType x : { IntegralType(0), IntegralType(1), IntegralType(-1),
+ IntegralType(3), IntegralType(-3),
+ IntegralType(100), IntegralType(5555), IntegralType(-5555),
+ std::numeric_limits<IntegralType>::min(),
+ std::numeric_limits<IntegralType>::max() })
+ {
+
+ checkShrinkExplosions<IntegralType>(x, [](IntegralType x)
+ {
+ return shrinkIntegral(x);
+ });
+ }
+}
+
+TEST_CASE("Number of elements should not explode during shrinking (char)",
+ "[shrinkIntegral][char]")
+{
+ checkShrinkExplosions_IntegralType<char>();
+}
+
+TEST_CASE("Number of elements should not explode during shrinking (signed char)",
+ "[shrinkIntegral][signed char]")
+{
+ checkShrinkExplosions_IntegralType<signed char>();
+}
+
+TEST_CASE("Number of elements should not explode during shrinking (unsigned char)",
+ "[shrinkIntegral][unsigned char]")
+{
+ checkShrinkExplosions_IntegralType<unsigned char>();
+}
+
+TEST_CASE("Number of elements should not explode during shrinking (short)",
+ "[shrinkIntegral][short]")
+{
+ checkShrinkExplosions_IntegralType<short>();
+}
+
+TEST_CASE("Number of elements should not explode during shrinking (unsigned short)",
+ "[shrinkIntegral][unsigned short]")
+{
+ checkShrinkExplosions_IntegralType<unsigned short>();
+}
+
+TEST_CASE("Number of elements should not explode during shrinking (int)",
+ "[shrinkIntegral][int]")
+{
+ checkShrinkExplosions_IntegralType<int>();
+}
+
+TEST_CASE("Number of elements should not explode during shrinking (unsigned int)",
+ "[shrinkIntegral][unsigned int]")
+{
+ checkShrinkExplosions_IntegralType<unsigned int>();
+}
+
+TEST_CASE("Number of elements should not explode during shrinking (long)",
+ "[shrinkIntegral][long]")
+{
+ checkShrinkExplosions_IntegralType<long>();
+}
+
+TEST_CASE("Number of elements should not explode during shrinking (unsigned long)",
+ "[shrinkIntegral][unsigned long]")
+{
+ checkShrinkExplosions_IntegralType<unsigned long>();
+}
+
+TEST_CASE("Number of elements should not explode during shrinking (long long)",
+ "[shrinkIntegral][long long]")
+{
+ checkShrinkExplosions_IntegralType<long long>();
+}
+
+TEST_CASE("Number of elements should not explode during shrinking (unsigned long long)",
+ "[shrinkIntegral][unsigned long long]")
+{
+ checkShrinkExplosions_IntegralType<unsigned long long>();
+}
diff --git a/vendor/fmt b/vendor/fmt
index 8d7e4769..e437278e 120000
--- a/vendor/fmt
+++ b/vendor/fmt
@@ -1 +1 @@
-fmt-3.0.1 \ No newline at end of file
+fmt-4.1.0 \ No newline at end of file
diff --git a/vendor/fmt-3.0.1/fmt/format.cc b/vendor/fmt-3.0.1/fmt/format.cc
deleted file mode 100644
index 2bd774e4..00000000
--- a/vendor/fmt-3.0.1/fmt/format.cc
+++ /dev/null
@@ -1,940 +0,0 @@
-/*
- Formatting library for C++
-
- Copyright (c) 2012 - 2016, Victor Zverovich
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "format.h"
-
-#include <string.h>
-
-#include <cctype>
-#include <cerrno>
-#include <climits>
-#include <cmath>
-#include <cstdarg>
-#include <cstddef> // for std::ptrdiff_t
-
-#if defined(_WIN32) && defined(__MINGW32__)
-# include <cstring>
-#endif
-
-#if FMT_USE_WINDOWS_H
-# if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
-# include <windows.h>
-# else
-# define NOMINMAX
-# include <windows.h>
-# undef NOMINMAX
-# endif
-#endif
-
-using fmt::internal::Arg;
-
-#if FMT_EXCEPTIONS
-# define FMT_TRY try
-# define FMT_CATCH(x) catch (x)
-#else
-# define FMT_TRY if (true)
-# define FMT_CATCH(x) if (false)
-#endif
-
-#ifdef _MSC_VER
-# pragma warning(push)
-# pragma warning(disable: 4127) // conditional expression is constant
-# pragma warning(disable: 4702) // unreachable code
-// Disable deprecation warning for strerror. The latter is not called but
-// MSVC fails to detect it.
-# pragma warning(disable: 4996)
-#endif
-
-// Dummy implementations of strerror_r and strerror_s called if corresponding
-// system functions are not available.
-static inline fmt::internal::Null<> strerror_r(int, char *, ...) {
- return fmt::internal::Null<>();
-}
-static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) {
- return fmt::internal::Null<>();
-}
-
-namespace fmt {
-
-FMT_FUNC internal::RuntimeError::~RuntimeError() throw() {}
-FMT_FUNC FormatError::~FormatError() throw() {}
-FMT_FUNC SystemError::~SystemError() throw() {}
-
-namespace {
-
-#ifndef _MSC_VER
-# define FMT_SNPRINTF snprintf
-#else // _MSC_VER
-inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
- va_list args;
- va_start(args, format);
- int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
- va_end(args);
- return result;
-}
-# define FMT_SNPRINTF fmt_snprintf
-#endif // _MSC_VER
-
-#if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
-# define FMT_SWPRINTF snwprintf
-#else
-# define FMT_SWPRINTF swprintf
-#endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
-
-// Checks if a value fits in int - used to avoid warnings about comparing
-// signed and unsigned integers.
-template <bool IsSigned>
-struct IntChecker {
- template <typename T>
- static bool fits_in_int(T value) {
- unsigned max = INT_MAX;
- return value <= max;
- }
- static bool fits_in_int(bool) { return true; }
-};
-
-template <>
-struct IntChecker<true> {
- template <typename T>
- static bool fits_in_int(T value) {
- return value >= INT_MIN && value <= INT_MAX;
- }
- static bool fits_in_int(int) { return true; }
-};
-
-const char RESET_COLOR[] = "\x1b[0m";
-
-typedef void (*FormatFunc)(Writer &, int, StringRef);
-
-// Portable thread-safe version of strerror.
-// Sets buffer to point to a string describing the error code.
-// This can be either a pointer to a string stored in buffer,
-// or a pointer to some static immutable string.
-// Returns one of the following values:
-// 0 - success
-// ERANGE - buffer is not large enough to store the error message
-// other - failure
-// Buffer should be at least of size 1.
-int safe_strerror(
- int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
- FMT_ASSERT(buffer != 0 && buffer_size != 0, "invalid buffer");
-
- class StrError {
- private:
- int error_code_;
- char *&buffer_;
- std::size_t buffer_size_;
-
- // A noop assignment operator to avoid bogus warnings.
- void operator=(const StrError &) {}
-
- // Handle the result of XSI-compliant version of strerror_r.
- int handle(int result) {
- // glibc versions before 2.13 return result in errno.
- return result == -1 ? errno : result;
- }
-
- // Handle the result of GNU-specific version of strerror_r.
- int handle(char *message) {
- // If the buffer is full then the message is probably truncated.
- if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
- return ERANGE;
- buffer_ = message;
- return 0;
- }
-
- // Handle the case when strerror_r is not available.
- int handle(internal::Null<>) {
- return fallback(strerror_s(buffer_, buffer_size_, error_code_));
- }
-
- // Fallback to strerror_s when strerror_r is not available.
- int fallback(int result) {
- // If the buffer is full then the message is probably truncated.
- return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
- ERANGE : result;
- }
-
- // Fallback to strerror if strerror_r and strerror_s are not available.
- int fallback(internal::Null<>) {
- errno = 0;
- buffer_ = strerror(error_code_);
- return errno;
- }
-
- public:
- StrError(int err_code, char *&buf, std::size_t buf_size)
- : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
-
- int run() {
- strerror_r(0, 0, ""); // Suppress a warning about unused strerror_r.
- return handle(strerror_r(error_code_, buffer_, buffer_size_));
- }
- };
- return StrError(error_code, buffer, buffer_size).run();
-}
-
-void format_error_code(Writer &out, int error_code,
- StringRef message) FMT_NOEXCEPT {
- // Report error code making sure that the output fits into
- // INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
- // bad_alloc.
- out.clear();
- static const char SEP[] = ": ";
- static const char ERROR_STR[] = "error ";
- // Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
- std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
- typedef internal::IntTraits<int>::MainType MainType;
- MainType abs_value = static_cast<MainType>(error_code);
- if (internal::is_negative(error_code)) {
- abs_value = 0 - abs_value;
- ++error_code_size;
- }
- error_code_size += internal::count_digits(abs_value);
- if (message.size() <= internal::INLINE_BUFFER_SIZE - error_code_size)
- out << message << SEP;
- out << ERROR_STR << error_code;
- assert(out.size() <= internal::INLINE_BUFFER_SIZE);
-}
-
-void report_error(FormatFunc func, int error_code,
- StringRef message) FMT_NOEXCEPT {
- MemoryWriter full_message;
- func(full_message, error_code, message);
- // Use Writer::data instead of Writer::c_str to avoid potential memory
- // allocation.
- std::fwrite(full_message.data(), full_message.size(), 1, stderr);
- std::fputc('\n', stderr);
-}
-
-// IsZeroInt::visit(arg) returns true iff arg is a zero integer.
-class IsZeroInt : public ArgVisitor<IsZeroInt, bool> {
- public:
- template <typename T>
- bool visit_any_int(T value) { return value == 0; }
-};
-
-// Checks if an argument is a valid printf width specifier and sets
-// left alignment if it is negative.
-class WidthHandler : public ArgVisitor<WidthHandler, unsigned> {
- private:
- FormatSpec &spec_;
-
- FMT_DISALLOW_COPY_AND_ASSIGN(WidthHandler);
-
- public:
- explicit WidthHandler(FormatSpec &spec) : spec_(spec) {}
-
- void report_unhandled_arg() {
- FMT_THROW(FormatError("width is not integer"));
- }
-
- template <typename T>
- unsigned visit_any_int(T value) {
- typedef typename internal::IntTraits<T>::MainType UnsignedType;
- UnsignedType width = static_cast<UnsignedType>(value);
- if (internal::is_negative(value)) {
- spec_.align_ = ALIGN_LEFT;
- width = 0 - width;
- }
- if (width > INT_MAX)
- FMT_THROW(FormatError("number is too big"));
- return static_cast<unsigned>(width);
- }
-};
-
-class PrecisionHandler : public ArgVisitor<PrecisionHandler, int> {
- public:
- void report_unhandled_arg() {
- FMT_THROW(FormatError("precision is not integer"));
- }
-
- template <typename T>
- int visit_any_int(T value) {
- if (!IntChecker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
- FMT_THROW(FormatError("number is too big"));
- return static_cast<int>(value);
- }
-};
-
-template <typename T, typename U>
-struct is_same {
- enum { value = 0 };
-};
-
-template <typename T>
-struct is_same<T, T> {
- enum { value = 1 };
-};
-
-// An argument visitor that converts an integer argument to T for printf,
-// if T is an integral type. If T is void, the argument is converted to
-// corresponding signed or unsigned type depending on the type specifier:
-// 'd' and 'i' - signed, other - unsigned)
-template <typename T = void>
-class ArgConverter : public ArgVisitor<ArgConverter<T>, void> {
- private:
- internal::Arg &arg_;
- wchar_t type_;
-
- FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter);
-
- public:
- ArgConverter(internal::Arg &arg, wchar_t type)
- : arg_(arg), type_(type) {}
-
- void visit_bool(bool value) {
- if (type_ != 's')
- visit_any_int(value);
- }
-
- template <typename U>
- void visit_any_int(U value) {
- bool is_signed = type_ == 'd' || type_ == 'i';
- using internal::Arg;
- typedef typename internal::Conditional<
- is_same<T, void>::value, U, T>::type TargetType;
- if (sizeof(TargetType) <= sizeof(int)) {
- // Extra casts are used to silence warnings.
- if (is_signed) {
- arg_.type = Arg::INT;
- arg_.int_value = static_cast<int>(static_cast<TargetType>(value));
- } else {
- arg_.type = Arg::UINT;
- typedef typename internal::MakeUnsigned<TargetType>::Type Unsigned;
- arg_.uint_value = static_cast<unsigned>(static_cast<Unsigned>(value));
- }
- } else {
- if (is_signed) {
- arg_.type = Arg::LONG_LONG;
- // glibc's printf doesn't sign extend arguments of smaller types:
- // std::printf("%lld", -42); // prints "4294967254"
- // but we don't have to do the same because it's a UB.
- arg_.long_long_value = static_cast<LongLong>(value);
- } else {
- arg_.type = Arg::ULONG_LONG;
- arg_.ulong_long_value =
- static_cast<typename internal::MakeUnsigned<U>::Type>(value);
- }
- }
- }
-};
-
-// Converts an integer argument to char for printf.
-class CharConverter : public ArgVisitor<CharConverter, void> {
- private:
- internal::Arg &arg_;
-
- FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter);
-
- public:
- explicit CharConverter(internal::Arg &arg) : arg_(arg) {}
-
- template <typename T>
- void visit_any_int(T value) {
- arg_.type = internal::Arg::CHAR;
- arg_.int_value = static_cast<char>(value);
- }
-};
-} // namespace
-
-namespace internal {
-
-template <typename Char>
-class PrintfArgFormatter :
- public ArgFormatterBase<PrintfArgFormatter<Char>, Char> {
-
- void write_null_pointer() {
- this->spec().type_ = 0;
- this->write("(nil)");
- }
-
- typedef ArgFormatterBase<PrintfArgFormatter<Char>, Char> Base;
-
- public:
- PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s)
- : ArgFormatterBase<PrintfArgFormatter<Char>, Char>(w, s) {}
-
- void visit_bool(bool value) {
- FormatSpec &fmt_spec = this->spec();
- if (fmt_spec.type_ != 's')
- return this->visit_any_int(value);
- fmt_spec.type_ = 0;
- this->write(value);
- }
-
- void visit_char(int value) {
- const FormatSpec &fmt_spec = this->spec();
- BasicWriter<Char> &w = this->writer();
- if (fmt_spec.type_ && fmt_spec.type_ != 'c')
- w.write_int(value, fmt_spec);
- typedef typename BasicWriter<Char>::CharPtr CharPtr;
- CharPtr out = CharPtr();
- if (fmt_spec.width_ > 1) {
- Char fill = ' ';
- out = w.grow_buffer(fmt_spec.width_);
- if (fmt_spec.align_ != ALIGN_LEFT) {
- std::fill_n(out, fmt_spec.width_ - 1, fill);
- out += fmt_spec.width_ - 1;
- } else {
- std::fill_n(out + 1, fmt_spec.width_ - 1, fill);
- }
- } else {
- out = w.grow_buffer(1);
- }
- *out = static_cast<Char>(value);
- }
-
- void visit_cstring(const char *value) {
- if (value)
- Base::visit_cstring(value);
- else if (this->spec().type_ == 'p')
- write_null_pointer();
- else
- this->write("(null)");
- }
-
- void visit_pointer(const void *value) {
- if (value)
- return Base::visit_pointer(value);
- this->spec().type_ = 0;
- write_null_pointer();
- }
-
- void visit_custom(Arg::CustomValue c) {
- BasicFormatter<Char> formatter(ArgList(), this->writer());
- const Char format_str[] = {'}', 0};
- const Char *format = format_str;
- c.format(&formatter, c.value, &format);
- }
-};
-} // namespace internal
-} // namespace fmt
-
-FMT_FUNC void fmt::SystemError::init(
- int err_code, CStringRef format_str, ArgList args) {
- error_code_ = err_code;
- MemoryWriter w;
- internal::format_system_error(w, err_code, format(format_str, args));
- std::runtime_error &base = *this;
- base = std::runtime_error(w.str());
-}
-
-template <typename T>
-int fmt::internal::CharTraits<char>::format_float(
- char *buffer, std::size_t size, const char *format,
- unsigned width, int precision, T value) {
- if (width == 0) {
- return precision < 0 ?
- FMT_SNPRINTF(buffer, size, format, value) :
- FMT_SNPRINTF(buffer, size, format, precision, value);
- }
- return precision < 0 ?
- FMT_SNPRINTF(buffer, size, format, width, value) :
- FMT_SNPRINTF(buffer, size, format, width, precision, value);
-}
-
-template <typename T>
-int fmt::internal::CharTraits<wchar_t>::format_float(
- wchar_t *buffer, std::size_t size, const wchar_t *format,
- unsigned width, int precision, T value) {
- if (width == 0) {
- return precision < 0 ?
- FMT_SWPRINTF(buffer, size, format, value) :
- FMT_SWPRINTF(buffer, size, format, precision, value);
- }
- return precision < 0 ?
- FMT_SWPRINTF(buffer, size, format, width, value) :
- FMT_SWPRINTF(buffer, size, format, width, precision, value);
-}
-
-template <typename T>
-const char fmt::internal::BasicData<T>::DIGITS[] =
- "0001020304050607080910111213141516171819"
- "2021222324252627282930313233343536373839"
- "4041424344454647484950515253545556575859"
- "6061626364656667686970717273747576777879"
- "8081828384858687888990919293949596979899";
-
-#define FMT_POWERS_OF_10(factor) \
- factor * 10, \
- factor * 100, \
- factor * 1000, \
- factor * 10000, \
- factor * 100000, \
- factor * 1000000, \
- factor * 10000000, \
- factor * 100000000, \
- factor * 1000000000
-
-template <typename T>
-const uint32_t fmt::internal::BasicData<T>::POWERS_OF_10_32[] = {
- 0, FMT_POWERS_OF_10(1)
-};
-
-template <typename T>
-const uint64_t fmt::internal::BasicData<T>::POWERS_OF_10_64[] = {
- 0,
- FMT_POWERS_OF_10(1),
- FMT_POWERS_OF_10(fmt::ULongLong(1000000000)),
- // Multiply several constants instead of using a single long long constant
- // to avoid warnings about C++98 not supporting long long.
- fmt::ULongLong(1000000000) * fmt::ULongLong(1000000000) * 10
-};
-
-FMT_FUNC void fmt::internal::report_unknown_type(char code, const char *type) {
- (void)type;
- if (std::isprint(static_cast<unsigned char>(code))) {
- FMT_THROW(fmt::FormatError(
- fmt::format("unknown format code '{}' for {}", code, type)));
- }
- FMT_THROW(fmt::FormatError(
- fmt::format("unknown format code '\\x{:02x}' for {}",
- static_cast<unsigned>(code), type)));
-}
-
-#if FMT_USE_WINDOWS_H
-
-FMT_FUNC fmt::internal::UTF8ToUTF16::UTF8ToUTF16(fmt::StringRef s) {
- static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16";
- if (s.size() > INT_MAX)
- FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG));
- int s_size = static_cast<int>(s.size());
- int length = MultiByteToWideChar(
- CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, 0, 0);
- if (length == 0)
- FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
- buffer_.resize(length + 1);
- length = MultiByteToWideChar(
- CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length);
- if (length == 0)
- FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
- buffer_[length] = 0;
-}
-
-FMT_FUNC fmt::internal::UTF16ToUTF8::UTF16ToUTF8(fmt::WStringRef s) {
- if (int error_code = convert(s)) {
- FMT_THROW(WindowsError(error_code,
- "cannot convert string from UTF-16 to UTF-8"));
- }
-}
-
-FMT_FUNC int fmt::internal::UTF16ToUTF8::convert(fmt::WStringRef s) {
- if (s.size() > INT_MAX)
- return ERROR_INVALID_PARAMETER;
- int s_size = static_cast<int>(s.size());
- int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, 0, 0, 0, 0);
- if (length == 0)
- return GetLastError();
- buffer_.resize(length + 1);
- length = WideCharToMultiByte(
- CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, 0, 0);
- if (length == 0)
- return GetLastError();
- buffer_[length] = 0;
- return 0;
-}
-
-FMT_FUNC void fmt::WindowsError::init(
- int err_code, CStringRef format_str, ArgList args) {
- error_code_ = err_code;
- MemoryWriter w;
- internal::format_windows_error(w, err_code, format(format_str, args));
- std::runtime_error &base = *this;
- base = std::runtime_error(w.str());
-}
-
-FMT_FUNC void fmt::internal::format_windows_error(
- fmt::Writer &out, int error_code,
- fmt::StringRef message) FMT_NOEXCEPT {
- FMT_TRY {
- MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer;
- buffer.resize(INLINE_BUFFER_SIZE);
- for (;;) {
- wchar_t *system_message = &buffer[0];
- int result = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- 0, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- system_message, static_cast<uint32_t>(buffer.size()), 0);
- if (result != 0) {
- UTF16ToUTF8 utf8_message;
- if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
- out << message << ": " << utf8_message;
- return;
- }
- break;
- }
- if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
- break; // Can't get error message, report error code instead.
- buffer.resize(buffer.size() * 2);
- }
- } FMT_CATCH(...) {}
- fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
-}
-
-#endif // FMT_USE_WINDOWS_H
-
-FMT_FUNC void fmt::internal::format_system_error(
- fmt::Writer &out, int error_code,
- fmt::StringRef message) FMT_NOEXCEPT {
- FMT_TRY {
- MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer;
- buffer.resize(INLINE_BUFFER_SIZE);
- for (;;) {
- char *system_message = &buffer[0];
- int result = safe_strerror(error_code, system_message, buffer.size());
- if (result == 0) {
- out << message << ": " << system_message;
- return;
- }
- if (result != ERANGE)
- break; // Can't get error message, report error code instead.
- buffer.resize(buffer.size() * 2);
- }
- } FMT_CATCH(...) {}
- fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
-}
-
-template <typename Char>
-void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
- if (!map_.empty())
- return;
- typedef internal::NamedArg<Char> NamedArg;
- const NamedArg *named_arg = 0;
- bool use_values =
- args.type(ArgList::MAX_PACKED_ARGS - 1) == internal::Arg::NONE;
- if (use_values) {
- for (unsigned i = 0;/*nothing*/; ++i) {
- internal::Arg::Type arg_type = args.type(i);
- switch (arg_type) {
- case internal::Arg::NONE:
- return;
- case internal::Arg::NAMED_ARG:
- named_arg = static_cast<const NamedArg*>(args.values_[i].pointer);
- map_.push_back(Pair(named_arg->name, *named_arg));
- break;
- default:
- /*nothing*/;
- }
- }
- return;
- }
- for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) {
- internal::Arg::Type arg_type = args.type(i);
- if (arg_type == internal::Arg::NAMED_ARG) {
- named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
- map_.push_back(Pair(named_arg->name, *named_arg));
- }
- }
- for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
- switch (args.args_[i].type) {
- case internal::Arg::NONE:
- return;
- case internal::Arg::NAMED_ARG:
- named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
- map_.push_back(Pair(named_arg->name, *named_arg));
- break;
- default:
- /*nothing*/;
- }
- }
-}
-
-template <typename Char>
-void fmt::internal::FixedBuffer<Char>::grow(std::size_t) {
- FMT_THROW(std::runtime_error("buffer overflow"));
-}
-
-FMT_FUNC Arg fmt::internal::FormatterBase::do_get_arg(
- unsigned arg_index, const char *&error) {
- Arg arg = args_[arg_index];
- switch (arg.type) {
- case Arg::NONE:
- error = "argument index out of range";
- break;
- case Arg::NAMED_ARG:
- arg = *static_cast<const internal::Arg*>(arg.pointer);
- break;
- default:
- /*nothing*/;
- }
- return arg;
-}
-
-template <typename Char>
-void fmt::internal::PrintfFormatter<Char>::parse_flags(
- FormatSpec &spec, const Char *&s) {
- for (;;) {
- switch (*s++) {
- case '-':
- spec.align_ = ALIGN_LEFT;
- break;
- case '+':
- spec.flags_ |= SIGN_FLAG | PLUS_FLAG;
- break;
- case '0':
- spec.fill_ = '0';
- break;
- case ' ':
- spec.flags_ |= SIGN_FLAG;
- break;
- case '#':
- spec.flags_ |= HASH_FLAG;
- break;
- default:
- --s;
- return;
- }
- }
-}
-
-template <typename Char>
-Arg fmt::internal::PrintfFormatter<Char>::get_arg(
- const Char *s, unsigned arg_index) {
- (void)s;
- const char *error = 0;
- Arg arg = arg_index == UINT_MAX ?
- next_arg(error) : FormatterBase::get_arg(arg_index - 1, error);
- if (error)
- FMT_THROW(FormatError(!*s ? "invalid format string" : error));
- return arg;
-}
-
-template <typename Char>
-unsigned fmt::internal::PrintfFormatter<Char>::parse_header(
- const Char *&s, FormatSpec &spec) {
- unsigned arg_index = UINT_MAX;
- Char c = *s;
- if (c >= '0' && c <= '9') {
- // Parse an argument index (if followed by '$') or a width possibly
- // preceded with '0' flag(s).
- unsigned value = parse_nonnegative_int(s);
- if (*s == '$') { // value is an argument index
- ++s;
- arg_index = value;
- } else {
- if (c == '0')
- spec.fill_ = '0';
- if (value != 0) {
- // Nonzero value means that we parsed width and don't need to
- // parse it or flags again, so return now.
- spec.width_ = value;
- return arg_index;
- }
- }
- }
- parse_flags(spec, s);
- // Parse width.
- if (*s >= '0' && *s <= '9') {
- spec.width_ = parse_nonnegative_int(s);
- } else if (*s == '*') {
- ++s;
- spec.width_ = WidthHandler(spec).visit(get_arg(s));
- }
- return arg_index;
-}
-
-template <typename Char>
-void fmt::internal::PrintfFormatter<Char>::format(
- BasicWriter<Char> &writer, BasicCStringRef<Char> format_str) {
- const Char *start = format_str.c_str();
- const Char *s = start;
- while (*s) {
- Char c = *s++;
- if (c != '%') continue;
- if (*s == c) {
- write(writer, start, s);
- start = ++s;
- continue;
- }
- write(writer, start, s - 1);
-
- FormatSpec spec;
- spec.align_ = ALIGN_RIGHT;
-
- // Parse argument index, flags and width.
- unsigned arg_index = parse_header(s, spec);
-
- // Parse precision.
- if (*s == '.') {
- ++s;
- if ('0' <= *s && *s <= '9') {
- spec.precision_ = static_cast<int>(parse_nonnegative_int(s));
- } else if (*s == '*') {
- ++s;
- spec.precision_ = PrecisionHandler().visit(get_arg(s));
- }
- }
-
- Arg arg = get_arg(s, arg_index);
- if (spec.flag(HASH_FLAG) && IsZeroInt().visit(arg))
- spec.flags_ &= ~to_unsigned<int>(HASH_FLAG);
- if (spec.fill_ == '0') {
- if (arg.type <= Arg::LAST_NUMERIC_TYPE)
- spec.align_ = ALIGN_NUMERIC;
- else
- spec.fill_ = ' '; // Ignore '0' flag for non-numeric types.
- }
-
- // Parse length and convert the argument to the required type.
- switch (*s++) {
- case 'h':
- if (*s == 'h')
- ArgConverter<signed char>(arg, *++s).visit(arg);
- else
- ArgConverter<short>(arg, *s).visit(arg);
- break;
- case 'l':
- if (*s == 'l')
- ArgConverter<fmt::LongLong>(arg, *++s).visit(arg);
- else
- ArgConverter<long>(arg, *s).visit(arg);
- break;
- case 'j':
- ArgConverter<intmax_t>(arg, *s).visit(arg);
- break;
- case 'z':
- ArgConverter<std::size_t>(arg, *s).visit(arg);
- break;
- case 't':
- ArgConverter<std::ptrdiff_t>(arg, *s).visit(arg);
- break;
- case 'L':
- // printf produces garbage when 'L' is omitted for long double, no
- // need to do the same.
- break;
- default:
- --s;
- ArgConverter<void>(arg, *s).visit(arg);
- }
-
- // Parse type.
- if (!*s)
- FMT_THROW(FormatError("invalid format string"));
- spec.type_ = static_cast<char>(*s++);
- if (arg.type <= Arg::LAST_INTEGER_TYPE) {
- // Normalize type.
- switch (spec.type_) {
- case 'i': case 'u':
- spec.type_ = 'd';
- break;
- case 'c':
- // TODO: handle wchar_t
- CharConverter(arg).visit(arg);
- break;
- }
- }
-
- start = s;
-
- // Format argument.
- internal::PrintfArgFormatter<Char>(writer, spec).visit(arg);
- }
- write(writer, start, s);
-}
-
-FMT_FUNC void fmt::report_system_error(
- int error_code, fmt::StringRef message) FMT_NOEXCEPT {
- // 'fmt::' is for bcc32.
- fmt::report_error(internal::format_system_error, error_code, message);
-}
-
-#if FMT_USE_WINDOWS_H
-FMT_FUNC void fmt::report_windows_error(
- int error_code, fmt::StringRef message) FMT_NOEXCEPT {
- // 'fmt::' is for bcc32.
- fmt::report_error(internal::format_windows_error, error_code, message);
-}
-#endif
-
-FMT_FUNC void fmt::print(std::FILE *f, CStringRef format_str, ArgList args) {
- MemoryWriter w;
- w.write(format_str, args);
- std::fwrite(w.data(), 1, w.size(), f);
-}
-
-FMT_FUNC void fmt::print(CStringRef format_str, ArgList args) {
- print(stdout, format_str, args);
-}
-
-FMT_FUNC void fmt::print_colored(Color c, CStringRef format, ArgList args) {
- char escape[] = "\x1b[30m";
- escape[3] = static_cast<char>('0' + c);
- std::fputs(escape, stdout);
- print(format, args);
- std::fputs(RESET_COLOR, stdout);
-}
-
-FMT_FUNC int fmt::fprintf(std::FILE *f, CStringRef format, ArgList args) {
- MemoryWriter w;
- printf(w, format, args);
- std::size_t size = w.size();
- return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast<int>(size);
-}
-
-#ifndef FMT_HEADER_ONLY
-
-template struct fmt::internal::BasicData<void>;
-
-// Explicit instantiations for char.
-
-template void fmt::internal::FixedBuffer<char>::grow(std::size_t);
-
-template void fmt::internal::ArgMap<char>::init(const fmt::ArgList &args);
-
-template void fmt::internal::PrintfFormatter<char>::format(
- BasicWriter<char> &writer, CStringRef format);
-
-template int fmt::internal::CharTraits<char>::format_float(
- char *buffer, std::size_t size, const char *format,
- unsigned width, int precision, double value);
-
-template int fmt::internal::CharTraits<char>::format_float(
- char *buffer, std::size_t size, const char *format,
- unsigned width, int precision, long double value);
-
-// Explicit instantiations for wchar_t.
-
-template void fmt::internal::FixedBuffer<wchar_t>::grow(std::size_t);
-
-template void fmt::internal::ArgMap<wchar_t>::init(const fmt::ArgList &args);
-
-template void fmt::internal::PrintfFormatter<wchar_t>::format(
- BasicWriter<wchar_t> &writer, WCStringRef format);
-
-template int fmt::internal::CharTraits<wchar_t>::format_float(
- wchar_t *buffer, std::size_t size, const wchar_t *format,
- unsigned width, int precision, double value);
-
-template int fmt::internal::CharTraits<wchar_t>::format_float(
- wchar_t *buffer, std::size_t size, const wchar_t *format,
- unsigned width, int precision, long double value);
-
-#endif // FMT_HEADER_ONLY
-
-#ifdef _MSC_VER
-# pragma warning(pop)
-#endif
diff --git a/vendor/fmt-3.0.1/fmt/time.h b/vendor/fmt-3.0.1/fmt/time.h
deleted file mode 100644
index 10225c03..00000000
--- a/vendor/fmt-3.0.1/fmt/time.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- Formatting library for C++ - time formatting
-
- Copyright (c) 2012 - 2016, Victor Zverovich
- All rights reserved.
-
- For the license information refer to format.h.
- */
-
-#ifndef FMT_TIME_H_
-#define FMT_TIME_H_
-
-#include "format.h"
-#include <ctime>
-
-namespace fmt {
-template <typename ArgFormatter>
-void format(BasicFormatter<char, ArgFormatter> &f,
- const char *&format_str, const std::tm &tm) {
- if (*format_str == ':')
- ++format_str;
- const char *end = format_str;
- while (*end && *end != '}')
- ++end;
- if (*end != '}')
- FMT_THROW(FormatError("missing '}' in format string"));
- internal::MemoryBuffer<char, internal::INLINE_BUFFER_SIZE> format;
- format.append(format_str, end + 1);
- format[format.size() - 1] = '\0';
- Buffer<char> &buffer = f.writer().buffer();
- std::size_t start = buffer.size();
- for (;;) {
- std::size_t size = buffer.capacity() - start;
- std::size_t count = std::strftime(&buffer[start], size, &format[0], &tm);
- if (count != 0) {
- buffer.resize(start + count);
- break;
- }
- if (size >= format.size() * 256) {
- // If the buffer is 256 times larger than the format string, assume
- // that `strftime` gives an empty result. There doesn't seem to be a
- // better way to distinguish the two cases:
- // https://github.com/fmtlib/fmt/issues/367
- break;
- }
- const std::size_t MIN_GROWTH = 10;
- buffer.reserve(buffer.capacity() + (size > MIN_GROWTH ? size : MIN_GROWTH));
- }
- format_str = end + 1;
-}
-}
-
-#endif // FMT_TIME_H_
diff --git a/vendor/fmt-3.0.1/fmt/CMakeLists.txt b/vendor/fmt-4.1.0/fmt/CMakeLists.txt
index 89ef1f35..3259d788 100644
--- a/vendor/fmt-3.0.1/fmt/CMakeLists.txt
+++ b/vendor/fmt-4.1.0/fmt/CMakeLists.txt
@@ -1,21 +1,19 @@
# Define the fmt library, its includes and the needed defines.
-# format.cc is added to FMT_HEADERS for the header-only configuration.
-set(FMT_HEADERS format.h format.cc ostream.h ostream.cc time.h)
+# *.cc are added to FMT_HEADERS for the header-only configuration.
+set(FMT_HEADERS container.h format.h format.cc ostream.h ostream.cc printf.h
+ printf.cc string.h time.h)
if (HAVE_OPEN)
set(FMT_HEADERS ${FMT_HEADERS} posix.h)
set(FMT_SOURCES ${FMT_SOURCES} posix.cc)
endif ()
-add_library(fmt ${FMT_SOURCES} ${FMT_HEADERS} ../ChangeLog.rst)
-
-option(FMT_CPPFORMAT "Build cppformat library for backward compatibility." OFF)
-if (FMT_CPPFORMAT)
- message(WARNING "The cppformat library is deprecated, use fmt instead.")
- add_library(cppformat ${FMT_SOURCES} ${FMT_HEADERS})
-endif ()
+add_library(fmt ${FMT_SOURCES} ${FMT_HEADERS} ../README.rst ../ChangeLog.rst)
+add_library(fmt::fmt ALIAS fmt)
# Starting with cmake 3.1 the CXX_STANDARD property can be used instead.
-target_compile_options(fmt PUBLIC ${CPP11_FLAG})
+# Note: Don't make -std=c++11 public or interface, since it breaks projects
+# that use C++14.
+target_compile_options(fmt PRIVATE ${CPP11_FLAG})
if (FMT_PEDANTIC)
target_compile_options(fmt PRIVATE ${PEDANTIC_COMPILE_FLAGS})
endif ()
@@ -40,6 +38,7 @@ endif ()
# additionally define a header only library when cmake is new enough
if (CMAKE_VERSION VERSION_GREATER 3.1.0 OR CMAKE_VERSION VERSION_EQUAL 3.1.0)
add_library(fmt-header-only INTERFACE)
+ add_library(fmt::fmt-header-only ALIAS fmt-header-only)
target_compile_definitions(fmt-header-only INTERFACE FMT_HEADER_ONLY=1)
@@ -50,8 +49,9 @@ endif ()
# Install targets.
if (FMT_INSTALL)
+ include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
- set(FMT_CMAKE_DIR lib/cmake/fmt CACHE STRING
+ set(FMT_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/fmt CACHE STRING
"Installation directory for cmake files, relative to ${CMAKE_INSTALL_PREFIX}.")
set(version_config ${PROJECT_BINARY_DIR}/fmt-config-version.cmake)
set(project_config ${PROJECT_BINARY_DIR}/fmt-config.cmake)
@@ -62,9 +62,12 @@ if (FMT_INSTALL)
set(INSTALL_TARGETS ${INSTALL_TARGETS} fmt-header-only)
endif ()
- set(FMT_LIB_DIR lib CACHE STRING
+ set(FMT_LIB_DIR ${CMAKE_INSTALL_LIBDIR} CACHE STRING
"Installation directory for libraries, relative to ${CMAKE_INSTALL_PREFIX}.")
+ set(FMT_INC_DIR ${CMAKE_INSTALL_INCLUDEDIR}/fmt CACHE STRING
+ "Installation directory for include files, relative to ${CMAKE_INSTALL_PREFIX}.")
+
# Generate the version, config and target files into the build directory.
write_basic_package_version_file(
${version_config}
@@ -74,20 +77,18 @@ if (FMT_INSTALL)
${PROJECT_SOURCE_DIR}/support/cmake/fmt-config.cmake.in
${project_config}
INSTALL_DESTINATION ${FMT_CMAKE_DIR})
- export(TARGETS ${INSTALL_TARGETS}
+ export(TARGETS ${INSTALL_TARGETS} NAMESPACE fmt::
FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake)
# Install version, config and target files.
install(
FILES ${project_config} ${version_config}
DESTINATION ${FMT_CMAKE_DIR})
- install(EXPORT ${targets_export_name} DESTINATION ${FMT_CMAKE_DIR})
+ install(EXPORT ${targets_export_name} DESTINATION ${FMT_CMAKE_DIR}
+ NAMESPACE fmt::)
# Install the library and headers.
install(TARGETS ${INSTALL_TARGETS} EXPORT ${targets_export_name}
DESTINATION ${FMT_LIB_DIR})
- install(FILES ${FMT_HEADERS} DESTINATION include/fmt)
- if (FMT_CPPFORMAT)
- install(TARGETS cppformat DESTINATION ${FMT_LIB_DIR})
- endif ()
+ install(FILES ${FMT_HEADERS} DESTINATION ${FMT_INC_DIR})
endif ()
diff --git a/vendor/fmt-4.1.0/fmt/container.h b/vendor/fmt-4.1.0/fmt/container.h
new file mode 100644
index 00000000..cb6303fb
--- /dev/null
+++ b/vendor/fmt-4.1.0/fmt/container.h
@@ -0,0 +1,82 @@
+/*
+ Formatting library for C++ - standard container utilities
+
+ Copyright (c) 2012 - 2016, Victor Zverovich
+ All rights reserved.
+
+ For the license information refer to format.h.
+ */
+
+#ifndef FMT_CONTAINER_H_
+#define FMT_CONTAINER_H_
+
+#include "format.h"
+
+namespace fmt {
+
+namespace internal {
+
+/**
+ \rst
+ A "buffer" that appends data to a standard container (e.g. typically a
+ ``std::vector`` or ``std::basic_string``).
+ \endrst
+ */
+template <typename Container>
+class ContainerBuffer : public Buffer<typename Container::value_type> {
+ private:
+ Container& container_;
+
+ protected:
+ virtual void grow(std::size_t size) FMT_OVERRIDE {
+ container_.resize(size);
+ this->ptr_ = &container_[0];
+ this->capacity_ = size;
+ }
+
+ public:
+ explicit ContainerBuffer(Container& container) : container_(container) {
+ this->size_ = container_.size();
+ if (this->size_ > 0) {
+ this->ptr_ = &container_[0];
+ this->capacity_ = this->size_;
+ }
+ }
+};
+} // namespace internal
+
+/**
+ \rst
+ This class template provides operations for formatting and appending data
+ to a standard *container* like ``std::vector`` or ``std::basic_string``.
+
+ **Example**::
+
+ void vecformat(std::vector<char>& dest, fmt::BasicCStringRef<char> format,
+ fmt::ArgList args) {
+ fmt::BasicContainerWriter<std::vector<char> > appender(dest);
+ appender.write(format, args);
+ }
+ FMT_VARIADIC(void, vecformat, std::vector<char>&,
+ fmt::BasicCStringRef<char>);
+ \endrst
+ */
+template <class Container>
+class BasicContainerWriter
+ : public BasicWriter<typename Container::value_type> {
+ private:
+ internal::ContainerBuffer<Container> buffer_;
+
+ public:
+ /**
+ \rst
+ Constructs a :class:`fmt::BasicContainerWriter` object.
+ \endrst
+ */
+ explicit BasicContainerWriter(Container& dest)
+ : BasicWriter<typename Container::value_type>(buffer_), buffer_(dest) {}
+};
+
+} // namespace fmt
+
+#endif // FMT_CONTAINER_H_
diff --git a/vendor/fmt-4.1.0/fmt/format.cc b/vendor/fmt-4.1.0/fmt/format.cc
new file mode 100644
index 00000000..2d236bc6
--- /dev/null
+++ b/vendor/fmt-4.1.0/fmt/format.cc
@@ -0,0 +1,495 @@
+/*
+ Formatting library for C++
+
+ Copyright (c) 2012 - 2016, Victor Zverovich
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "format.h"
+
+#include <string.h>
+
+#include <cctype>
+#include <cerrno>
+#include <climits>
+#include <cmath>
+#include <cstdarg>
+#include <cstddef> // for std::ptrdiff_t
+
+#if defined(_WIN32) && defined(__MINGW32__)
+# include <cstring>
+#endif
+
+#if FMT_USE_WINDOWS_H
+# if !defined(FMT_HEADER_ONLY) && !defined(WIN32_LEAN_AND_MEAN)
+# define WIN32_LEAN_AND_MEAN
+# endif
+# if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
+# include <windows.h>
+# else
+# define NOMINMAX
+# include <windows.h>
+# undef NOMINMAX
+# endif
+#endif
+
+#if FMT_EXCEPTIONS
+# define FMT_TRY try
+# define FMT_CATCH(x) catch (x)
+#else
+# define FMT_TRY if (true)
+# define FMT_CATCH(x) if (false)
+#endif
+
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable: 4127) // conditional expression is constant
+# pragma warning(disable: 4702) // unreachable code
+// Disable deprecation warning for strerror. The latter is not called but
+// MSVC fails to detect it.
+# pragma warning(disable: 4996)
+#endif
+
+// Dummy implementations of strerror_r and strerror_s called if corresponding
+// system functions are not available.
+FMT_MAYBE_UNUSED
+static inline fmt::internal::Null<> strerror_r(int, char *, ...) {
+ return fmt::internal::Null<>();
+}
+FMT_MAYBE_UNUSED
+static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) {
+ return fmt::internal::Null<>();
+}
+
+namespace fmt {
+
+FMT_FUNC internal::RuntimeError::~RuntimeError() FMT_DTOR_NOEXCEPT {}
+FMT_FUNC FormatError::~FormatError() FMT_DTOR_NOEXCEPT {}
+FMT_FUNC SystemError::~SystemError() FMT_DTOR_NOEXCEPT {}
+
+namespace {
+
+#ifndef _MSC_VER
+# define FMT_SNPRINTF snprintf
+#else // _MSC_VER
+inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
+ va_end(args);
+ return result;
+}
+# define FMT_SNPRINTF fmt_snprintf
+#endif // _MSC_VER
+
+#if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
+# define FMT_SWPRINTF snwprintf
+#else
+# define FMT_SWPRINTF swprintf
+#endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
+
+const char RESET_COLOR[] = "\x1b[0m";
+
+typedef void (*FormatFunc)(Writer &, int, StringRef);
+
+// Portable thread-safe version of strerror.
+// Sets buffer to point to a string describing the error code.
+// This can be either a pointer to a string stored in buffer,
+// or a pointer to some static immutable string.
+// Returns one of the following values:
+// 0 - success
+// ERANGE - buffer is not large enough to store the error message
+// other - failure
+// Buffer should be at least of size 1.
+int safe_strerror(
+ int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
+ FMT_ASSERT(buffer != FMT_NULL && buffer_size != 0, "invalid buffer");
+
+ class StrError {
+ private:
+ int error_code_;
+ char *&buffer_;
+ std::size_t buffer_size_;
+
+ // A noop assignment operator to avoid bogus warnings.
+ void operator=(const StrError &) {}
+
+ // Handle the result of XSI-compliant version of strerror_r.
+ int handle(int result) {
+ // glibc versions before 2.13 return result in errno.
+ return result == -1 ? errno : result;
+ }
+
+ // Handle the result of GNU-specific version of strerror_r.
+ int handle(char *message) {
+ // If the buffer is full then the message is probably truncated.
+ if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
+ return ERANGE;
+ buffer_ = message;
+ return 0;
+ }
+
+ // Handle the case when strerror_r is not available.
+ int handle(internal::Null<>) {
+ return fallback(strerror_s(buffer_, buffer_size_, error_code_));
+ }
+
+ // Fallback to strerror_s when strerror_r is not available.
+ int fallback(int result) {
+ // If the buffer is full then the message is probably truncated.
+ return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
+ ERANGE : result;
+ }
+
+#ifdef __c2__
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
+ // Fallback to strerror if strerror_r and strerror_s are not available.
+ int fallback(internal::Null<>) {
+ errno = 0;
+ buffer_ = strerror(error_code_);
+ return errno;
+ }
+
+#ifdef __c2__
+# pragma clang diagnostic pop
+#endif
+
+ public:
+ StrError(int err_code, char *&buf, std::size_t buf_size)
+ : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
+
+ int run() {
+ return handle(strerror_r(error_code_, buffer_, buffer_size_));
+ }
+ };
+ return StrError(error_code, buffer, buffer_size).run();
+}
+
+void format_error_code(Writer &out, int error_code,
+ StringRef message) FMT_NOEXCEPT {
+ // Report error code making sure that the output fits into
+ // INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
+ // bad_alloc.
+ out.clear();
+ static const char SEP[] = ": ";
+ static const char ERROR_STR[] = "error ";
+ // Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
+ std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
+ typedef internal::IntTraits<int>::MainType MainType;
+ MainType abs_value = static_cast<MainType>(error_code);
+ if (internal::is_negative(error_code)) {
+ abs_value = 0 - abs_value;
+ ++error_code_size;
+ }
+ error_code_size += internal::count_digits(abs_value);
+ if (message.size() <= internal::INLINE_BUFFER_SIZE - error_code_size)
+ out << message << SEP;
+ out << ERROR_STR << error_code;
+ assert(out.size() <= internal::INLINE_BUFFER_SIZE);
+}
+
+void report_error(FormatFunc func, int error_code,
+ StringRef message) FMT_NOEXCEPT {
+ MemoryWriter full_message;
+ func(full_message, error_code, message);
+ // Use Writer::data instead of Writer::c_str to avoid potential memory
+ // allocation.
+ std::fwrite(full_message.data(), full_message.size(), 1, stderr);
+ std::fputc('\n', stderr);
+}
+} // namespace
+
+FMT_FUNC void SystemError::init(
+ int err_code, CStringRef format_str, ArgList args) {
+ error_code_ = err_code;
+ MemoryWriter w;
+ format_system_error(w, err_code, format(format_str, args));
+ std::runtime_error &base = *this;
+ base = std::runtime_error(w.str());
+}
+
+template <typename T>
+int internal::CharTraits<char>::format_float(
+ char *buffer, std::size_t size, const char *format,
+ unsigned width, int precision, T value) {
+ if (width == 0) {
+ return precision < 0 ?
+ FMT_SNPRINTF(buffer, size, format, value) :
+ FMT_SNPRINTF(buffer, size, format, precision, value);
+ }
+ return precision < 0 ?
+ FMT_SNPRINTF(buffer, size, format, width, value) :
+ FMT_SNPRINTF(buffer, size, format, width, precision, value);
+}
+
+template <typename T>
+int internal::CharTraits<wchar_t>::format_float(
+ wchar_t *buffer, std::size_t size, const wchar_t *format,
+ unsigned width, int precision, T value) {
+ if (width == 0) {
+ return precision < 0 ?
+ FMT_SWPRINTF(buffer, size, format, value) :
+ FMT_SWPRINTF(buffer, size, format, precision, value);
+ }
+ return precision < 0 ?
+ FMT_SWPRINTF(buffer, size, format, width, value) :
+ FMT_SWPRINTF(buffer, size, format, width, precision, value);
+}
+
+template <typename T>
+const char internal::BasicData<T>::DIGITS[] =
+ "0001020304050607080910111213141516171819"
+ "2021222324252627282930313233343536373839"
+ "4041424344454647484950515253545556575859"
+ "6061626364656667686970717273747576777879"
+ "8081828384858687888990919293949596979899";
+
+#define FMT_POWERS_OF_10(factor) \
+ factor * 10, \
+ factor * 100, \
+ factor * 1000, \
+ factor * 10000, \
+ factor * 100000, \
+ factor * 1000000, \
+ factor * 10000000, \
+ factor * 100000000, \
+ factor * 1000000000
+
+template <typename T>
+const uint32_t internal::BasicData<T>::POWERS_OF_10_32[] = {
+ 0, FMT_POWERS_OF_10(1)
+};
+
+template <typename T>
+const uint64_t internal::BasicData<T>::POWERS_OF_10_64[] = {
+ 0,
+ FMT_POWERS_OF_10(1),
+ FMT_POWERS_OF_10(ULongLong(1000000000)),
+ // Multiply several constants instead of using a single long long constant
+ // to avoid warnings about C++98 not supporting long long.
+ ULongLong(1000000000) * ULongLong(1000000000) * 10
+};
+
+FMT_FUNC void internal::report_unknown_type(char code, const char *type) {
+ (void)type;
+ if (std::isprint(static_cast<unsigned char>(code))) {
+ FMT_THROW(FormatError(
+ format("unknown format code '{}' for {}", code, type)));
+ }
+ FMT_THROW(FormatError(
+ format("unknown format code '\\x{:02x}' for {}",
+ static_cast<unsigned>(code), type)));
+}
+
+#if FMT_USE_WINDOWS_H
+
+FMT_FUNC internal::UTF8ToUTF16::UTF8ToUTF16(StringRef s) {
+ static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16";
+ if (s.size() > INT_MAX)
+ FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG));
+ int s_size = static_cast<int>(s.size());
+ int length = MultiByteToWideChar(
+ CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, FMT_NULL, 0);
+ if (length == 0)
+ FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
+ buffer_.resize(length + 1);
+ length = MultiByteToWideChar(
+ CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length);
+ if (length == 0)
+ FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
+ buffer_[length] = 0;
+}
+
+FMT_FUNC internal::UTF16ToUTF8::UTF16ToUTF8(WStringRef s) {
+ if (int error_code = convert(s)) {
+ FMT_THROW(WindowsError(error_code,
+ "cannot convert string from UTF-16 to UTF-8"));
+ }
+}
+
+FMT_FUNC int internal::UTF16ToUTF8::convert(WStringRef s) {
+ if (s.size() > INT_MAX)
+ return ERROR_INVALID_PARAMETER;
+ int s_size = static_cast<int>(s.size());
+ int length = WideCharToMultiByte(
+ CP_UTF8, 0, s.data(), s_size, FMT_NULL, 0, FMT_NULL, FMT_NULL);
+ if (length == 0)
+ return GetLastError();
+ buffer_.resize(length + 1);
+ length = WideCharToMultiByte(
+ CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, FMT_NULL, FMT_NULL);
+ if (length == 0)
+ return GetLastError();
+ buffer_[length] = 0;
+ return 0;
+}
+
+FMT_FUNC void WindowsError::init(
+ int err_code, CStringRef format_str, ArgList args) {
+ error_code_ = err_code;
+ MemoryWriter w;
+ internal::format_windows_error(w, err_code, format(format_str, args));
+ std::runtime_error &base = *this;
+ base = std::runtime_error(w.str());
+}
+
+FMT_FUNC void internal::format_windows_error(
+ Writer &out, int error_code, StringRef message) FMT_NOEXCEPT {
+ FMT_TRY {
+ MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer;
+ buffer.resize(INLINE_BUFFER_SIZE);
+ for (;;) {
+ wchar_t *system_message = &buffer[0];
+ int result = FormatMessageW(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ FMT_NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ system_message, static_cast<uint32_t>(buffer.size()), FMT_NULL);
+ if (result != 0) {
+ UTF16ToUTF8 utf8_message;
+ if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
+ out << message << ": " << utf8_message;
+ return;
+ }
+ break;
+ }
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ break; // Can't get error message, report error code instead.
+ buffer.resize(buffer.size() * 2);
+ }
+ } FMT_CATCH(...) {}
+ fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
+}
+
+#endif // FMT_USE_WINDOWS_H
+
+FMT_FUNC void format_system_error(
+ Writer &out, int error_code, StringRef message) FMT_NOEXCEPT {
+ FMT_TRY {
+ internal::MemoryBuffer<char, internal::INLINE_BUFFER_SIZE> buffer;
+ buffer.resize(internal::INLINE_BUFFER_SIZE);
+ for (;;) {
+ char *system_message = &buffer[0];
+ int result = safe_strerror(error_code, system_message, buffer.size());
+ if (result == 0) {
+ out << message << ": " << system_message;
+ return;
+ }
+ if (result != ERANGE)
+ break; // Can't get error message, report error code instead.
+ buffer.resize(buffer.size() * 2);
+ }
+ } FMT_CATCH(...) {}
+ fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
+}
+
+template <typename Char>
+void internal::FixedBuffer<Char>::grow(std::size_t) {
+ FMT_THROW(std::runtime_error("buffer overflow"));
+}
+
+FMT_FUNC internal::Arg internal::FormatterBase::do_get_arg(
+ unsigned arg_index, const char *&error) {
+ internal::Arg arg = args_[arg_index];
+ switch (arg.type) {
+ case internal::Arg::NONE:
+ error = "argument index out of range";
+ break;
+ case internal::Arg::NAMED_ARG:
+ arg = *static_cast<const internal::Arg*>(arg.pointer);
+ break;
+ default:
+ /*nothing*/;
+ }
+ return arg;
+}
+
+FMT_FUNC void report_system_error(
+ int error_code, fmt::StringRef message) FMT_NOEXCEPT {
+ // 'fmt::' is for bcc32.
+ report_error(format_system_error, error_code, message);
+}
+
+#if FMT_USE_WINDOWS_H
+FMT_FUNC void report_windows_error(
+ int error_code, fmt::StringRef message) FMT_NOEXCEPT {
+ // 'fmt::' is for bcc32.
+ report_error(internal::format_windows_error, error_code, message);
+}
+#endif
+
+FMT_FUNC void print(std::FILE *f, CStringRef format_str, ArgList args) {
+ MemoryWriter w;
+ w.write(format_str, args);
+ std::fwrite(w.data(), 1, w.size(), f);
+}
+
+FMT_FUNC void print(CStringRef format_str, ArgList args) {
+ print(stdout, format_str, args);
+}
+
+FMT_FUNC void print_colored(Color c, CStringRef format, ArgList args) {
+ char escape[] = "\x1b[30m";
+ escape[3] = static_cast<char>('0' + c);
+ std::fputs(escape, stdout);
+ print(format, args);
+ std::fputs(RESET_COLOR, stdout);
+}
+
+#ifndef FMT_HEADER_ONLY
+
+template struct internal::BasicData<void>;
+
+// Explicit instantiations for char.
+
+template void internal::FixedBuffer<char>::grow(std::size_t);
+
+template FMT_API int internal::CharTraits<char>::format_float(
+ char *buffer, std::size_t size, const char *format,
+ unsigned width, int precision, double value);
+
+template FMT_API int internal::CharTraits<char>::format_float(
+ char *buffer, std::size_t size, const char *format,
+ unsigned width, int precision, long double value);
+
+// Explicit instantiations for wchar_t.
+
+template void internal::FixedBuffer<wchar_t>::grow(std::size_t);
+
+template FMT_API int internal::CharTraits<wchar_t>::format_float(
+ wchar_t *buffer, std::size_t size, const wchar_t *format,
+ unsigned width, int precision, double value);
+
+template FMT_API int internal::CharTraits<wchar_t>::format_float(
+ wchar_t *buffer, std::size_t size, const wchar_t *format,
+ unsigned width, int precision, long double value);
+
+#endif // FMT_HEADER_ONLY
+
+} // namespace fmt
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
diff --git a/vendor/fmt-3.0.1/fmt/format.h b/vendor/fmt-4.1.0/fmt/format.h
index f8ce147c..561a9e07 100644
--- a/vendor/fmt-3.0.1/fmt/format.h
+++ b/vendor/fmt-4.1.0/fmt/format.h
@@ -28,6 +28,7 @@
#ifndef FMT_FORMAT_H_
#define FMT_FORMAT_H_
+#define FMT_INCLUDE
#include <cassert>
#include <clocale>
#include <cmath>
@@ -38,9 +39,27 @@
#include <stdexcept>
#include <string>
#include <vector>
-#include <utility>
+#include <utility> // for std::pair
+#undef FMT_INCLUDE
-#ifdef _SECURE_SCL
+// The fmt library version in the form major * 10000 + minor * 100 + patch.
+#define FMT_VERSION 40100
+
+#if defined(__has_include)
+# define FMT_HAS_INCLUDE(x) __has_include(x)
+#else
+# define FMT_HAS_INCLUDE(x) 0
+#endif
+
+#if (FMT_HAS_INCLUDE(<string_view>) && __cplusplus > 201402L) || \
+ (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910)
+# include <string_view>
+# define FMT_HAS_STRING_VIEW 1
+#else
+# define FMT_HAS_STRING_VIEW 0
+#endif
+
+#if defined _SECURE_SCL && _SECURE_SCL
# define FMT_SECURE_SCL _SECURE_SCL
#else
# define FMT_SECURE_SCL 0
@@ -94,7 +113,9 @@ typedef __int64 intmax_t;
# define FMT_HAS_GXX_CXX11 1
# endif
#else
+# define FMT_GCC_VERSION 0
# define FMT_GCC_EXTENSION
+# define FMT_HAS_GXX_CXX11 0
#endif
#if defined(__INTEL_COMPILER)
@@ -104,6 +125,7 @@ typedef __int64 intmax_t;
#endif
#if defined(__clang__) && !defined(FMT_ICC_VERSION)
+# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
# pragma clang diagnostic ignored "-Wpadded"
@@ -131,6 +153,32 @@ typedef __int64 intmax_t;
# define FMT_HAS_CPP_ATTRIBUTE(x) 0
#endif
+#if FMT_HAS_CPP_ATTRIBUTE(maybe_unused)
+# define FMT_HAS_CXX17_ATTRIBUTE_MAYBE_UNUSED
+// VC++ 1910 support /std: option and that will set _MSVC_LANG macro
+// Clang with Microsoft CodeGen doesn't define _MSVC_LANG macro
+#elif defined(_MSVC_LANG) && _MSVC_LANG > 201402 && _MSC_VER >= 1910
+# define FMT_HAS_CXX17_ATTRIBUTE_MAYBE_UNUSED
+#endif
+
+#ifdef FMT_HAS_CXX17_ATTRIBUTE_MAYBE_UNUSED
+# define FMT_MAYBE_UNUSED [[maybe_unused]]
+// g++/clang++ also support [[gnu::unused]]. However, we don't use it.
+#elif defined(__GNUC__)
+# define FMT_MAYBE_UNUSED __attribute__((unused))
+#else
+# define FMT_MAYBE_UNUSED
+#endif
+
+// Use the compiler's attribute noreturn
+#if defined(__MINGW32__) || defined(__MINGW64__)
+# define FMT_NORETURN __attribute__((noreturn))
+#elif FMT_HAS_CPP_ATTRIBUTE(noreturn) && __cplusplus >= 201103L
+# define FMT_NORETURN [[noreturn]]
+#else
+# define FMT_NORETURN
+#endif
+
#ifndef FMT_USE_VARIADIC_TEMPLATES
// Variadic templates are available in GCC since version 4.4
// (http://gcc.gnu.org/projects/cxx0x.html) and in Visual C++
@@ -152,8 +200,10 @@ typedef __int64 intmax_t;
# endif
#endif
-#if FMT_USE_RVALUE_REFERENCES
-# include <utility> // for std::move
+#if __cplusplus >= 201103L || FMT_MSC_VER >= 1700
+# define FMT_USE_ALLOCATOR_TRAITS 1
+#else
+# define FMT_USE_ALLOCATOR_TRAITS 0
#endif
// Check if exceptions are disabled.
@@ -180,22 +230,32 @@ typedef __int64 intmax_t;
# define FMT_USE_NOEXCEPT 0
#endif
-#ifndef FMT_NOEXCEPT
-# if FMT_EXCEPTIONS
-# if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
+#if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
(FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \
FMT_MSC_VER >= 1900
-# define FMT_NOEXCEPT noexcept
-# else
-# define FMT_NOEXCEPT throw()
-# endif
+# define FMT_DETECTED_NOEXCEPT noexcept
+#else
+# define FMT_DETECTED_NOEXCEPT throw()
+#endif
+
+#ifndef FMT_NOEXCEPT
+# if FMT_EXCEPTIONS
+# define FMT_NOEXCEPT FMT_DETECTED_NOEXCEPT
# else
# define FMT_NOEXCEPT
# endif
#endif
+// This is needed because GCC still uses throw() in its headers when exceptions
+// are disabled.
+#if FMT_GCC_VERSION
+# define FMT_DTOR_NOEXCEPT FMT_DETECTED_NOEXCEPT
+#else
+# define FMT_DTOR_NOEXCEPT FMT_NOEXCEPT
+#endif
+
#ifndef FMT_OVERRIDE
-# if FMT_USE_OVERRIDE || FMT_HAS_FEATURE(cxx_override) || \
+# if (defined(FMT_USE_OVERRIDE) && FMT_USE_OVERRIDE) || FMT_HAS_FEATURE(cxx_override) || \
(FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \
FMT_MSC_VER >= 1900
# define FMT_OVERRIDE override
@@ -204,6 +264,15 @@ typedef __int64 intmax_t;
# endif
#endif
+#ifndef FMT_NULL
+# if FMT_HAS_FEATURE(cxx_nullptr) || \
+ (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \
+ FMT_MSC_VER >= 1600
+# define FMT_NULL nullptr
+# else
+# define FMT_NULL NULL
+# endif
+#endif
// A macro to disallow the copy constructor and operator= functions
// This should be used in the private: declarations for a class
@@ -224,40 +293,75 @@ typedef __int64 intmax_t;
TypeName& operator=(const TypeName&)
#endif
+#ifndef FMT_USE_DEFAULTED_FUNCTIONS
+# define FMT_USE_DEFAULTED_FUNCTIONS 0
+#endif
+
+#ifndef FMT_DEFAULTED_COPY_CTOR
+# if FMT_USE_DEFAULTED_FUNCTIONS || FMT_HAS_FEATURE(cxx_defaulted_functions) || \
+ (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800
+# define FMT_DEFAULTED_COPY_CTOR(TypeName) \
+ TypeName(const TypeName&) = default;
+# else
+# define FMT_DEFAULTED_COPY_CTOR(TypeName)
+# endif
+#endif
+
#ifndef FMT_USE_USER_DEFINED_LITERALS
// All compilers which support UDLs also support variadic templates. This
// makes the fmt::literals implementation easier. However, an explicit check
// for variadic templates is added here just in case.
// For Intel's compiler both it and the system gcc/msc must support UDLs.
-# define FMT_USE_USER_DEFINED_LITERALS \
- FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES && \
+# if FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES && \
(FMT_HAS_FEATURE(cxx_user_literals) || \
(FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900) && \
(!defined(FMT_ICC_VERSION) || FMT_ICC_VERSION >= 1500)
+# define FMT_USE_USER_DEFINED_LITERALS 1
+# else
+# define FMT_USE_USER_DEFINED_LITERALS 0
+# endif
+#endif
+
+#ifndef FMT_USE_EXTERN_TEMPLATES
+# define FMT_USE_EXTERN_TEMPLATES \
+ (FMT_CLANG_VERSION >= 209 || (FMT_GCC_VERSION >= 303 && FMT_HAS_GXX_CXX11))
+#endif
+
+#ifdef FMT_HEADER_ONLY
+// If header only do not use extern templates.
+# undef FMT_USE_EXTERN_TEMPLATES
+# define FMT_USE_EXTERN_TEMPLATES 0
#endif
#ifndef FMT_ASSERT
# define FMT_ASSERT(condition, message) assert((condition) && message)
#endif
-#if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz)
-# define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
-#endif
+// __builtin_clz is broken in clang with Microsoft CodeGen:
+// https://github.com/fmtlib/fmt/issues/519
+#ifndef _MSC_VER
+# if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz)
+# define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
+# endif
-#if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll)
-# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
+# if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll)
+# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
+# endif
#endif
// Some compilers masquerade as both MSVC and GCC-likes or
// otherwise support __builtin_clz and __builtin_clzll, so
// only define FMT_BUILTIN_CLZ using the MSVC intrinsics
// if the clz and clzll builtins are not available.
-#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL)
+#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(_MANAGED)
# include <intrin.h> // _BitScanReverse, _BitScanReverse64
namespace fmt {
namespace internal {
-# pragma intrinsic(_BitScanReverse)
+// avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning
+# ifndef __clang__
+# pragma intrinsic(_BitScanReverse)
+# endif
inline uint32_t clz(uint32_t x) {
unsigned long r = 0;
_BitScanReverse(&r, x);
@@ -271,7 +375,8 @@ inline uint32_t clz(uint32_t x) {
}
# define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n)
-# ifdef _WIN64
+// avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning
+# if defined(_WIN64) && !defined(__clang__)
# pragma intrinsic(_BitScanReverse64)
# endif
@@ -360,8 +465,10 @@ class numeric_limits<fmt::internal::DummyInt> :
// Portable version of signbit.
static bool isnegative(double x) {
using namespace fmt::internal;
- if (const_check(sizeof(signbit(x)) == sizeof(int)))
+ if (const_check(sizeof(signbit(x)) == sizeof(bool) ||
+ sizeof(signbit(x)) == sizeof(int))) {
return signbit(x) != 0;
+ }
if (x < 0) return true;
if (!isnotanumber(x)) return false;
int dec = 0, sign = 0;
@@ -392,13 +499,19 @@ typedef BasicWriter<wchar_t> WWriter;
template <typename Char>
class ArgFormatter;
+struct FormatSpec;
+
+template <typename Impl, typename Char, typename Spec = fmt::FormatSpec>
+class BasicPrintfArgFormatter;
+
template <typename CharType,
typename ArgFormatter = fmt::ArgFormatter<CharType> >
class BasicFormatter;
/**
\rst
- A string reference. It can be constructed from a C string or ``std::string``.
+ A string reference. It can be constructed from a C string or
+ ``std::basic_string``.
You can use one of the following typedefs for common character types:
@@ -441,12 +554,34 @@ class BasicStringRef {
/**
\rst
- Constructs a string reference from an ``std::string`` object.
+ Constructs a string reference from a ``std::basic_string`` object.
\endrst
*/
- BasicStringRef(const std::basic_string<Char> &s)
+ template <typename Allocator>
+ BasicStringRef(
+ const std::basic_string<Char, std::char_traits<Char>, Allocator> &s)
: data_(s.c_str()), size_(s.size()) {}
+#if FMT_HAS_STRING_VIEW
+ /**
+ \rst
+ Constructs a string reference from a ``std::basic_string_view`` object.
+ \endrst
+ */
+ BasicStringRef(
+ const std::basic_string_view<Char, std::char_traits<Char>> &s)
+ : data_(s.data()), size_(s.size()) {}
+
+ /**
+ \rst
+ Converts a string reference to an ``std::string_view`` object.
+ \endrst
+ */
+ explicit operator std::basic_string_view<Char>() const FMT_NOEXCEPT {
+ return std::basic_string_view<Char>(data_, size_);
+ }
+#endif
+
/**
\rst
Converts a string reference to an ``std::string`` object.
@@ -497,7 +632,7 @@ typedef BasicStringRef<wchar_t> WStringRef;
/**
\rst
A reference to a null terminated string. It can be constructed from a C
- string or ``std::string``.
+ string or ``std::basic_string``.
You can use one of the following typedefs for common character types:
@@ -530,10 +665,13 @@ class BasicCStringRef {
/**
\rst
- Constructs a string reference from an ``std::string`` object.
+ Constructs a string reference from a ``std::basic_string`` object.
\endrst
*/
- BasicCStringRef(const std::basic_string<Char> &s) : data_(s.c_str()) {}
+ template <typename Allocator>
+ BasicCStringRef(
+ const std::basic_string<Char, std::char_traits<Char>, Allocator> &s)
+ : data_(s.c_str()) {}
/** Returns the pointer to a C string. */
const Char *c_str() const { return data_; }
@@ -547,7 +685,8 @@ class FormatError : public std::runtime_error {
public:
explicit FormatError(CStringRef message)
: std::runtime_error(message.c_str()) {}
- ~FormatError() throw();
+ FormatError(const FormatError &ferr) : std::runtime_error(ferr) {}
+ FMT_API ~FormatError() FMT_DTOR_NOEXCEPT FMT_OVERRIDE;
};
namespace internal {
@@ -605,7 +744,7 @@ class Buffer {
std::size_t size_;
std::size_t capacity_;
- Buffer(T *ptr = 0, std::size_t capacity = 0)
+ Buffer(T *ptr = FMT_NULL, std::size_t capacity = 0)
: ptr_(ptr), size_(0), capacity_(capacity) {}
/**
@@ -663,7 +802,8 @@ class Buffer {
template <typename T>
template <typename U>
void Buffer<T>::append(const U *begin, const U *end) {
- std::size_t new_size = size_ + internal::to_unsigned(end - begin);
+ FMT_ASSERT(end >= begin, "negative value");
+ std::size_t new_size = size_ + static_cast<std::size_t>(end - begin);
if (new_size > capacity_)
grow(new_size);
std::uninitialized_copy(begin, end,
@@ -691,7 +831,7 @@ class MemoryBuffer : private Allocator, public Buffer<T> {
public:
explicit MemoryBuffer(const Allocator &alloc = Allocator())
: Allocator(alloc), Buffer<T>(data_, SIZE) {}
- ~MemoryBuffer() { deallocate(); }
+ ~MemoryBuffer() FMT_OVERRIDE { deallocate(); }
#if FMT_USE_RVALUE_REFERENCES
private:
@@ -735,7 +875,12 @@ void MemoryBuffer<T, SIZE, Allocator>::grow(std::size_t size) {
std::size_t new_capacity = this->capacity_ + this->capacity_ / 2;
if (size > new_capacity)
new_capacity = size;
- T *new_ptr = this->allocate(new_capacity);
+#if FMT_USE_ALLOCATOR_TRAITS
+ T *new_ptr =
+ std::allocator_traits<Allocator>::allocate(*this, new_capacity, FMT_NULL);
+#else
+ T *new_ptr = this->allocate(new_capacity, FMT_NULL);
+#endif
// The following code doesn't throw, so the raw pointer above doesn't leak.
std::uninitialized_copy(this->ptr_, this->ptr_ + this->size_,
make_ptr(new_ptr, new_capacity));
@@ -757,7 +902,7 @@ class FixedBuffer : public fmt::Buffer<Char> {
FixedBuffer(Char *array, std::size_t size) : fmt::Buffer<Char>(array, size) {}
protected:
- FMT_API void grow(std::size_t size);
+ FMT_API void grow(std::size_t size) FMT_OVERRIDE;
};
template <typename Char>
@@ -789,6 +934,15 @@ class CharTraits<char> : public BasicCharTraits<char> {
const char *format, unsigned width, int precision, T value);
};
+#if FMT_USE_EXTERN_TEMPLATES
+extern template int CharTraits<char>::format_float<double>
+ (char *buffer, std::size_t size,
+ const char* format, unsigned width, int precision, double value);
+extern template int CharTraits<char>::format_float<long double>
+ (char *buffer, std::size_t size,
+ const char* format, unsigned width, int precision, long double value);
+#endif
+
template <>
class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> {
public:
@@ -800,6 +954,15 @@ class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> {
const wchar_t *format, unsigned width, int precision, T value);
};
+#if FMT_USE_EXTERN_TEMPLATES
+extern template int CharTraits<wchar_t>::format_float<double>
+ (wchar_t *buffer, std::size_t size,
+ const wchar_t* format, unsigned width, int precision, double value);
+extern template int CharTraits<wchar_t>::format_float<long double>
+ (wchar_t *buffer, std::size_t size,
+ const wchar_t* format, unsigned width, int precision, long double value);
+#endif
+
// Checks if a number is negative - used to avoid warnings.
template <bool IsSigned>
struct SignChecker {
@@ -835,7 +998,7 @@ struct IntTraits {
TypeSelector<std::numeric_limits<T>::digits <= 32>::Type MainType;
};
-FMT_API void report_unknown_type(char code, const char *type);
+FMT_API FMT_NORETURN void report_unknown_type(char code, const char *type);
// Static data is placed in this class template to allow header-only
// configuration.
@@ -846,13 +1009,7 @@ struct FMT_API BasicData {
static const char DIGITS[];
};
-#ifndef FMT_USE_EXTERN_TEMPLATES
-// Clang doesn't have a feature check for extern templates so we check
-// for variadic templates which were introduced in the same version.
-# define FMT_USE_EXTERN_TEMPLATES (__clang__ && FMT_USE_VARIADIC_TEMPLATES)
-#endif
-
-#if FMT_USE_EXTERN_TEMPLATES && !defined(FMT_HEADER_ONLY)
+#if FMT_USE_EXTERN_TEMPLATES
extern template struct BasicData<void>;
#endif
@@ -950,7 +1107,8 @@ inline void format_decimal(Char *buffer, UInt value, unsigned num_digits,
template <typename UInt, typename Char>
inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) {
- return format_decimal(buffer, value, num_digits, NoThousandsSep());
+ format_decimal(buffer, value, num_digits, NoThousandsSep());
+ return;
}
#ifndef _WIN32
@@ -1000,9 +1158,6 @@ FMT_API void format_windows_error(fmt::Writer &out, int error_code,
fmt::StringRef message) FMT_NOEXCEPT;
#endif
-FMT_API void format_system_error(fmt::Writer &out, int error_code,
- fmt::StringRef message) FMT_NOEXCEPT;
-
// A formatting argument value.
struct Value {
template <typename Char>
@@ -1052,6 +1207,8 @@ struct Arg : Value {
template <typename Char>
struct NamedArg;
+template <typename Char, typename T>
+struct NamedArgWithType;
template <typename T = void>
struct Null {};
@@ -1080,17 +1237,17 @@ T &get();
Yes &convert(fmt::ULongLong);
No &convert(...);
-template<typename T, bool ENABLE_CONVERSION>
+template <typename T, bool ENABLE_CONVERSION>
struct ConvertToIntImpl {
enum { value = ENABLE_CONVERSION };
};
-template<typename T, bool ENABLE_CONVERSION>
+template <typename T, bool ENABLE_CONVERSION>
struct ConvertToIntImpl2 {
enum { value = false };
};
-template<typename T>
+template <typename T>
struct ConvertToIntImpl2<T, true> {
enum {
// Don't convert numeric types.
@@ -1098,9 +1255,11 @@ struct ConvertToIntImpl2<T, true> {
};
};
-template<typename T>
+template <typename T>
struct ConvertToInt {
- enum { enable_conversion = sizeof(convert(get<T>())) == sizeof(Yes) };
+ enum {
+ enable_conversion = sizeof(fmt::internal::convert(get<T>())) == sizeof(Yes)
+ };
enum { value = ConvertToIntImpl2<T, enable_conversion>::value };
};
@@ -1113,26 +1272,29 @@ FMT_DISABLE_CONVERSION_TO_INT(float);
FMT_DISABLE_CONVERSION_TO_INT(double);
FMT_DISABLE_CONVERSION_TO_INT(long double);
-template<bool B, class T = void>
+template <bool B, class T = void>
struct EnableIf {};
-template<class T>
+template <class T>
struct EnableIf<true, T> { typedef T type; };
-template<bool B, class T, class F>
+template <bool B, class T, class F>
struct Conditional { typedef T type; };
-template<class T, class F>
+template <class T, class F>
struct Conditional<false, T, F> { typedef F type; };
// For bcc32 which doesn't understand ! in template arguments.
-template<bool>
+template <bool>
struct Not { enum { value = 0 }; };
-template<>
+template <>
struct Not<false> { enum { value = 1 }; };
-template<typename T, T> struct LConvCheck {
+template <typename T>
+struct FalseType { enum { value = 0 }; };
+
+template <typename T, T> struct LConvCheck {
LConvCheck(int) {}
};
@@ -1147,6 +1309,35 @@ inline StringRef thousands_sep(
inline fmt::StringRef thousands_sep(...) { return ""; }
+#define FMT_CONCAT(a, b) a##b
+
+#if FMT_GCC_VERSION >= 303
+# define FMT_UNUSED __attribute__((unused))
+#else
+# define FMT_UNUSED
+#endif
+
+#ifndef FMT_USE_STATIC_ASSERT
+# define FMT_USE_STATIC_ASSERT 0
+#endif
+
+#if FMT_USE_STATIC_ASSERT || FMT_HAS_FEATURE(cxx_static_assert) || \
+ (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600
+# define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message)
+#else
+# define FMT_CONCAT_(a, b) FMT_CONCAT(a, b)
+# define FMT_STATIC_ASSERT(cond, message) \
+ typedef int FMT_CONCAT_(Assert, __LINE__)[(cond) ? 1 : -1] FMT_UNUSED
+#endif
+
+template <typename Formatter>
+void format_arg(Formatter&, ...) {
+ FMT_STATIC_ASSERT(FalseType<Formatter>::value,
+ "Cannot format argument. To enable the use of ostream "
+ "operator<< include fmt/ostream.h. Otherwise provide "
+ "an overload of format_arg.");
+}
+
// Makes an Arg object from any type.
template <typename Formatter>
class MakeValue : public Arg {
@@ -1174,6 +1365,9 @@ class MakeValue : public Arg {
MakeValue(typename WCharHelper<wchar_t *, Char>::Unsupported);
MakeValue(typename WCharHelper<const wchar_t *, Char>::Unsupported);
MakeValue(typename WCharHelper<const std::wstring &, Char>::Unsupported);
+#if FMT_HAS_STRING_VIEW
+ MakeValue(typename WCharHelper<const std::wstring_view &, Char>::Unsupported);
+#endif
MakeValue(typename WCharHelper<WStringRef, Char>::Unsupported);
void set_string(StringRef str) {
@@ -1190,9 +1384,9 @@ class MakeValue : public Arg {
template <typename T>
static void format_custom_arg(
void *formatter, const void *arg, void *format_str_ptr) {
- format(*static_cast<Formatter*>(formatter),
- *static_cast<const Char**>(format_str_ptr),
- *static_cast<const T*>(arg));
+ format_arg(*static_cast<Formatter*>(formatter),
+ *static_cast<const Char**>(format_str_ptr),
+ *static_cast<const T*>(arg));
}
public:
@@ -1243,6 +1437,20 @@ class MakeValue : public Arg {
FMT_MAKE_VALUE(unsigned char, uint_value, UINT)
FMT_MAKE_VALUE(char, int_value, CHAR)
+#if __cplusplus >= 201103L
+ template <
+ typename T,
+ typename = typename std::enable_if<
+ std::is_enum<T>::value && ConvertToInt<T>::value>::type>
+ MakeValue(T value) { int_value = value; }
+
+ template <
+ typename T,
+ typename = typename std::enable_if<
+ std::is_enum<T>::value && ConvertToInt<T>::value>::type>
+ static uint64_t type(T) { return Arg::INT; }
+#endif
+
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
MakeValue(typename WCharHelper<wchar_t, Char>::Supported value) {
int_value = value;
@@ -1261,6 +1469,9 @@ class MakeValue : public Arg {
FMT_MAKE_VALUE(unsigned char *, ustring.value, CSTRING)
FMT_MAKE_VALUE(const unsigned char *, ustring.value, CSTRING)
FMT_MAKE_STR_VALUE(const std::string &, STRING)
+#if FMT_HAS_STRING_VIEW
+ FMT_MAKE_STR_VALUE(const std::string_view &, STRING)
+#endif
FMT_MAKE_STR_VALUE(StringRef, STRING)
FMT_MAKE_VALUE_(CStringRef, string.value, CSTRING, value.c_str())
@@ -1273,6 +1484,9 @@ class MakeValue : public Arg {
FMT_MAKE_WSTR_VALUE(wchar_t *, WSTRING)
FMT_MAKE_WSTR_VALUE(const wchar_t *, WSTRING)
FMT_MAKE_WSTR_VALUE(const std::wstring &, WSTRING)
+#if FMT_HAS_STRING_VIEW
+ FMT_MAKE_WSTR_VALUE(const std::wstring_view &, WSTRING)
+#endif
FMT_MAKE_WSTR_VALUE(WStringRef, WSTRING)
FMT_MAKE_VALUE(void *, pointer, POINTER)
@@ -1287,23 +1501,22 @@ class MakeValue : public Arg {
}
template <typename T>
- MakeValue(const T &value,
- typename EnableIf<ConvertToInt<T>::value, int>::type = 0) {
- int_value = value;
- }
-
- template <typename T>
- static uint64_t type(const T &) {
- return ConvertToInt<T>::value ? Arg::INT : Arg::CUSTOM;
+ static typename EnableIf<Not<ConvertToInt<T>::value>::value, uint64_t>::type
+ type(const T &) {
+ return Arg::CUSTOM;
}
// Additional template param `Char_` is needed here because make_type always
// uses char.
template <typename Char_>
MakeValue(const NamedArg<Char_> &value) { pointer = &value; }
+ template <typename Char_, typename T>
+ MakeValue(const NamedArgWithType<Char_, T> &value) { pointer = &value; }
template <typename Char_>
static uint64_t type(const NamedArg<Char_> &) { return Arg::NAMED_ARG; }
+ template <typename Char_, typename T>
+ static uint64_t type(const NamedArgWithType<Char_, T> &) { return Arg::NAMED_ARG; }
};
template <typename Formatter>
@@ -1329,16 +1542,20 @@ struct NamedArg : Arg {
: Arg(MakeArg< BasicFormatter<Char> >(value)), name(argname) {}
};
+template <typename Char, typename T>
+struct NamedArgWithType : NamedArg<Char> {
+ NamedArgWithType(BasicStringRef<Char> argname, const T &value)
+ : NamedArg<Char>(argname, value) {}
+};
+
class RuntimeError : public std::runtime_error {
protected:
RuntimeError() : std::runtime_error("") {}
- ~RuntimeError() throw();
+ RuntimeError(const RuntimeError &rerr) : std::runtime_error(rerr) {}
+ FMT_API ~RuntimeError() FMT_DTOR_NOEXCEPT FMT_OVERRIDE;
};
template <typename Char>
-class PrintfArgFormatter;
-
-template <typename Char>
class ArgMap;
} // namespace internal
@@ -1359,10 +1576,7 @@ class ArgList {
};
internal::Arg::Type type(unsigned index) const {
- unsigned shift = index * 4;
- uint64_t mask = 0xf;
- return static_cast<internal::Arg::Type>(
- (types_ & (mask << shift)) >> shift);
+ return type(types_, index);
}
template <typename Char>
@@ -1379,6 +1593,8 @@ class ArgList {
ArgList(ULongLong types, const internal::Arg *args)
: types_(types), args_(args) {}
+ uint64_t types() const { return types_; }
+
/** Returns the argument at specified index. */
internal::Arg operator[](unsigned index) const {
using internal::Arg;
@@ -1404,6 +1620,13 @@ class ArgList {
}
return args_[index];
}
+
+ static internal::Arg::Type type(uint64_t types, unsigned index) {
+ unsigned shift = index * 4;
+ uint64_t mask = 0xf;
+ return static_cast<internal::Arg::Type>(
+ (types & (mask << shift)) >> shift);
+ }
};
#define FMT_DISPATCH(call) static_cast<Impl*>(this)->call
@@ -1588,6 +1811,7 @@ struct TypeSpec : EmptySpec {
int precision() const { return -1; }
bool flag(unsigned) const { return false; }
char type() const { return TYPE; }
+ char type_prefix() const { return TYPE; }
char fill() const { return ' '; }
};
@@ -1623,6 +1847,7 @@ struct AlignTypeSpec : AlignSpec {
bool flag(unsigned) const { return false; }
char type() const { return TYPE; }
+ char type_prefix() const { return TYPE; }
};
// A full format specifier.
@@ -1638,6 +1863,7 @@ struct FormatSpec : AlignSpec {
bool flag(unsigned f) const { return (flags_ & f) != 0; }
int precision() const { return precision_; }
char type() const { return type_; }
+ char type_prefix() const { return type_; }
};
// An integer format specifier.
@@ -1800,24 +2026,69 @@ class ArgMap {
MapType map_;
public:
- FMT_API void init(const ArgList &args);
+ void init(const ArgList &args);
- const internal::Arg* find(const fmt::BasicStringRef<Char> &name) const {
+ const internal::Arg *find(const fmt::BasicStringRef<Char> &name) const {
// The list is unsorted, so just return the first matching name.
for (typename MapType::const_iterator it = map_.begin(), end = map_.end();
it != end; ++it) {
if (it->first == name)
return &it->second;
}
- return 0;
+ return FMT_NULL;
}
};
-template <typename Impl, typename Char>
+template <typename Char>
+void ArgMap<Char>::init(const ArgList &args) {
+ if (!map_.empty())
+ return;
+ typedef internal::NamedArg<Char> NamedArg;
+ const NamedArg *named_arg = FMT_NULL;
+ bool use_values =
+ args.type(ArgList::MAX_PACKED_ARGS - 1) == internal::Arg::NONE;
+ if (use_values) {
+ for (unsigned i = 0;/*nothing*/; ++i) {
+ internal::Arg::Type arg_type = args.type(i);
+ switch (arg_type) {
+ case internal::Arg::NONE:
+ return;
+ case internal::Arg::NAMED_ARG:
+ named_arg = static_cast<const NamedArg*>(args.values_[i].pointer);
+ map_.push_back(Pair(named_arg->name, *named_arg));
+ break;
+ default:
+ /*nothing*/;
+ }
+ }
+ return;
+ }
+ for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) {
+ internal::Arg::Type arg_type = args.type(i);
+ if (arg_type == internal::Arg::NAMED_ARG) {
+ named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
+ map_.push_back(Pair(named_arg->name, *named_arg));
+ }
+ }
+ for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
+ switch (args.args_[i].type) {
+ case internal::Arg::NONE:
+ return;
+ case internal::Arg::NAMED_ARG:
+ named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
+ map_.push_back(Pair(named_arg->name, *named_arg));
+ break;
+ default:
+ /*nothing*/;
+ }
+ }
+}
+
+template <typename Impl, typename Char, typename Spec = fmt::FormatSpec>
class ArgFormatterBase : public ArgVisitor<Impl, void> {
private:
BasicWriter<Char> &writer_;
- FormatSpec &spec_;
+ Spec &spec_;
FMT_DISALLOW_COPY_AND_ASSIGN(ArgFormatterBase);
@@ -1827,9 +2098,12 @@ class ArgFormatterBase : public ArgVisitor<Impl, void> {
writer_.write_int(reinterpret_cast<uintptr_t>(p), spec_);
}
+ // workaround MSVC two-phase lookup issue
+ typedef internal::Arg Arg;
+
protected:
BasicWriter<Char> &writer() { return writer_; }
- FormatSpec &spec() { return spec_; }
+ Spec &spec() { return spec_; }
void write(bool value) {
const char *str_value = value ? "true" : "false";
@@ -1838,12 +2112,14 @@ class ArgFormatterBase : public ArgVisitor<Impl, void> {
}
void write(const char *value) {
- Arg::StringValue<char> str = {value, value != 0 ? std::strlen(value) : 0};
+ Arg::StringValue<char> str = {value, value ? std::strlen(value) : 0};
writer_.write_str(str, spec_);
}
public:
- ArgFormatterBase(BasicWriter<Char> &w, FormatSpec &s)
+ typedef Spec SpecType;
+
+ ArgFormatterBase(BasicWriter<Char> &w, Spec &s)
: writer_(w), spec_(s) {}
template <typename T>
@@ -1853,8 +2129,10 @@ class ArgFormatterBase : public ArgVisitor<Impl, void> {
void visit_any_double(T value) { writer_.write_double(value, spec_); }
void visit_bool(bool value) {
- if (spec_.type_)
- return visit_any_int(value);
+ if (spec_.type_) {
+ visit_any_int(value);
+ return;
+ }
write(value);
}
@@ -1894,13 +2172,14 @@ class ArgFormatterBase : public ArgVisitor<Impl, void> {
write(value);
}
- void visit_string(Arg::StringValue<char> value) {
+ // Qualification with "internal" here and below is a workaround for nvcc.
+ void visit_string(internal::Arg::StringValue<char> value) {
writer_.write_str(value, spec_);
}
using ArgVisitor<Impl, void>::visit_wstring;
- void visit_wstring(Arg::StringValue<Char> value) {
+ void visit_wstring(internal::Arg::StringValue<Char> value) {
writer_.write_str(value, spec_);
}
@@ -1956,26 +2235,6 @@ class FormatterBase {
w << BasicStringRef<Char>(start, internal::to_unsigned(end - start));
}
};
-
-// A printf formatter.
-template <typename Char>
-class PrintfFormatter : private FormatterBase {
- private:
- void parse_flags(FormatSpec &spec, const Char *&s);
-
- // Returns the argument with specified index or, if arg_index is equal
- // to the maximum unsigned value, the next argument.
- Arg get_arg(const Char *s,
- unsigned arg_index = (std::numeric_limits<unsigned>::max)());
-
- // Parses argument index, flags and width and returns the argument index.
- unsigned parse_header(const Char *&s, FormatSpec &spec);
-
- public:
- explicit PrintfFormatter(const ArgList &args) : FormatterBase(args) {}
- FMT_API void format(BasicWriter<Char> &writer,
- BasicCStringRef<Char> format_str);
-};
} // namespace internal
/**
@@ -1995,8 +2254,8 @@ class PrintfFormatter : private FormatterBase {
will be called.
\endrst
*/
-template <typename Impl, typename Char>
-class BasicArgFormatter : public internal::ArgFormatterBase<Impl, Char> {
+template <typename Impl, typename Char, typename Spec = fmt::FormatSpec>
+class BasicArgFormatter : public internal::ArgFormatterBase<Impl, Char, Spec> {
private:
BasicFormatter<Char, Impl> &formatter_;
const Char *format_;
@@ -2011,11 +2270,11 @@ class BasicArgFormatter : public internal::ArgFormatterBase<Impl, Char> {
\endrst
*/
BasicArgFormatter(BasicFormatter<Char, Impl> &formatter,
- FormatSpec &spec, const Char *fmt)
- : internal::ArgFormatterBase<Impl, Char>(formatter.writer(), spec),
+ Spec &spec, const Char *fmt)
+ : internal::ArgFormatterBase<Impl, Char, Spec>(formatter.writer(), spec),
formatter_(formatter), format_(fmt) {}
- /** Formats argument of a custom (user-defined) type. */
+ /** Formats an argument of a custom (user-defined) type. */
void visit_custom(internal::Arg::CustomValue c) {
c.format(&formatter_, c.value, &format_);
}
@@ -2023,12 +2282,14 @@ class BasicArgFormatter : public internal::ArgFormatterBase<Impl, Char> {
/** The default argument formatter. */
template <typename Char>
-class ArgFormatter : public BasicArgFormatter<ArgFormatter<Char>, Char> {
+class ArgFormatter :
+ public BasicArgFormatter<ArgFormatter<Char>, Char, FormatSpec> {
public:
/** Constructs an argument formatter object. */
ArgFormatter(BasicFormatter<Char> &formatter,
FormatSpec &spec, const Char *fmt)
- : BasicArgFormatter<ArgFormatter<Char>, Char>(formatter, spec, fmt) {}
+ : BasicArgFormatter<ArgFormatter<Char>,
+ Char, FormatSpec>(formatter, spec, fmt) {}
};
/** This template formats data and writes the output to a writer. */
@@ -2104,12 +2365,13 @@ inline uint64_t make_type(const T &arg) {
return MakeValue< BasicFormatter<char> >::type(arg);
}
-template <unsigned N, bool/*IsPacked*/= (N < ArgList::MAX_PACKED_ARGS)>
+template <std::size_t N, bool/*IsPacked*/= (N < ArgList::MAX_PACKED_ARGS)>
struct ArgArray;
-template <unsigned N>
+template <std::size_t N>
struct ArgArray<N, true/*IsPacked*/> {
- typedef Value Type[N > 0 ? N : 1];
+ // '+' is used to silence GCC -Wduplicated-branches warning.
+ typedef Value Type[N > 0 ? N : +1];
template <typename Formatter, typename T>
static Value make(const T &value) {
@@ -2125,7 +2387,7 @@ struct ArgArray<N, true/*IsPacked*/> {
}
};
-template <unsigned N>
+template <std::size_t N>
struct ArgArray<N, false/*IsPacked*/> {
typedef Arg Type[N + 1]; // +1 for the list end Arg::NONE
@@ -2265,7 +2527,7 @@ inline uint64_t make_type(FMT_GEN15(FMT_ARG_TYPE_DEFAULT)) {
*/
class SystemError : public internal::RuntimeError {
private:
- void init(int err_code, CStringRef format_str, ArgList args);
+ FMT_API void init(int err_code, CStringRef format_str, ArgList args);
protected:
int error_code_;
@@ -2277,17 +2539,10 @@ class SystemError : public internal::RuntimeError {
public:
/**
\rst
- Constructs a :class:`fmt::SystemError` object with the description
- of the form
-
- .. parsed-literal::
- *<message>*: *<system-message>*
-
- where *<message>* is the formatted message and *<system-message>* is
- the system message corresponding to the error code.
- *error_code* is a system error code as given by ``errno``.
- If *error_code* is not a valid error code such as -1, the system message
- may look like "Unknown error -1" and is platform-dependent.
+ Constructs a :class:`fmt::SystemError` object with a description
+ formatted with `fmt::format_system_error`. *message* and additional
+ arguments passed into the constructor are formatted similarly to
+ `fmt::format`.
**Example**::
@@ -2303,15 +2558,35 @@ class SystemError : public internal::RuntimeError {
SystemError(int error_code, CStringRef message) {
init(error_code, message, ArgList());
}
+ FMT_DEFAULTED_COPY_CTOR(SystemError)
FMT_VARIADIC_CTOR(SystemError, init, int, CStringRef)
- ~SystemError() throw();
+ FMT_API ~SystemError() FMT_DTOR_NOEXCEPT FMT_OVERRIDE;
int error_code() const { return error_code_; }
};
/**
\rst
+ Formats an error returned by an operating system or a language runtime,
+ for example a file opening error, and writes it to *out* in the following
+ form:
+
+ .. parsed-literal::
+ *<message>*: *<system-message>*
+
+ where *<message>* is the passed message and *<system-message>* is
+ the system message corresponding to the error code.
+ *error_code* is a system error code as given by ``errno``.
+ If *error_code* is not a valid error code such as -1, the system message
+ may look like "Unknown error -1" and is platform-dependent.
+ \endrst
+ */
+FMT_API void format_system_error(fmt::Writer &out, int error_code,
+ fmt::StringRef message) FMT_NOEXCEPT;
+
+/**
+ \rst
This template provides operations for formatting and writing data into
a character stream. The output is stored in a buffer provided by a subclass
such as :class:`fmt::BasicMemoryWriter`.
@@ -2398,16 +2673,16 @@ class BasicWriter {
void write_int(T value, Spec spec);
// Formats a floating-point number (double or long double).
- template <typename T>
- void write_double(T value, const FormatSpec &spec);
+ template <typename T, typename Spec>
+ void write_double(T value, const Spec &spec);
// Writes a formatted string.
template <typename StrChar>
CharPtr write_str(const StrChar *s, std::size_t size, const AlignSpec &spec);
- template <typename StrChar>
+ template <typename StrChar, typename Spec>
void write_str(const internal::Arg::StringValue<StrChar> &str,
- const FormatSpec &spec);
+ const Spec &spec);
// This following methods are private to disallow writing wide characters
// and strings to a char stream. If you want to print a wide string as a
@@ -2426,10 +2701,11 @@ class BasicWriter {
template<typename T>
void append_float_length(Char *&, T) {}
- template <typename Impl, typename Char_>
+ template <typename Impl, typename Char_, typename Spec_>
friend class internal::ArgFormatterBase;
- friend class internal::PrintfArgFormatter<Char>;
+ template <typename Impl, typename Char_, typename Spec_>
+ friend class BasicPrintfArgFormatter;
protected:
/**
@@ -2625,9 +2901,9 @@ typename BasicWriter<Char>::CharPtr BasicWriter<Char>::write_str(
}
template <typename Char>
-template <typename StrChar>
+template <typename StrChar, typename Spec>
void BasicWriter<Char>::write_str(
- const internal::Arg::StringValue<StrChar> &s, const FormatSpec &spec) {
+ const internal::Arg::StringValue<StrChar> &s, const Spec &spec) {
// Check if StrChar is convertible to Char.
internal::CharTraits<Char>::convert(StrChar());
if (spec.type_ && spec.type_ != 's')
@@ -2751,7 +3027,7 @@ void BasicWriter<Char>::write_int(T value, Spec spec) {
UnsignedType n = abs_value;
if (spec.flag(HASH_FLAG)) {
prefix[prefix_size++] = '0';
- prefix[prefix_size++] = spec.type();
+ prefix[prefix_size++] = spec.type_prefix();
}
unsigned num_digits = 0;
do {
@@ -2771,7 +3047,7 @@ void BasicWriter<Char>::write_int(T value, Spec spec) {
UnsignedType n = abs_value;
if (spec.flag(HASH_FLAG)) {
prefix[prefix_size++] = '0';
- prefix[prefix_size++] = spec.type();
+ prefix[prefix_size++] = spec.type_prefix();
}
unsigned num_digits = 0;
do {
@@ -2802,7 +3078,7 @@ void BasicWriter<Char>::write_int(T value, Spec spec) {
case 'n': {
unsigned num_digits = internal::count_digits(abs_value);
fmt::StringRef sep = "";
-#ifndef ANDROID
+#if !(defined(ANDROID) || defined(__ANDROID__))
sep = internal::thousands_sep(std::localeconv());
#endif
unsigned size = static_cast<unsigned>(
@@ -2819,8 +3095,8 @@ void BasicWriter<Char>::write_int(T value, Spec spec) {
}
template <typename Char>
-template <typename T>
-void BasicWriter<Char>::write_double(T value, const FormatSpec &spec) {
+template <typename T, typename Spec>
+void BasicWriter<Char>::write_double(T value, const Spec &spec) {
// Check type.
char type = spec.type();
bool upper = false;
@@ -2921,7 +3197,7 @@ void BasicWriter<Char>::write_double(T value, const FormatSpec &spec) {
// Format using snprintf.
Char fill = internal::CharTraits<Char>::cast(spec.fill());
unsigned n = 0;
- Char *start = 0;
+ Char *start = FMT_NULL;
for (;;) {
std::size_t buffer_size = buffer_.capacity() - offset;
#if FMT_MSC_VER
@@ -3198,56 +3474,6 @@ FMT_API void print(std::FILE *f, CStringRef format_str, ArgList args);
*/
FMT_API void print(CStringRef format_str, ArgList args);
-template <typename Char>
-void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args) {
- internal::PrintfFormatter<Char>(args).format(w, format);
-}
-
-/**
- \rst
- Formats arguments and returns the result as a string.
-
- **Example**::
-
- std::string message = fmt::sprintf("The answer is %d", 42);
- \endrst
-*/
-inline std::string sprintf(CStringRef format, ArgList args) {
- MemoryWriter w;
- printf(w, format, args);
- return w.str();
-}
-
-inline std::wstring sprintf(WCStringRef format, ArgList args) {
- WMemoryWriter w;
- printf(w, format, args);
- return w.str();
-}
-
-/**
- \rst
- Prints formatted data to the file *f*.
-
- **Example**::
-
- fmt::fprintf(stderr, "Don't %s!", "panic");
- \endrst
- */
-FMT_API int fprintf(std::FILE *f, CStringRef format, ArgList args);
-
-/**
- \rst
- Prints formatted data to ``stdout``.
-
- **Example**::
-
- fmt::printf("Elapsed time: %.2f seconds", 1.23);
- \endrst
- */
-inline int printf(CStringRef format, ArgList args) {
- return fprintf(stdout, format, args);
-}
-
/**
Fast integer formatter.
*/
@@ -3364,13 +3590,13 @@ inline void format_decimal(char *&buffer, T value) {
\endrst
*/
template <typename T>
-inline internal::NamedArg<char> arg(StringRef name, const T &arg) {
- return internal::NamedArg<char>(name, arg);
+inline internal::NamedArgWithType<char, T> arg(StringRef name, const T &arg) {
+ return internal::NamedArgWithType<char, T>(name, arg);
}
template <typename T>
-inline internal::NamedArg<wchar_t> arg(WStringRef name, const T &arg) {
- return internal::NamedArg<wchar_t>(name, arg);
+inline internal::NamedArgWithType<wchar_t, T> arg(WStringRef name, const T &arg) {
+ return internal::NamedArgWithType<wchar_t, T>(name, arg);
}
// The following two functions are deleted intentionally to disable
@@ -3399,7 +3625,6 @@ void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
#define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
#define FMT_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
-#define FMT_CONCAT(a, b) a##b
#define FMT_FOR_EACH_(N, f, ...) \
FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__))
#define FMT_FOR_EACH(f, ...) \
@@ -3409,10 +3634,10 @@ void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
#define FMT_GET_ARG_NAME(type, index) arg##index
#if FMT_USE_VARIADIC_TEMPLATES
-# define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \
+# define FMT_VARIADIC_(Const, Char, ReturnType, func, call, ...) \
template <typename... Args> \
ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
- const Args & ... args) { \
+ const Args & ... args) Const { \
typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray; \
typename ArgArray::Type array{ \
ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
@@ -3422,35 +3647,35 @@ void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
#else
// Defines a wrapper for a function taking __VA_ARGS__ arguments
// and n additional arguments of arbitrary types.
-# define FMT_WRAP(Char, ReturnType, func, call, n, ...) \
+# define FMT_WRAP(Const, Char, ReturnType, func, call, n, ...) \
template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
- FMT_GEN(n, FMT_MAKE_ARG)) { \
+ FMT_GEN(n, FMT_MAKE_ARG)) Const { \
fmt::internal::ArgArray<n>::Type arr; \
FMT_GEN(n, FMT_ASSIGN_##Char); \
call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList( \
fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), arr)); \
}
-# define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \
- inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__)) { \
+# define FMT_VARIADIC_(Const, Char, ReturnType, func, call, ...) \
+ inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__)) Const { \
call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList()); \
} \
- FMT_WRAP(Char, ReturnType, func, call, 1, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 2, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 3, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 4, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 5, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 6, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 7, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 8, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 9, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 10, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 11, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 12, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 13, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 14, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 15, __VA_ARGS__)
+ FMT_WRAP(Const, Char, ReturnType, func, call, 1, __VA_ARGS__) \
+ FMT_WRAP(Const, Char, ReturnType, func, call, 2, __VA_ARGS__) \
+ FMT_WRAP(Const, Char, ReturnType, func, call, 3, __VA_ARGS__) \
+ FMT_WRAP(Const, Char, ReturnType, func, call, 4, __VA_ARGS__) \
+ FMT_WRAP(Const, Char, ReturnType, func, call, 5, __VA_ARGS__) \
+ FMT_WRAP(Const, Char, ReturnType, func, call, 6, __VA_ARGS__) \
+ FMT_WRAP(Const, Char, ReturnType, func, call, 7, __VA_ARGS__) \
+ FMT_WRAP(Const, Char, ReturnType, func, call, 8, __VA_ARGS__) \
+ FMT_WRAP(Const, Char, ReturnType, func, call, 9, __VA_ARGS__) \
+ FMT_WRAP(Const, Char, ReturnType, func, call, 10, __VA_ARGS__) \
+ FMT_WRAP(Const, Char, ReturnType, func, call, 11, __VA_ARGS__) \
+ FMT_WRAP(Const, Char, ReturnType, func, call, 12, __VA_ARGS__) \
+ FMT_WRAP(Const, Char, ReturnType, func, call, 13, __VA_ARGS__) \
+ FMT_WRAP(Const, Char, ReturnType, func, call, 14, __VA_ARGS__) \
+ FMT_WRAP(Const, Char, ReturnType, func, call, 15, __VA_ARGS__)
#endif // FMT_USE_VARIADIC_TEMPLATES
/**
@@ -3481,10 +3706,16 @@ void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
\endrst
*/
#define FMT_VARIADIC(ReturnType, func, ...) \
- FMT_VARIADIC_(char, ReturnType, func, return func, __VA_ARGS__)
+ FMT_VARIADIC_(, char, ReturnType, func, return func, __VA_ARGS__)
+
+#define FMT_VARIADIC_CONST(ReturnType, func, ...) \
+ FMT_VARIADIC_(const, char, ReturnType, func, return func, __VA_ARGS__)
#define FMT_VARIADIC_W(ReturnType, func, ...) \
- FMT_VARIADIC_(wchar_t, ReturnType, func, return func, __VA_ARGS__)
+ FMT_VARIADIC_(, wchar_t, ReturnType, func, return func, __VA_ARGS__)
+
+#define FMT_VARIADIC_CONST_W(ReturnType, func, ...) \
+ FMT_VARIADIC_(const, wchar_t, ReturnType, func, return func, __VA_ARGS__)
#define FMT_CAPTURE_ARG_(id, index) ::fmt::arg(#id, id)
@@ -3513,12 +3744,7 @@ FMT_VARIADIC(std::string, format, CStringRef)
FMT_VARIADIC_W(std::wstring, format, WCStringRef)
FMT_VARIADIC(void, print, CStringRef)
FMT_VARIADIC(void, print, std::FILE *, CStringRef)
-
FMT_VARIADIC(void, print_colored, Color, CStringRef)
-FMT_VARIADIC(std::string, sprintf, CStringRef)
-FMT_VARIADIC_W(std::wstring, sprintf, WCStringRef)
-FMT_VARIADIC(int, printf, CStringRef)
-FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef)
namespace internal {
template <typename Char>
@@ -3532,17 +3758,19 @@ template <typename Char>
unsigned parse_nonnegative_int(const Char *&s) {
assert('0' <= *s && *s <= '9');
unsigned value = 0;
+ // Convert to unsigned to prevent a warning.
+ unsigned max_int = (std::numeric_limits<int>::max)();
+ unsigned big = max_int / 10;
do {
- unsigned new_value = value * 10 + (*s++ - '0');
- // Check if value wrapped around.
- if (new_value < value) {
- value = (std::numeric_limits<unsigned>::max)();
+ // Check for overflow.
+ if (value > big) {
+ value = max_int + 1;
break;
}
- value = new_value;
+ value = value * 10 + (*s - '0');
+ ++s;
} while ('0' <= *s && *s <= '9');
// Convert to unsigned to prevent a warning.
- unsigned max_int = (std::numeric_limits<int>::max)();
if (value > max_int)
FMT_THROW(FormatError("number is too big"));
return value;
@@ -3583,7 +3811,7 @@ inline internal::Arg BasicFormatter<Char, AF>::get_arg(
template <typename Char, typename AF>
inline internal::Arg BasicFormatter<Char, AF>::parse_arg_index(const Char *&s) {
- const char *error = 0;
+ const char *error = FMT_NULL;
internal::Arg arg = *s < '0' || *s > '9' ?
next_arg(error) : get_arg(internal::parse_nonnegative_int(s), error);
if (error) {
@@ -3601,7 +3829,7 @@ inline internal::Arg BasicFormatter<Char, AF>::parse_arg_name(const Char *&s) {
do {
c = *++s;
} while (internal::is_name_start(c) || ('0' <= c && c <= '9'));
- const char *error = 0;
+ const char *error = FMT_NULL;
internal::Arg arg = get_arg(BasicStringRef<Char>(start, s - start), error);
if (error)
FMT_THROW(FormatError(error));
@@ -3613,7 +3841,7 @@ const Char *BasicFormatter<Char, ArgFormatter>::format(
const Char *&format_str, const internal::Arg &arg) {
using internal::Arg;
const Char *s = format_str;
- FormatSpec spec;
+ typename ArgFormatter::SpecType spec;
if (*s == ':') {
if (arg.type == Arg::CUSTOM) {
arg.custom.format(this, arg.custom.value, &s);
@@ -3714,7 +3942,8 @@ const Char *BasicFormatter<Char, ArgFormatter>::format(
default:
FMT_THROW(FormatError("width is not integer"));
}
- if (value > (std::numeric_limits<int>::max)())
+ unsigned max_int = (std::numeric_limits<int>::max)();
+ if (value > max_int)
FMT_THROW(FormatError("number is too big"));
spec.width_ = static_cast<int>(value);
}
@@ -3752,7 +3981,8 @@ const Char *BasicFormatter<Char, ArgFormatter>::format(
default:
FMT_THROW(FormatError("precision is not integer"));
}
- if (value > (std::numeric_limits<int>::max)())
+ unsigned max_int = (std::numeric_limits<int>::max)();
+ if (value > max_int)
FMT_THROW(FormatError("number is too big"));
spec.precision_ = static_cast<int>(value);
} else {
@@ -3799,6 +4029,66 @@ void BasicFormatter<Char, AF>::format(BasicCStringRef<Char> format_str) {
}
write(writer_, start, s);
}
+
+template <typename Char, typename It>
+struct ArgJoin {
+ It first;
+ It last;
+ BasicCStringRef<Char> sep;
+
+ ArgJoin(It first, It last, const BasicCStringRef<Char>& sep) :
+ first(first),
+ last(last),
+ sep(sep) {}
+};
+
+template <typename It>
+ArgJoin<char, It> join(It first, It last, const BasicCStringRef<char>& sep) {
+ return ArgJoin<char, It>(first, last, sep);
+}
+
+template <typename It>
+ArgJoin<wchar_t, It> join(It first, It last, const BasicCStringRef<wchar_t>& sep) {
+ return ArgJoin<wchar_t, It>(first, last, sep);
+}
+
+#if FMT_HAS_GXX_CXX11
+template <typename Range>
+auto join(const Range& range, const BasicCStringRef<char>& sep)
+ -> ArgJoin<char, decltype(std::begin(range))> {
+ return join(std::begin(range), std::end(range), sep);
+}
+
+template <typename Range>
+auto join(const Range& range, const BasicCStringRef<wchar_t>& sep)
+ -> ArgJoin<wchar_t, decltype(std::begin(range))> {
+ return join(std::begin(range), std::end(range), sep);
+}
+#endif
+
+template <typename ArgFormatter, typename Char, typename It>
+void format_arg(fmt::BasicFormatter<Char, ArgFormatter> &f,
+ const Char *&format_str, const ArgJoin<Char, It>& e) {
+ const Char* end = format_str;
+ if (*end == ':')
+ ++end;
+ while (*end && *end != '}')
+ ++end;
+ if (*end != '}')
+ FMT_THROW(FormatError("missing '}' in format string"));
+
+ It it = e.first;
+ if (it != e.last) {
+ const Char* save = format_str;
+ f.format(format_str, internal::MakeArg<fmt::BasicFormatter<Char, ArgFormatter> >(*it++));
+ while (it != e.last) {
+ f.writer().write(e.sep);
+ format_str = save;
+ f.format(format_str, internal::MakeArg<fmt::BasicFormatter<Char, ArgFormatter> >(*it++));
+ }
+ }
+ format_str = end + 1;
+}
} // namespace fmt
#if FMT_USE_USER_DEFINED_LITERALS
@@ -3821,7 +4111,7 @@ struct UdlArg {
const Char *str;
template <typename T>
- NamedArg<Char> operator=(T &&value) const {
+ NamedArgWithType<Char, T> operator=(T &&value) const {
return {str, std::forward<T>(value)};
}
};
diff --git a/vendor/fmt-3.0.1/fmt/ostream.cc b/vendor/fmt-4.1.0/fmt/ostream.cc
index bcb67fe1..2d443f73 100644
--- a/vendor/fmt-3.0.1/fmt/ostream.cc
+++ b/vendor/fmt-4.1.0/fmt/ostream.cc
@@ -11,9 +11,8 @@
namespace fmt {
-namespace {
-// Write the content of w to os.
-void write(std::ostream &os, Writer &w) {
+namespace internal {
+FMT_FUNC void write(std::ostream &os, Writer &w) {
const char *data = w.data();
typedef internal::MakeUnsigned<std::streamsize>::Type UnsignedStreamSize;
UnsignedStreamSize size = w.size();
@@ -31,13 +30,6 @@ void write(std::ostream &os, Writer &w) {
FMT_FUNC void print(std::ostream &os, CStringRef format_str, ArgList args) {
MemoryWriter w;
w.write(format_str, args);
- write(os, w);
-}
-
-FMT_FUNC int fprintf(std::ostream &os, CStringRef format, ArgList args) {
- MemoryWriter w;
- printf(w, format, args);
- write(os, w);
- return static_cast<int>(w.size());
+ internal::write(os, w);
}
} // namespace fmt
diff --git a/vendor/fmt-3.0.1/fmt/ostream.h b/vendor/fmt-4.1.0/fmt/ostream.h
index 29483c1b..6848aac2 100644
--- a/vendor/fmt-3.0.1/fmt/ostream.h
+++ b/vendor/fmt-4.1.0/fmt/ostream.h
@@ -24,28 +24,27 @@ class FormatBuf : public std::basic_streambuf<Char> {
typedef typename std::basic_streambuf<Char>::traits_type traits_type;
Buffer<Char> &buffer_;
- Char *start_;
public:
- FormatBuf(Buffer<Char> &buffer) : buffer_(buffer), start_(&buffer[0]) {
- this->setp(start_, start_ + buffer_.capacity());
- }
-
- int_type overflow(int_type ch = traits_type::eof()) {
- if (!traits_type::eq_int_type(ch, traits_type::eof())) {
- size_t buf_size = size();
- buffer_.resize(buf_size);
- buffer_.reserve(buf_size * 2);
-
- start_ = &buffer_[0];
- start_[buf_size] = traits_type::to_char_type(ch);
- this->setp(start_+ buf_size + 1, start_ + buf_size * 2);
- }
+ FormatBuf(Buffer<Char> &buffer) : buffer_(buffer) {}
+
+ protected:
+ // The put-area is actually always empty. This makes the implementation
+ // simpler and has the advantage that the streambuf and the buffer are always
+ // in sync and sputc never writes into uninitialized memory. The obvious
+ // disadvantage is that each call to sputc always results in a (virtual) call
+ // to overflow. There is no disadvantage here for sputn since this always
+ // results in a call to xsputn.
+
+ int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE {
+ if (!traits_type::eq_int_type(ch, traits_type::eof()))
+ buffer_.push_back(static_cast<Char>(ch));
return ch;
}
- size_t size() const {
- return to_unsigned(this->pptr() - start_);
+ std::streamsize xsputn(const Char *s, std::streamsize count) FMT_OVERRIDE {
+ buffer_.append(s, s + count);
+ return count;
}
};
@@ -53,32 +52,38 @@ Yes &convert(std::ostream &);
struct DummyStream : std::ostream {
DummyStream(); // Suppress a bogus warning in MSVC.
+
// Hide all operator<< overloads from std::ostream.
- void operator<<(Null<>);
+ template <typename T>
+ typename EnableIf<sizeof(T) == 0>::type operator<<(const T &);
};
No &operator<<(std::ostream &, int);
-template<typename T>
+template <typename T>
struct ConvertToIntImpl<T, true> {
// Convert to int only if T doesn't have an overloaded operator<<.
enum {
value = sizeof(convert(get<DummyStream>() << get<T>())) == sizeof(No)
};
};
+
+// Write the content of w to os.
+FMT_API void write(std::ostream &os, Writer &w);
} // namespace internal
// Formats a value.
-template <typename Char, typename ArgFormatter, typename T>
-void format(BasicFormatter<Char, ArgFormatter> &f,
- const Char *&format_str, const T &value) {
+template <typename Char, typename ArgFormatter_, typename T>
+void format_arg(BasicFormatter<Char, ArgFormatter_> &f,
+ const Char *&format_str, const T &value) {
internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
internal::FormatBuf<Char> format_buf(buffer);
std::basic_ostream<Char> output(&format_buf);
+ output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
output << value;
- BasicStringRef<Char> str(&buffer[0], format_buf.size());
+ BasicStringRef<Char> str(&buffer[0], buffer.size());
typedef internal::MakeArg< BasicFormatter<Char> > MakeArg;
format_str = f.format(format_str, MakeArg(str));
}
@@ -94,18 +99,6 @@ void format(BasicFormatter<Char, ArgFormatter> &f,
*/
FMT_API void print(std::ostream &os, CStringRef format_str, ArgList args);
FMT_VARIADIC(void, print, std::ostream &, CStringRef)
-
-/**
- \rst
- Prints formatted data to the stream *os*.
-
- **Example**::
-
- fprintf(cerr, "Don't %s!", "panic");
- \endrst
- */
-FMT_API int fprintf(std::ostream &os, CStringRef format_str, ArgList args);
-FMT_VARIADIC(int, fprintf, std::ostream &, CStringRef)
} // namespace fmt
#ifdef FMT_HEADER_ONLY
diff --git a/vendor/fmt-3.0.1/fmt/posix.cc b/vendor/fmt-4.1.0/fmt/posix.cc
index 76eb7f05..356668c1 100644
--- a/vendor/fmt-3.0.1/fmt/posix.cc
+++ b/vendor/fmt-4.1.0/fmt/posix.cc
@@ -21,6 +21,9 @@
#ifndef _WIN32
# include <unistd.h>
#else
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
# include <windows.h>
# include <io.h>
@@ -79,7 +82,7 @@ void fmt::BufferedFile::close() {
if (!file_)
return;
int result = FMT_SYSTEM(fclose(file_));
- file_ = 0;
+ file_ = FMT_NULL;
if (result != 0)
FMT_THROW(SystemError(errno, "cannot close file"));
}
diff --git a/vendor/fmt-3.0.1/fmt/posix.h b/vendor/fmt-4.1.0/fmt/posix.h
index be1286c4..88512de5 100644
--- a/vendor/fmt-3.0.1/fmt/posix.h
+++ b/vendor/fmt-4.1.0/fmt/posix.h
@@ -51,25 +51,6 @@
# endif
#endif
-#if FMT_GCC_VERSION >= 407
-# define FMT_UNUSED __attribute__((unused))
-#else
-# define FMT_UNUSED
-#endif
-
-#ifndef FMT_USE_STATIC_ASSERT
-# define FMT_USE_STATIC_ASSERT 0
-#endif
-
-#if FMT_USE_STATIC_ASSERT || FMT_HAS_FEATURE(cxx_static_assert) || \
- (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600
-# define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message)
-#else
-# define FMT_CONCAT_(a, b) FMT_CONCAT(a, b)
-# define FMT_STATIC_ASSERT(cond, message) \
- typedef int FMT_CONCAT_(Assert, __LINE__)[(cond) ? 1 : -1] FMT_UNUSED
-#endif
-
// Retries the expression while it evaluates to error_result and errno
// equals to EINTR.
#ifndef _WIN32
@@ -107,10 +88,10 @@ class BufferedFile {
public:
// Constructs a BufferedFile object which doesn't represent any file.
- BufferedFile() FMT_NOEXCEPT : file_(0) {}
+ BufferedFile() FMT_NOEXCEPT : file_(FMT_NULL) {}
// Destroys the object closing the file it represents if any.
- ~BufferedFile() FMT_NOEXCEPT;
+ FMT_API ~BufferedFile() FMT_NOEXCEPT;
#if !FMT_USE_RVALUE_REFERENCES
// Emulate a move constructor and a move assignment operator if rvalue
@@ -129,7 +110,7 @@ public:
// A "move constructor" for moving from an lvalue.
BufferedFile(BufferedFile &f) FMT_NOEXCEPT : file_(f.file_) {
- f.file_ = 0;
+ f.file_ = FMT_NULL;
}
// A "move assignment operator" for moving from a temporary.
@@ -143,7 +124,7 @@ public:
BufferedFile &operator=(BufferedFile &other) {
close();
file_ = other.file_;
- other.file_ = 0;
+ other.file_ = FMT_NULL;
return *this;
}
@@ -151,7 +132,7 @@ public:
// BufferedFile file = BufferedFile(...);
operator Proxy() FMT_NOEXCEPT {
Proxy p = {file_};
- file_ = 0;
+ file_ = FMT_NULL;
return p;
}
@@ -161,29 +142,29 @@ public:
public:
BufferedFile(BufferedFile &&other) FMT_NOEXCEPT : file_(other.file_) {
- other.file_ = 0;
+ other.file_ = FMT_NULL;
}
BufferedFile& operator=(BufferedFile &&other) {
close();
file_ = other.file_;
- other.file_ = 0;
+ other.file_ = FMT_NULL;
return *this;
}
#endif
// Opens a file.
- BufferedFile(CStringRef filename, CStringRef mode);
+ FMT_API BufferedFile(CStringRef filename, CStringRef mode);
// Closes the file.
- void close();
+ FMT_API void close();
// Returns the pointer to a FILE object representing this file.
FILE *get() const FMT_NOEXCEPT { return file_; }
// We place parentheses around fileno to workaround a bug in some versions
// of MinGW that define fileno as a macro.
- int (fileno)() const;
+ FMT_API int (fileno)() const;
void print(CStringRef format_str, const ArgList &args) {
fmt::print(file_, format_str, args);
@@ -216,7 +197,7 @@ class File {
File() FMT_NOEXCEPT : fd_(-1) {}
// Opens a file and constructs a File object representing this file.
- File(CStringRef path, int oflag);
+ FMT_API File(CStringRef path, int oflag);
#if !FMT_USE_RVALUE_REFERENCES
// Emulate a move constructor and a move assignment operator if rvalue
@@ -279,43 +260,43 @@ class File {
#endif
// Destroys the object closing the file it represents if any.
- ~File() FMT_NOEXCEPT;
+ FMT_API ~File() FMT_NOEXCEPT;
// Returns the file descriptor.
int descriptor() const FMT_NOEXCEPT { return fd_; }
// Closes the file.
- void close();
+ FMT_API void close();
// Returns the file size. The size has signed type for consistency with
// stat::st_size.
- LongLong size() const;
+ FMT_API LongLong size() const;
// Attempts to read count bytes from the file into the specified buffer.
- std::size_t read(void *buffer, std::size_t count);
+ FMT_API std::size_t read(void *buffer, std::size_t count);
// Attempts to write count bytes from the specified buffer to the file.
- std::size_t write(const void *buffer, std::size_t count);
+ FMT_API std::size_t write(const void *buffer, std::size_t count);
// Duplicates a file descriptor with the dup function and returns
// the duplicate as a file object.
- static File dup(int fd);
+ FMT_API static File dup(int fd);
// Makes fd be the copy of this file descriptor, closing fd first if
// necessary.
- void dup2(int fd);
+ FMT_API void dup2(int fd);
// Makes fd be the copy of this file descriptor, closing fd first if
// necessary.
- void dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT;
+ FMT_API void dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT;
// Creates a pipe setting up read_end and write_end file objects for reading
// and writing respectively.
- static void pipe(File &read_end, File &write_end);
+ FMT_API static void pipe(File &read_end, File &write_end);
// Creates a BufferedFile object associated with this file and detaches
// this File object from the file.
- BufferedFile fdopen(const char *mode);
+ FMT_API BufferedFile fdopen(const char *mode);
};
// Returns the memory page size.
@@ -355,7 +336,7 @@ class Locale {
public:
typedef locale_t Type;
- Locale() : locale_(newlocale(LC_NUMERIC_MASK, "C", NULL)) {
+ Locale() : locale_(newlocale(LC_NUMERIC_MASK, "C", FMT_NULL)) {
if (!locale_)
FMT_THROW(fmt::SystemError(errno, "cannot create locale"));
}
@@ -366,7 +347,7 @@ class Locale {
// Converts string to floating-point number and advances str past the end
// of the parsed input.
double strtod(const char *&str) const {
- char *end = 0;
+ char *end = FMT_NULL;
double result = strtod_l(str, &end, locale_);
str = end;
return result;
diff --git a/vendor/fmt-4.1.0/fmt/printf.cc b/vendor/fmt-4.1.0/fmt/printf.cc
new file mode 100644
index 00000000..95d7a36a
--- /dev/null
+++ b/vendor/fmt-4.1.0/fmt/printf.cc
@@ -0,0 +1,32 @@
+/*
+ Formatting library for C++
+
+ Copyright (c) 2012 - 2016, Victor Zverovich
+ All rights reserved.
+
+ For the license information refer to format.h.
+ */
+
+#include "format.h"
+#include "printf.h"
+
+namespace fmt {
+
+template <typename Char>
+void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args);
+
+FMT_FUNC int fprintf(std::FILE *f, CStringRef format, ArgList args) {
+ MemoryWriter w;
+ printf(w, format, args);
+ std::size_t size = w.size();
+ return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast<int>(size);
+}
+
+#ifndef FMT_HEADER_ONLY
+
+template void PrintfFormatter<char>::format(CStringRef format);
+template void PrintfFormatter<wchar_t>::format(WCStringRef format);
+
+#endif // FMT_HEADER_ONLY
+
+} // namespace fmt
diff --git a/vendor/fmt-4.1.0/fmt/printf.h b/vendor/fmt-4.1.0/fmt/printf.h
new file mode 100644
index 00000000..46205a78
--- /dev/null
+++ b/vendor/fmt-4.1.0/fmt/printf.h
@@ -0,0 +1,603 @@
+/*
+ Formatting library for C++
+
+ Copyright (c) 2012 - 2016, Victor Zverovich
+ All rights reserved.
+
+ For the license information refer to format.h.
+ */
+
+#ifndef FMT_PRINTF_H_
+#define FMT_PRINTF_H_
+
+#include <algorithm> // std::fill_n
+#include <limits> // std::numeric_limits
+
+#include "ostream.h"
+
+namespace fmt {
+namespace internal {
+
+// Checks if a value fits in int - used to avoid warnings about comparing
+// signed and unsigned integers.
+template <bool IsSigned>
+struct IntChecker {
+ template <typename T>
+ static bool fits_in_int(T value) {
+ unsigned max = std::numeric_limits<int>::max();
+ return value <= max;
+ }
+ static bool fits_in_int(bool) { return true; }
+};
+
+template <>
+struct IntChecker<true> {
+ template <typename T>
+ static bool fits_in_int(T value) {
+ return value >= std::numeric_limits<int>::min() &&
+ value <= std::numeric_limits<int>::max();
+ }
+ static bool fits_in_int(int) { return true; }
+};
+
+class PrecisionHandler : public ArgVisitor<PrecisionHandler, int> {
+ public:
+ void report_unhandled_arg() {
+ FMT_THROW(FormatError("precision is not integer"));
+ }
+
+ template <typename T>
+ int visit_any_int(T value) {
+ if (!IntChecker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
+ FMT_THROW(FormatError("number is too big"));
+ return static_cast<int>(value);
+ }
+};
+
+// IsZeroInt::visit(arg) returns true iff arg is a zero integer.
+class IsZeroInt : public ArgVisitor<IsZeroInt, bool> {
+ public:
+ template <typename T>
+ bool visit_any_int(T value) { return value == 0; }
+};
+
+// returns the default type for format specific "%s"
+class DefaultType : public ArgVisitor<DefaultType, char> {
+ public:
+ char visit_char(int) { return 'c'; }
+
+ char visit_bool(bool) { return 's'; }
+
+ char visit_pointer(const void *) { return 'p'; }
+
+ template <typename T>
+ char visit_any_int(T) { return 'd'; }
+
+ template <typename T>
+ char visit_any_double(T) { return 'g'; }
+
+ char visit_unhandled_arg() { return 's'; }
+};
+
+template <typename T, typename U>
+struct is_same {
+ enum { value = 0 };
+};
+
+template <typename T>
+struct is_same<T, T> {
+ enum { value = 1 };
+};
+
+// An argument visitor that converts an integer argument to T for printf,
+// if T is an integral type. If T is void, the argument is converted to
+// corresponding signed or unsigned type depending on the type specifier:
+// 'd' and 'i' - signed, other - unsigned)
+template <typename T = void>
+class ArgConverter : public ArgVisitor<ArgConverter<T>, void> {
+ private:
+ internal::Arg &arg_;
+ wchar_t type_;
+
+ FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter);
+
+ public:
+ ArgConverter(internal::Arg &arg, wchar_t type)
+ : arg_(arg), type_(type) {}
+
+ void visit_bool(bool value) {
+ if (type_ != 's')
+ visit_any_int(value);
+ }
+
+ void visit_char(int value) {
+ if (type_ != 's')
+ visit_any_int(value);
+ }
+
+ template <typename U>
+ void visit_any_int(U value) {
+ bool is_signed = type_ == 'd' || type_ == 'i';
+ if (type_ == 's') {
+ is_signed = std::numeric_limits<U>::is_signed;
+ }
+
+ using internal::Arg;
+ typedef typename internal::Conditional<
+ is_same<T, void>::value, U, T>::type TargetType;
+ if (const_check(sizeof(TargetType) <= sizeof(int))) {
+ // Extra casts are used to silence warnings.
+ if (is_signed) {
+ arg_.type = Arg::INT;
+ arg_.int_value = static_cast<int>(static_cast<TargetType>(value));
+ } else {
+ arg_.type = Arg::UINT;
+ typedef typename internal::MakeUnsigned<TargetType>::Type Unsigned;
+ arg_.uint_value = static_cast<unsigned>(static_cast<Unsigned>(value));
+ }
+ } else {
+ if (is_signed) {
+ arg_.type = Arg::LONG_LONG;
+ // glibc's printf doesn't sign extend arguments of smaller types:
+ // std::printf("%lld", -42); // prints "4294967254"
+ // but we don't have to do the same because it's a UB.
+ arg_.long_long_value = static_cast<LongLong>(value);
+ } else {
+ arg_.type = Arg::ULONG_LONG;
+ arg_.ulong_long_value =
+ static_cast<typename internal::MakeUnsigned<U>::Type>(value);
+ }
+ }
+ }
+};
+
+// Converts an integer argument to char for printf.
+class CharConverter : public ArgVisitor<CharConverter, void> {
+ private:
+ internal::Arg &arg_;
+
+ FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter);
+
+ public:
+ explicit CharConverter(internal::Arg &arg) : arg_(arg) {}
+
+ template <typename T>
+ void visit_any_int(T value) {
+ arg_.type = internal::Arg::CHAR;
+ arg_.int_value = static_cast<char>(value);
+ }
+};
+
+// Checks if an argument is a valid printf width specifier and sets
+// left alignment if it is negative.
+class WidthHandler : public ArgVisitor<WidthHandler, unsigned> {
+ private:
+ FormatSpec &spec_;
+
+ FMT_DISALLOW_COPY_AND_ASSIGN(WidthHandler);
+
+ public:
+ explicit WidthHandler(FormatSpec &spec) : spec_(spec) {}
+
+ void report_unhandled_arg() {
+ FMT_THROW(FormatError("width is not integer"));
+ }
+
+ template <typename T>
+ unsigned visit_any_int(T value) {
+ typedef typename internal::IntTraits<T>::MainType UnsignedType;
+ UnsignedType width = static_cast<UnsignedType>(value);
+ if (internal::is_negative(value)) {
+ spec_.align_ = ALIGN_LEFT;
+ width = 0 - width;
+ }
+ unsigned int_max = std::numeric_limits<int>::max();
+ if (width > int_max)
+ FMT_THROW(FormatError("number is too big"));
+ return static_cast<unsigned>(width);
+ }
+};
+} // namespace internal
+
+/**
+ \rst
+ A ``printf`` argument formatter based on the `curiously recurring template
+ pattern <http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern>`_.
+
+ To use `~fmt::BasicPrintfArgFormatter` define a subclass that implements some
+ or all of the visit methods with the same signatures as the methods in
+ `~fmt::ArgVisitor`, for example, `~fmt::ArgVisitor::visit_int()`.
+ Pass the subclass as the *Impl* template parameter. When a formatting
+ function processes an argument, it will dispatch to a visit method
+ specific to the argument type. For example, if the argument type is
+ ``double`` then the `~fmt::ArgVisitor::visit_double()` method of a subclass
+ will be called. If the subclass doesn't contain a method with this signature,
+ then a corresponding method of `~fmt::BasicPrintfArgFormatter` or its
+ superclass will be called.
+ \endrst
+ */
+template <typename Impl, typename Char, typename Spec>
+class BasicPrintfArgFormatter :
+ public internal::ArgFormatterBase<Impl, Char, Spec> {
+ private:
+ void write_null_pointer() {
+ this->spec().type_ = 0;
+ this->write("(nil)");
+ }
+
+ typedef internal::ArgFormatterBase<Impl, Char, Spec> Base;
+
+ public:
+ /**
+ \rst
+ Constructs an argument formatter object.
+ *writer* is a reference to the output writer and *spec* contains format
+ specifier information for standard argument types.
+ \endrst
+ */
+ BasicPrintfArgFormatter(BasicWriter<Char> &w, Spec &s)
+ : internal::ArgFormatterBase<Impl, Char, Spec>(w, s) {}
+
+ /** Formats an argument of type ``bool``. */
+ void visit_bool(bool value) {
+ Spec &fmt_spec = this->spec();
+ if (fmt_spec.type_ != 's')
+ return this->visit_any_int(value);
+ fmt_spec.type_ = 0;
+ this->write(value);
+ }
+
+ /** Formats a character. */
+ void visit_char(int value) {
+ const Spec &fmt_spec = this->spec();
+ BasicWriter<Char> &w = this->writer();
+ if (fmt_spec.type_ && fmt_spec.type_ != 'c')
+ w.write_int(value, fmt_spec);
+ typedef typename BasicWriter<Char>::CharPtr CharPtr;
+ CharPtr out = CharPtr();
+ if (fmt_spec.width_ > 1) {
+ Char fill = ' ';
+ out = w.grow_buffer(fmt_spec.width_);
+ if (fmt_spec.align_ != ALIGN_LEFT) {
+ std::fill_n(out, fmt_spec.width_ - 1, fill);
+ out += fmt_spec.width_ - 1;
+ } else {
+ std::fill_n(out + 1, fmt_spec.width_ - 1, fill);
+ }
+ } else {
+ out = w.grow_buffer(1);
+ }
+ *out = static_cast<Char>(value);
+ }
+
+ /** Formats a null-terminated C string. */
+ void visit_cstring(const char *value) {
+ if (value)
+ Base::visit_cstring(value);
+ else if (this->spec().type_ == 'p')
+ write_null_pointer();
+ else
+ this->write("(null)");
+ }
+
+ /** Formats a pointer. */
+ void visit_pointer(const void *value) {
+ if (value)
+ return Base::visit_pointer(value);
+ this->spec().type_ = 0;
+ write_null_pointer();
+ }
+
+ /** Formats an argument of a custom (user-defined) type. */
+ void visit_custom(internal::Arg::CustomValue c) {
+ BasicFormatter<Char> formatter(ArgList(), this->writer());
+ const Char format_str[] = {'}', 0};
+ const Char *format = format_str;
+ c.format(&formatter, c.value, &format);
+ }
+};
+
+/** The default printf argument formatter. */
+template <typename Char>
+class PrintfArgFormatter :
+ public BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char, FormatSpec> {
+ public:
+ /** Constructs an argument formatter object. */
+ PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s)
+ : BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char, FormatSpec>(w, s) {}
+};
+
+/** This template formats data and writes the output to a writer. */
+template <typename Char, typename ArgFormatter = PrintfArgFormatter<Char> >
+class PrintfFormatter : private internal::FormatterBase {
+ private:
+ BasicWriter<Char> &writer_;
+
+ void parse_flags(FormatSpec &spec, const Char *&s);
+
+ // Returns the argument with specified index or, if arg_index is equal
+ // to the maximum unsigned value, the next argument.
+ internal::Arg get_arg(
+ const Char *s,
+ unsigned arg_index = (std::numeric_limits<unsigned>::max)());
+
+ // Parses argument index, flags and width and returns the argument index.
+ unsigned parse_header(const Char *&s, FormatSpec &spec);
+
+ public:
+ /**
+ \rst
+ Constructs a ``PrintfFormatter`` object. References to the arguments and
+ the writer are stored in the formatter object so make sure they have
+ appropriate lifetimes.
+ \endrst
+ */
+ explicit PrintfFormatter(const ArgList &al, BasicWriter<Char> &w)
+ : FormatterBase(al), writer_(w) {}
+
+ /** Formats stored arguments and writes the output to the writer. */
+ void format(BasicCStringRef<Char> format_str);
+};
+
+template <typename Char, typename AF>
+void PrintfFormatter<Char, AF>::parse_flags(FormatSpec &spec, const Char *&s) {
+ for (;;) {
+ switch (*s++) {
+ case '-':
+ spec.align_ = ALIGN_LEFT;
+ break;
+ case '+':
+ spec.flags_ |= SIGN_FLAG | PLUS_FLAG;
+ break;
+ case '0':
+ spec.fill_ = '0';
+ break;
+ case ' ':
+ spec.flags_ |= SIGN_FLAG;
+ break;
+ case '#':
+ spec.flags_ |= HASH_FLAG;
+ break;
+ default:
+ --s;
+ return;
+ }
+ }
+}
+
+template <typename Char, typename AF>
+internal::Arg PrintfFormatter<Char, AF>::get_arg(const Char *s,
+ unsigned arg_index) {
+ (void)s;
+ const char *error = FMT_NULL;
+ internal::Arg arg = arg_index == std::numeric_limits<unsigned>::max() ?
+ next_arg(error) : FormatterBase::get_arg(arg_index - 1, error);
+ if (error)
+ FMT_THROW(FormatError(!*s ? "invalid format string" : error));
+ return arg;
+}
+
+template <typename Char, typename AF>
+unsigned PrintfFormatter<Char, AF>::parse_header(
+ const Char *&s, FormatSpec &spec) {
+ unsigned arg_index = std::numeric_limits<unsigned>::max();
+ Char c = *s;
+ if (c >= '0' && c <= '9') {
+ // Parse an argument index (if followed by '$') or a width possibly
+ // preceded with '0' flag(s).
+ unsigned value = internal::parse_nonnegative_int(s);
+ if (*s == '$') { // value is an argument index
+ ++s;
+ arg_index = value;
+ } else {
+ if (c == '0')
+ spec.fill_ = '0';
+ if (value != 0) {
+ // Nonzero value means that we parsed width and don't need to
+ // parse it or flags again, so return now.
+ spec.width_ = value;
+ return arg_index;
+ }
+ }
+ }
+ parse_flags(spec, s);
+ // Parse width.
+ if (*s >= '0' && *s <= '9') {
+ spec.width_ = internal::parse_nonnegative_int(s);
+ } else if (*s == '*') {
+ ++s;
+ spec.width_ = internal::WidthHandler(spec).visit(get_arg(s));
+ }
+ return arg_index;
+}
+
+template <typename Char, typename AF>
+void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str) {
+ const Char *start = format_str.c_str();
+ const Char *s = start;
+ while (*s) {
+ Char c = *s++;
+ if (c != '%') continue;
+ if (*s == c) {
+ write(writer_, start, s);
+ start = ++s;
+ continue;
+ }
+ write(writer_, start, s - 1);
+
+ FormatSpec spec;
+ spec.align_ = ALIGN_RIGHT;
+
+ // Parse argument index, flags and width.
+ unsigned arg_index = parse_header(s, spec);
+
+ // Parse precision.
+ if (*s == '.') {
+ ++s;
+ if ('0' <= *s && *s <= '9') {
+ spec.precision_ = static_cast<int>(internal::parse_nonnegative_int(s));
+ } else if (*s == '*') {
+ ++s;
+ spec.precision_ = internal::PrecisionHandler().visit(get_arg(s));
+ } else {
+ spec.precision_ = 0;
+ }
+ }
+
+ using internal::Arg;
+ Arg arg = get_arg(s, arg_index);
+ if (spec.flag(HASH_FLAG) && internal::IsZeroInt().visit(arg))
+ spec.flags_ &= ~internal::to_unsigned<int>(HASH_FLAG);
+ if (spec.fill_ == '0') {
+ if (arg.type <= Arg::LAST_NUMERIC_TYPE)
+ spec.align_ = ALIGN_NUMERIC;
+ else
+ spec.fill_ = ' '; // Ignore '0' flag for non-numeric types.
+ }
+
+ // Parse length and convert the argument to the required type.
+ using internal::ArgConverter;
+ switch (*s++) {
+ case 'h':
+ if (*s == 'h')
+ ArgConverter<signed char>(arg, *++s).visit(arg);
+ else
+ ArgConverter<short>(arg, *s).visit(arg);
+ break;
+ case 'l':
+ if (*s == 'l')
+ ArgConverter<fmt::LongLong>(arg, *++s).visit(arg);
+ else
+ ArgConverter<long>(arg, *s).visit(arg);
+ break;
+ case 'j':
+ ArgConverter<intmax_t>(arg, *s).visit(arg);
+ break;
+ case 'z':
+ ArgConverter<std::size_t>(arg, *s).visit(arg);
+ break;
+ case 't':
+ ArgConverter<std::ptrdiff_t>(arg, *s).visit(arg);
+ break;
+ case 'L':
+ // printf produces garbage when 'L' is omitted for long double, no
+ // need to do the same.
+ break;
+ default:
+ --s;
+ ArgConverter<void>(arg, *s).visit(arg);
+ }
+
+ // Parse type.
+ if (!*s)
+ FMT_THROW(FormatError("invalid format string"));
+ spec.type_ = static_cast<char>(*s++);
+
+ if (spec.type_ == 's') {
+ // set the format type to the default if 's' is specified
+ spec.type_ = internal::DefaultType().visit(arg);
+ }
+
+ if (arg.type <= Arg::LAST_INTEGER_TYPE) {
+ // Normalize type.
+ switch (spec.type_) {
+ case 'i': case 'u':
+ spec.type_ = 'd';
+ break;
+ case 'c':
+ // TODO: handle wchar_t
+ internal::CharConverter(arg).visit(arg);
+ break;
+ }
+ }
+
+ start = s;
+
+ // Format argument.
+ AF(writer_, spec).visit(arg);
+ }
+ write(writer_, start, s);
+}
+
+inline void printf(Writer &w, CStringRef format, ArgList args) {
+ PrintfFormatter<char>(args, w).format(format);
+}
+FMT_VARIADIC(void, printf, Writer &, CStringRef)
+
+inline void printf(WWriter &w, WCStringRef format, ArgList args) {
+ PrintfFormatter<wchar_t>(args, w).format(format);
+}
+FMT_VARIADIC(void, printf, WWriter &, WCStringRef)
+
+/**
+ \rst
+ Formats arguments and returns the result as a string.
+
+ **Example**::
+
+ std::string message = fmt::sprintf("The answer is %d", 42);
+ \endrst
+*/
+inline std::string sprintf(CStringRef format, ArgList args) {
+ MemoryWriter w;
+ printf(w, format, args);
+ return w.str();
+}
+FMT_VARIADIC(std::string, sprintf, CStringRef)
+
+inline std::wstring sprintf(WCStringRef format, ArgList args) {
+ WMemoryWriter w;
+ printf(w, format, args);
+ return w.str();
+}
+FMT_VARIADIC_W(std::wstring, sprintf, WCStringRef)
+
+/**
+ \rst
+ Prints formatted data to the file *f*.
+
+ **Example**::
+
+ fmt::fprintf(stderr, "Don't %s!", "panic");
+ \endrst
+ */
+FMT_API int fprintf(std::FILE *f, CStringRef format, ArgList args);
+FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef)
+
+/**
+ \rst
+ Prints formatted data to ``stdout``.
+
+ **Example**::
+
+ fmt::printf("Elapsed time: %.2f seconds", 1.23);
+ \endrst
+ */
+inline int printf(CStringRef format, ArgList args) {
+ return fprintf(stdout, format, args);
+}
+FMT_VARIADIC(int, printf, CStringRef)
+
+/**
+ \rst
+ Prints formatted data to the stream *os*.
+
+ **Example**::
+
+ fprintf(cerr, "Don't %s!", "panic");
+ \endrst
+ */
+inline int fprintf(std::ostream &os, CStringRef format_str, ArgList args) {
+ MemoryWriter w;
+ printf(w, format_str, args);
+ internal::write(os, w);
+ return static_cast<int>(w.size());
+}
+FMT_VARIADIC(int, fprintf, std::ostream &, CStringRef)
+} // namespace fmt
+
+#ifdef FMT_HEADER_ONLY
+# include "printf.cc"
+#endif
+
+#endif // FMT_PRINTF_H_
diff --git a/vendor/fmt-4.1.0/fmt/string.h b/vendor/fmt-4.1.0/fmt/string.h
new file mode 100644
index 00000000..05996eb5
--- /dev/null
+++ b/vendor/fmt-4.1.0/fmt/string.h
@@ -0,0 +1,148 @@
+/*
+ Formatting library for C++ - string utilities
+
+ Copyright (c) 2012 - 2016, Victor Zverovich
+ All rights reserved.
+
+ For the license information refer to format.h.
+ */
+
+#ifdef FMT_INCLUDE
+# error "Add the fmt's parent directory and not fmt itself to includes."
+#endif
+
+#ifndef FMT_STRING_H_
+#define FMT_STRING_H_
+
+#include "format.h"
+
+namespace fmt {
+
+namespace internal {
+
+// A buffer that stores data in ``std::basic_string``.
+template <typename Char, typename Allocator = std::allocator<Char> >
+class StringBuffer : public Buffer<Char> {
+ public:
+ typedef std::basic_string<Char, std::char_traits<Char>, Allocator> StringType;
+
+ private:
+ StringType data_;
+
+ protected:
+ virtual void grow(std::size_t size) FMT_OVERRIDE {
+ data_.resize(size);
+ this->ptr_ = &data_[0];
+ this->capacity_ = size;
+ }
+
+ public:
+ explicit StringBuffer(const Allocator &allocator = Allocator())
+ : data_(allocator) {}
+
+ // Moves the data to ``str`` clearing the buffer.
+ void move_to(StringType &str) {
+ data_.resize(this->size_);
+ str.swap(data_);
+ this->capacity_ = this->size_ = 0;
+ this->ptr_ = FMT_NULL;
+ }
+};
+} // namespace internal
+
+/**
+ \rst
+ This class template provides operations for formatting and writing data
+ into a character stream. The output is stored in a ``std::basic_string``
+ that grows dynamically.
+
+ You can use one of the following typedefs for common character types
+ and the standard allocator:
+
+ +---------------+----------------------------+
+ | Type | Definition |
+ +===============+============================+
+ | StringWriter | BasicStringWriter<char> |
+ +---------------+----------------------------+
+ | WStringWriter | BasicStringWriter<wchar_t> |
+ +---------------+----------------------------+
+
+ **Example**::
+
+ StringWriter out;
+ out << "The answer is " << 42 << "\n";
+
+ This will write the following output to the ``out`` object:
+
+ .. code-block:: none
+
+ The answer is 42
+
+ The output can be moved to a ``std::basic_string`` with ``out.move_to()``.
+ \endrst
+ */
+template <typename Char, typename Allocator = std::allocator<Char> >
+class BasicStringWriter : public BasicWriter<Char> {
+ private:
+ internal::StringBuffer<Char, Allocator> buffer_;
+
+ public:
+ /**
+ \rst
+ Constructs a :class:`fmt::BasicStringWriter` object.
+ \endrst
+ */
+ explicit BasicStringWriter(const Allocator &allocator = Allocator())
+ : BasicWriter<Char>(buffer_), buffer_(allocator) {}
+
+ /**
+ \rst
+ Moves the buffer content to *str* clearing the buffer.
+ \endrst
+ */
+ void move_to(std::basic_string<Char, std::char_traits<Char>, Allocator> &str) {
+ buffer_.move_to(str);
+ }
+};
+
+typedef BasicStringWriter<char> StringWriter;
+typedef BasicStringWriter<wchar_t> WStringWriter;
+
+/**
+ \rst
+ Converts *value* to ``std::string`` using the default format for type *T*.
+
+ **Example**::
+
+ #include "fmt/string.h"
+
+ std::string answer = fmt::to_string(42);
+ \endrst
+ */
+template <typename T>
+std::string to_string(const T &value) {
+ fmt::MemoryWriter w;
+ w << value;
+ return w.str();
+}
+
+/**
+ \rst
+ Converts *value* to ``std::wstring`` using the default format for type *T*.
+
+ **Example**::
+
+ #include "fmt/string.h"
+
+ std::wstring answer = fmt::to_wstring(42);
+ \endrst
+ */
+template <typename T>
+std::wstring to_wstring(const T &value) {
+ fmt::WMemoryWriter w;
+ w << value;
+ return w.str();
+}
+}
+
+#endif // FMT_STRING_H_
diff --git a/vendor/fmt-4.1.0/fmt/time.h b/vendor/fmt-4.1.0/fmt/time.h
new file mode 100644
index 00000000..c98b0e01
--- /dev/null
+++ b/vendor/fmt-4.1.0/fmt/time.h
@@ -0,0 +1,143 @@
+/*
+ Formatting library for C++ - time formatting
+
+ Copyright (c) 2012 - 2016, Victor Zverovich
+ All rights reserved.
+
+ For the license information refer to format.h.
+ */
+
+#ifndef FMT_TIME_H_
+#define FMT_TIME_H_
+
+#include "format.h"
+#include <ctime>
+
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable: 4702) // unreachable code
+# pragma warning(disable: 4996) // "deprecated" functions
+#endif
+
+namespace fmt {
+template <typename ArgFormatter>
+void format_arg(BasicFormatter<char, ArgFormatter> &f,
+ const char *&format_str, const std::tm &tm) {
+ if (*format_str == ':')
+ ++format_str;
+ const char *end = format_str;
+ while (*end && *end != '}')
+ ++end;
+ if (*end != '}')
+ FMT_THROW(FormatError("missing '}' in format string"));
+ internal::MemoryBuffer<char, internal::INLINE_BUFFER_SIZE> format;
+ format.append(format_str, end + 1);
+ format[format.size() - 1] = '\0';
+ Buffer<char> &buffer = f.writer().buffer();
+ std::size_t start = buffer.size();
+ for (;;) {
+ std::size_t size = buffer.capacity() - start;
+ std::size_t count = std::strftime(&buffer[start], size, &format[0], &tm);
+ if (count != 0) {
+ buffer.resize(start + count);
+ break;
+ }
+ if (size >= format.size() * 256) {
+ // If the buffer is 256 times larger than the format string, assume
+ // that `strftime` gives an empty result. There doesn't seem to be a
+ // better way to distinguish the two cases:
+ // https://github.com/fmtlib/fmt/issues/367
+ break;
+ }
+ const std::size_t MIN_GROWTH = 10;
+ buffer.reserve(buffer.capacity() + (size > MIN_GROWTH ? size : MIN_GROWTH));
+ }
+ format_str = end + 1;
+}
+
+namespace internal{
+inline Null<> localtime_r(...) { return Null<>(); }
+inline Null<> localtime_s(...) { return Null<>(); }
+inline Null<> gmtime_r(...) { return Null<>(); }
+inline Null<> gmtime_s(...) { return Null<>(); }
+}
+
+// Thread-safe replacement for std::localtime
+inline std::tm localtime(std::time_t time) {
+ struct LocalTime {
+ std::time_t time_;
+ std::tm tm_;
+
+ LocalTime(std::time_t t): time_(t) {}
+
+ bool run() {
+ using namespace fmt::internal;
+ return handle(localtime_r(&time_, &tm_));
+ }
+
+ bool handle(std::tm *tm) { return tm != FMT_NULL; }
+
+ bool handle(internal::Null<>) {
+ using namespace fmt::internal;
+ return fallback(localtime_s(&tm_, &time_));
+ }
+
+ bool fallback(int res) { return res == 0; }
+
+ bool fallback(internal::Null<>) {
+ using namespace fmt::internal;
+ std::tm *tm = std::localtime(&time_);
+ if (tm) tm_ = *tm;
+ return tm != FMT_NULL;
+ }
+ };
+ LocalTime lt(time);
+ if (lt.run())
+ return lt.tm_;
+ // Too big time values may be unsupported.
+ FMT_THROW(fmt::FormatError("time_t value out of range"));
+ return std::tm();
+}
+
+// Thread-safe replacement for std::gmtime
+inline std::tm gmtime(std::time_t time) {
+ struct GMTime {
+ std::time_t time_;
+ std::tm tm_;
+
+ GMTime(std::time_t t): time_(t) {}
+
+ bool run() {
+ using namespace fmt::internal;
+ return handle(gmtime_r(&time_, &tm_));
+ }
+
+ bool handle(std::tm *tm) { return tm != FMT_NULL; }
+
+ bool handle(internal::Null<>) {
+ using namespace fmt::internal;
+ return fallback(gmtime_s(&tm_, &time_));
+ }
+
+ bool fallback(int res) { return res == 0; }
+
+ bool fallback(internal::Null<>) {
+ std::tm *tm = std::gmtime(&time_);
+ if (tm != FMT_NULL) tm_ = *tm;
+ return tm != FMT_NULL;
+ }
+ };
+ GMTime gt(time);
+ if (gt.run())
+ return gt.tm_;
+ // Too big time values may be unsupported.
+ FMT_THROW(fmt::FormatError("time_t value out of range"));
+ return std::tm();
+}
+} //namespace fmt
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
+#endif // FMT_TIME_H_
diff --git a/vendor/jsoncons b/vendor/jsoncons
index 0f3415d8..33696c54 120000
--- a/vendor/jsoncons
+++ b/vendor/jsoncons
@@ -1 +1 @@
-jsoncons-0.99.2 \ No newline at end of file
+jsoncons-0.104.0 \ No newline at end of file
diff --git a/vendor/jsoncons-0.104.0/jsoncons/detail/heap_only_string.hpp b/vendor/jsoncons-0.104.0/jsoncons/detail/heap_only_string.hpp
new file mode 100644
index 00000000..5348b436
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/detail/heap_only_string.hpp
@@ -0,0 +1,155 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_DETAIL_HEAPONLYSTRING_HPP
+#define JSONCONS_DETAIL_HEAPONLYSTRING_HPP
+
+#include <stdexcept>
+#include <string>
+#include <cstdlib>
+#include <exception>
+#include <ostream>
+#include <jsoncons/jsoncons_config.hpp>
+
+namespace jsoncons { namespace detail {
+
+template <class Allocator>
+class heap_only_string_base
+{
+ Allocator allocator_;
+public:
+ Allocator& get_allocator()
+ {
+ return allocator_;
+ }
+
+ const Allocator& get_allocator() const
+ {
+ return allocator_;
+ }
+protected:
+ heap_only_string_base(const Allocator& allocator)
+ : allocator_(allocator)
+ {
+ }
+
+ ~heap_only_string_base() {}
+};
+
+template <class CharT,class Allocator>
+class heap_only_string_factory;
+
+template <class CharT, class Allocator>
+class heap_only_string : public heap_only_string_base<Allocator>
+{
+ typedef typename std::allocator_traits<Allocator>::template rebind_alloc<CharT> allocator_type;
+ typedef std::allocator_traits<allocator_type> allocator_traits_type;
+ typedef typename allocator_traits_type::pointer pointer;
+
+ friend class heap_only_string_factory<CharT, Allocator>;
+public:
+ typedef CharT char_type;
+ typedef heap_only_string<CharT,Allocator> value_type;
+
+ ~heap_only_string() {}
+
+ const char_type* c_str() const { return to_plain_pointer(p_); }
+ const char_type* data() const { return to_plain_pointer(p_); }
+ size_t length() const { return length_; }
+
+ using heap_only_string_base<Allocator>::get_allocator;
+
+
+ friend std::basic_ostream<CharT>& operator<<(std::basic_ostream<CharT>& os, const heap_only_string& s)
+ {
+ os.write(s.data(),s.length());
+ return os;
+ }
+private:
+ heap_only_string()
+ : heap_only_string_base<Allocator>(Allocator())
+ {
+
+ }
+ heap_only_string(const Allocator& allocator)
+ : heap_only_string_base<Allocator>(allocator)
+ {
+
+ }
+
+ pointer p_;
+ size_t length_;
+
+ heap_only_string(const heap_only_string&) = delete;
+ heap_only_string& operator=(const heap_only_string&) = delete;
+
+};
+
+template <class CharT, class Allocator>
+class heap_only_string_factory
+{
+ typedef CharT char_type;
+ typedef typename std::allocator_traits<Allocator>::template rebind_alloc<char> byte_allocator_type;
+ typedef std::allocator_traits<byte_allocator_type> byte_allocator_traits_type;
+ typedef typename byte_allocator_traits_type::pointer byte_pointer;
+ typedef typename heap_only_string<CharT,Allocator>::pointer pointer;
+public:
+
+ typedef typename std::allocator_traits<Allocator>::template rebind_alloc<heap_only_string<CharT,Allocator>> string_allocator_type;
+ typedef std::allocator_traits<string_allocator_type> string_allocator_traits_type;
+ typedef typename string_allocator_traits_type::pointer string_pointer;
+
+ typedef heap_only_string<char_type,Allocator>* raw_string_pointer_type;
+
+ struct string_storage
+ {
+ heap_only_string<CharT,Allocator> data;
+ char_type c[1];
+ };
+ typedef typename std::aligned_storage<sizeof(string_storage), JSONCONS_ALIGNOF(string_storage)>::type storage_type;
+
+ static size_t aligned_size(size_t n)
+ {
+ return sizeof(storage_type) + n;
+ }
+public:
+ static string_pointer create(const char_type* s, size_t length)
+ {
+ return create(s, length, Allocator());
+ }
+ static string_pointer create(const char_type* s, size_t length, const Allocator& allocator)
+ {
+ size_t mem_size = aligned_size(length*sizeof(char_type));
+
+ byte_allocator_type alloc(allocator);
+ byte_pointer ptr = alloc.allocate(mem_size);
+
+ char* storage = to_plain_pointer(ptr);
+ raw_string_pointer_type ps = new(storage)heap_only_string<char_type,Allocator>(alloc);
+ auto psa = reinterpret_cast<string_storage*>(storage);
+
+ CharT* p = new(&psa->c)char_type[length + 1];
+ memcpy(p, s, length*sizeof(char_type));
+ p[length] = 0;
+ ps->p_ = std::pointer_traits<pointer>::pointer_to(*p);
+ ps->length_ = length;
+ return std::pointer_traits<string_pointer>::pointer_to(*ps);
+ }
+
+ static void destroy(string_pointer ptr)
+ {
+ raw_string_pointer_type rawp = to_plain_pointer(ptr);
+ char* p = reinterpret_cast<char*>(rawp);
+ size_t mem_size = aligned_size(ptr->length_*sizeof(char_type));
+ byte_allocator_type alloc(ptr->get_allocator());
+ alloc.deallocate(p,mem_size);
+ }
+};
+
+
+}}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/detail/number_parsers.hpp b/vendor/jsoncons-0.104.0/jsoncons/detail/number_parsers.hpp
new file mode 100644
index 00000000..1a8fc0a9
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/detail/number_parsers.hpp
@@ -0,0 +1,266 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_DETAIL_NUMBERPARSERS_HPP
+#define JSONCONS_DETAIL_NUMBERPARSERS_HPP
+
+#include <stdexcept>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <cstdlib>
+#include <cstdarg>
+#include <locale>
+#include <limits>
+#include <type_traits>
+#include <algorithm>
+#include <exception>
+#include <jsoncons/jsoncons_config.hpp>
+
+namespace jsoncons { namespace detail {
+
+struct to_integer_result
+{
+ int64_t value;
+ bool overflow;
+};
+
+// Precondition: s satisfies
+
+// digit
+// digit1-digits
+// - digit
+// - digit1-digits
+
+template <class CharT>
+to_integer_result to_integer(const CharT* s, size_t length)
+{
+ JSONCONS_ASSERT(length > 0);
+
+ int64_t n = 0;
+ bool overflow = false;
+ const CharT* end = s + length;
+ if (*s == '-')
+ {
+ static const int64_t min_value = (std::numeric_limits<int64_t>::min)();
+ static const int64_t min_value_div_10 = min_value / 10;
+ ++s;
+ for (; s < end; ++s)
+ {
+ int64_t x = *s - '0';
+ if (n < min_value_div_10)
+ {
+ overflow = true;
+ break;
+ }
+ n = n * 10;
+ if (n < min_value + x)
+ {
+ overflow = true;
+ break;
+ }
+
+ n -= x;
+ }
+ }
+ else
+ {
+ static const int64_t max_value = (std::numeric_limits<int64_t>::max)();
+ static const int64_t max_value_div_10 = max_value / 10;
+ for (; s < end; ++s)
+ {
+ int64_t x = *s - '0';
+ if (n > max_value_div_10)
+ {
+ overflow = true;
+ break;
+ }
+ n = n * 10;
+ if (n > max_value - x)
+ {
+ overflow = true;
+ break;
+ }
+
+ n += x;
+ }
+ }
+
+ return to_integer_result({ n,overflow });
+}
+
+struct to_uinteger_result
+{
+ uint64_t value;
+ bool overflow;
+};
+
+// Precondition: s satisfies
+
+// digit
+// digit1-digits
+// - digit
+// - digit1-digits
+
+template <class CharT>
+to_uinteger_result to_uinteger(const CharT* s, size_t length)
+{
+ JSONCONS_ASSERT(length > 0);
+
+ static const uint64_t max_value = (std::numeric_limits<uint64_t>::max)();
+ static const uint64_t max_value_div_10 = max_value / 10;
+ uint64_t n = 0;
+ bool overflow = false;
+
+ const CharT* end = s + length;
+ for (; s < end; ++s)
+ {
+ uint64_t x = *s - '0';
+ if (n > max_value_div_10)
+ {
+ overflow = true;
+ break;
+ }
+ n = n * 10;
+ if (n > max_value - x)
+ {
+ overflow = true;
+ break;
+ }
+
+ n += x;
+ }
+ return to_uinteger_result{ n,overflow };
+}
+
+#if defined(JSONCONS_HAS_MSC__STRTOD_L)
+
+class string_to_double
+{
+private:
+ _locale_t locale_;
+public:
+ string_to_double()
+ {
+ locale_ = _create_locale(LC_NUMERIC, "C");
+ }
+ ~string_to_double()
+ {
+ _free_locale(locale_);
+ }
+
+ char get_decimal_point() const
+ {
+ return '.';
+ }
+
+ double operator()(const char* s, size_t) const
+ {
+ const char *begin = s;
+ char *end = nullptr;
+ double val = _strtod_l(begin, &end, locale_);
+ if (begin == end)
+ {
+ JSONCONS_THROW(json_exception_impl<std::invalid_argument>("Invalid float value"));
+ }
+ return val;
+ }
+private:
+ // noncopyable and nonmoveable
+ string_to_double(const string_to_double&) = delete;
+ string_to_double& operator=(const string_to_double&) = delete;
+};
+
+#elif defined(JSONCONS_HAS_STRTOLD_L)
+
+class string_to_double
+{
+private:
+ locale_t locale_;
+public:
+ string_to_double()
+ {
+ locale_ = newlocale(LC_ALL_MASK, "C", (locale_t) 0);
+ }
+ ~string_to_double()
+ {
+ freelocale(locale_);
+ }
+
+ char get_decimal_point() const
+ {
+ return '.';
+ }
+
+ double operator()(const char* s, size_t length) const
+ {
+ const char *begin = s;
+ char *end = nullptr;
+ double val = strtold_l(begin, &end, locale_);
+ if (begin == end)
+ {
+ JSONCONS_THROW(json_exception_impl<std::invalid_argument>("Invalid float value"));
+ }
+ return val;
+ }
+
+private:
+ // noncopyable and nonmoveable
+ string_to_double(const string_to_double& fr) = delete;
+ string_to_double& operator=(const string_to_double& fr) = delete;
+};
+
+#else
+class string_to_double
+{
+private:
+ std::vector<char> buffer_;
+ char decimal_point_;
+public:
+ string_to_double()
+ : buffer_()
+ {
+ struct lconv * lc = localeconv();
+ if (lc != nullptr && lc->decimal_point[0] != 0)
+ {
+ decimal_point_ = lc->decimal_point[0];
+ }
+ else
+ {
+ decimal_point_ = '.';
+ }
+ buffer_.reserve(100);
+ }
+
+ char get_decimal_point() const
+ {
+ return decimal_point_;
+ }
+
+ double operator()(const char* s, size_t /*length*/) const
+ {
+ char *end = nullptr;
+ double val = strtod(s, &end);
+ if (s == end)
+ {
+ JSONCONS_THROW(json_exception_impl<std::invalid_argument>("string_to_double failed"));
+ }
+ return val;
+ }
+
+private:
+ // noncopyable and nonmoveable
+ string_to_double(const string_to_double& fr) = delete;
+ string_to_double& operator=(const string_to_double& fr) = delete;
+};
+#endif
+
+}}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/detail/number_printers.hpp b/vendor/jsoncons-0.104.0/jsoncons/detail/number_printers.hpp
new file mode 100644
index 00000000..58779280
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/detail/number_printers.hpp
@@ -0,0 +1,374 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_DETAIL_NUMBERPRINTERS_HPP
+#define JSONCONS_DETAIL_NUMBERPRINTERS_HPP
+
+#include <stdexcept>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <cstdlib>
+#include <cmath>
+#include <cstdarg>
+#include <locale>
+#include <limits>
+#include <algorithm>
+#include <exception>
+#include <jsoncons/jsoncons_config.hpp>
+#include <jsoncons/detail/obufferedstream.hpp>
+
+namespace jsoncons { namespace detail {
+
+// print_integer
+
+template<class Writer>
+void print_integer(int64_t value, Writer& os)
+{
+ typedef typename Writer::char_type char_type;
+
+ char_type buf[255];
+ uint64_t u = (value < 0) ? static_cast<uint64_t>(-value) : static_cast<uint64_t>(value);
+ char_type* p = buf;
+ do
+ {
+ *p++ = static_cast<char_type>(48 + u%10);
+ }
+ while (u /= 10);
+ if (value < 0)
+ {
+ os.put('-');
+ }
+ while (--p >= buf)
+ {
+ os.put(*p);
+ }
+}
+
+// print_uinteger
+
+template<class Writer>
+void print_uinteger(uint64_t value, Writer& os)
+{
+ typedef typename Writer::char_type char_type;
+
+ char_type buf[255];
+ char_type* p = buf;
+ do
+ {
+ *p++ = static_cast<char_type>(48 + value % 10);
+ } while (value /= 10);
+ while (--p >= buf)
+ {
+ os.put(*p);
+ }
+}
+
+// print_double
+
+#if defined(JSONCONS_HAS__ECVT_S)
+
+class print_double
+{
+private:
+ uint8_t precision_override_;
+public:
+ print_double(uint8_t precision)
+ : precision_override_(precision)
+ {
+ }
+
+ template <class Writer>
+ void operator()(double val, uint8_t precision, Writer& writer)
+ {
+ typedef typename Writer::char_type char_type;
+
+ char buf[_CVTBUFSIZE];
+ int decimal_point = 0;
+ int sign = 0;
+
+ int prec;
+ if (precision_override_ != 0)
+ {
+ prec = precision_override_;
+ }
+ else if (precision != 0)
+ {
+ prec = precision;
+ }
+ else
+ {
+ prec = std::numeric_limits<double>::digits10;
+ }
+
+ int err = _ecvt_s(buf, _CVTBUFSIZE, val, prec, &decimal_point, &sign);
+ if (err != 0)
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Failed attempting double to string conversion"));
+ }
+ //std::cout << "prec:" << prec << ", buf:" << buf << std::endl;
+ char* s = buf;
+ char* se = s + prec;
+
+ int i, k;
+ int j;
+
+ if (sign)
+ {
+ writer.put('-');
+ }
+ if (decimal_point <= -4 || decimal_point > se - s + 5)
+ {
+ writer.put(*s++);
+ if (s < se)
+ {
+ writer.put('.');
+ while ((se-1) > s && *(se-1) == '0')
+ {
+ --se;
+ }
+
+ while(s < se)
+ {
+ writer.put(*s++);
+ }
+ }
+ writer.put('e');
+ /* sprintf(b, "%+.2d", decimal_point - 1); */
+ if (--decimal_point < 0) {
+ writer.put('-');
+ decimal_point = -decimal_point;
+ }
+ else
+ writer.put('+');
+ for(j = 2, k = 10; 10*k <= decimal_point; j++, k *= 10);
+ for(;;)
+ {
+ i = decimal_point / k;
+ writer.put(static_cast<char_type>(i) + '0');
+ if (--j <= 0)
+ break;
+ decimal_point -= i*k;
+ decimal_point *= 10;
+ }
+ }
+ else if (decimal_point <= 0)
+ {
+ writer.put('0');
+ writer.put('.');
+ while ((se-1) > s && *(se-1) == '0')
+ {
+ --se;
+ }
+ for(; decimal_point < 0; decimal_point++)
+ {
+ writer.put('0');
+ }
+ while(s < se)
+ {
+ writer.put(*s++);
+ }
+ }
+ else {
+ while(s < se)
+ {
+ writer.put(*s++);
+ if ((--decimal_point == 0) && s < se)
+ {
+ writer.put('.');
+ while ((se-1) > s && *(se-1) == '0')
+ {
+ --se;
+ }
+ }
+ }
+ for(; decimal_point > 0; decimal_point--)
+ {
+ writer.put('0');
+ }
+ }
+ }
+};
+
+#elif defined(JSONCONS_NO_LOCALECONV)
+
+class print_double
+{
+private:
+ uint8_t precision_override_;
+ basic_obufferedstream<char> os_;
+public:
+ print_double(uint8_t precision)
+ : precision_override_(precision)
+ {
+ os_.imbue(std::locale::classic());
+ os_.precision(precision);
+ }
+
+ template <class Writer>
+ void operator()(double val, uint8_t precision, Writer& writer)
+ {
+ typedef typename Writer::char_type char_type;
+
+ int prec;
+ if (precision_override_ != 0)
+ {
+ prec = precision_override_;
+ }
+ else if (precision != 0)
+ {
+ prec = precision;
+ }
+ else
+ {
+ prec = std::numeric_limits<double>::digits10;
+ }
+
+ os_.clear_sequence();
+ os_.precision(prec);
+ os_ << val;
+
+ //std::cout << "precision_override_:" << (int)precision_override_ << ", precision:" << (int)precision << ", buf:" << os_.data() << std::endl;
+
+ const char_type* sbeg = os_.data();
+ const char_type* send = sbeg + os_.length();
+ const char_type* pexp = send;
+
+ if (sbeg != send)
+ {
+ bool dot = false;
+ for (pexp = sbeg; *pexp != 'e' && *pexp != 'E' && pexp < send; ++pexp)
+ {
+ }
+
+ const char_type* qend = pexp;
+ while (qend >= sbeg+2 && *(qend-1) == '0' && *(qend-2) != '.')
+ {
+ --qend;
+ }
+ if (pexp == send)
+ {
+ qend = ((qend >= sbeg+2) && *(qend-2) == '.') ? qend : send;
+ }
+
+ for (const char_type* q = sbeg; q < qend; ++q)
+ {
+ if (*q == '.')
+ {
+ dot = true;
+ }
+ writer.put(*q);
+ }
+ if (!dot)
+ {
+ writer.put('.');
+ writer.put('0');
+ dot = true;
+ }
+ for (const char_type* q = pexp; q < send; ++q)
+ {
+ writer.put(*q);
+ }
+ }
+ }
+};
+#else
+
+class print_double
+{
+private:
+ uint8_t precision_override_;
+ char decimal_point_;
+public:
+ print_double(uint8_t precision)
+ : precision_override_(precision)
+ {
+ struct lconv * lc = localeconv();
+ if (lc != nullptr && lc->decimal_point[0] != 0)
+ {
+ decimal_point_ = lc->decimal_point[0];
+ }
+ else
+ {
+ decimal_point_ = '.';
+ }
+ }
+
+ template <class Writer>
+ void operator()(double val, uint8_t precision, Writer& writer)
+ {
+ typedef typename Writer::char_type char_type;
+
+ int prec;
+ if (precision_override_ != 0)
+ {
+ prec = precision_override_;
+ }
+ else if (precision != 0)
+ {
+ prec = precision;
+ }
+ else
+ {
+ prec = std::numeric_limits<double>::digits10;
+ }
+
+ char number_buffer[100];
+ int length = snprintf(number_buffer, 100, "%1.*g", prec, val);
+ if (length < 0)
+ {
+ JSONCONS_THROW(json_exception_impl<std::invalid_argument>("print_double failed."));
+ }
+
+ const char* sbeg = number_buffer;
+ const char* send = sbeg + length;
+ const char* pexp = send;
+
+ if (sbeg != send)
+ {
+ bool dot = false;
+ for (pexp = sbeg; *pexp != 'e' && *pexp != 'E' && pexp < send; ++pexp)
+ {
+ }
+
+ for (const char* q = sbeg; q < pexp; ++q)
+ {
+ switch (*q)
+ {
+ case '-':case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
+ writer.put(*q);
+ break;
+ default:
+ if (*q == decimal_point_)
+ {
+ dot = true;
+ writer.put('.');
+ }
+ break;
+ }
+ }
+ if (!dot)
+ {
+ writer.put('.');
+ writer.put('0');
+ dot = true;
+ }
+ for (const char* q = pexp; q < send; ++q)
+ {
+ writer.put(*q);
+ }
+ }
+ }
+};
+
+#endif
+
+}}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/detail/obufferedstream.hpp b/vendor/jsoncons-0.104.0/jsoncons/detail/obufferedstream.hpp
new file mode 100644
index 00000000..7b499f4b
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/detail/obufferedstream.hpp
@@ -0,0 +1,264 @@
+// Copyright 2016 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_DETAIL_OBUFFEREDSTREAM_HPP
+#define JSONCONS_DETAIL_OBUFFEREDSTREAM_HPP
+
+#include <ios>
+#include <ostream>
+#include <string>
+#include <cstddef>
+#include <vector>
+#include <locale>
+#include <jsoncons/jsoncons_config.hpp>
+
+namespace jsoncons {
+
+template<
+ class CharT,
+ class Traits = std::char_traits<CharT>
+> class basic_obufferedstream;
+
+template<class CharT, class Traits>
+class basic_ovectorbuf
+ : public std::basic_streambuf<CharT, Traits>
+{
+private:
+ std::ios_base::openmode mode_;
+ std::vector<CharT> buf_;
+
+public:
+ typedef CharT char_type;
+ typedef typename Traits::int_type int_type;
+ typedef typename Traits::pos_type pos_type;
+ typedef typename Traits::off_type off_type;
+ typedef Traits traits_type;
+
+public:
+
+ explicit basic_ovectorbuf() JSONCONS_NOEXCEPT
+ : mode_(std::ios_base::out | std::ios_base::binary),
+ buf_(100u)
+ {
+ // Set write position to beginning of buffer.
+ this->setp(buf_.data(), buf_.data() + buf_.size());
+ this->setg(buf_.data(), 0, buf_.data());
+ }
+
+ explicit basic_ovectorbuf(std::size_t length) JSONCONS_NOEXCEPT
+ : mode_(std::ios_base::out | std::ios_base::binary),
+ buf_(length)
+ {
+ // Set write position to beginning of buffer.
+ this->setp(buf_.data(), buf_.data() + buf_.size());
+ this->setg(buf_.data(), 0, buf_.data());
+ }
+
+ virtual ~basic_ovectorbuf() JSONCONS_NOEXCEPT {}
+
+ basic_ovectorbuf(const basic_ovectorbuf<CharT,Traits>&) = delete;
+
+ //basic_ovectorbuf(basic_ovectorbuf<CharT,Traits>&&) = default;
+
+ basic_ovectorbuf<CharT,Traits>& operator=(const basic_ovectorbuf<CharT,Traits>&) = delete;
+
+ //basic_ovectorbuf<CharT,Traits>& operator=(basic_ovectorbuf<CharT,Traits>&&) = default;
+
+ const CharT* data() const
+ {
+ return buf_.data();
+ }
+
+ size_t length() const
+ {
+ return this->pptr() - this->pbase();
+ }
+
+ virtual int sync() override
+ {
+ return EOF;
+ }
+
+protected:
+ int_type underflow() override
+ {
+ return this->gptr() != this->egptr() ?
+ Traits::to_int_type(*this->gptr()) : Traits::eof();
+ }
+
+ int_type pbackfail(int_type c = Traits::eof()) override
+ {
+ if (this->gptr() != this->eback())
+ {
+ if (!Traits::eq_int_type(c, Traits::eof()))
+ {
+ if (Traits::eq(Traits::to_char_type(c), this->gptr()[-1]))
+ {
+ this->gbump(-1);
+ return c;
+ }
+ this->gbump(-1);
+ *this->gptr() = static_cast<CharT>(c);
+ return c;
+ }
+ else
+ {
+ this->gbump(-1);
+ return Traits::not_eof(c);
+ }
+ }
+ else
+ {
+ return Traits::eof();
+ }
+ }
+
+ int_type overflow(int_type c = Traits::eof()) override
+ {
+ if (!Traits::eq_int_type(c, Traits::eof()))
+ {
+ size_t pos = buf_.size()+1;
+ buf_.resize(pos*2);
+ this->setp(buf_.data(), buf_.data() + buf_.size());
+ this->pubseekpos(pos, std::ios_base::out);
+ *this->pptr() = Traits::to_char_type(c);
+ this->pbump(1);
+ this->pubsync();
+ return c;
+ }
+ else
+ {
+ return Traits::not_eof(c);
+ }
+ }
+
+ pos_type seekoff(off_type off, std::ios_base::seekdir dir,
+ std::ios_base::openmode mode = std::ios_base::out) override
+ {
+ (void)mode; // Always out
+
+ std::streamoff newoff;
+ switch (dir)
+ {
+ case std::ios_base::beg:
+ newoff = 0;
+ break;
+ case std::ios_base::end:
+ newoff = static_cast<std::streamoff>(buf_.size());
+ break;
+ case std::ios_base::cur:
+ newoff = static_cast<std::streamoff>(this->pptr() - this->pbase());
+ break;
+ default:
+ return pos_type(off_type(-1));
+ }
+
+ off += newoff;
+
+ std::ptrdiff_t n = this->epptr() - this->pbase();
+
+ if (off < 0 || off > n) return pos_type(off_type(-1));
+ else
+ {
+ this->setp(this->pbase(), this->pbase() + n);
+ this->pbump(static_cast<int>(off));
+ }
+
+ return pos_type(off);
+ }
+
+ pos_type seekoff_beg(off_type off)
+ {
+ std::ptrdiff_t n = this->epptr() - this->pbase();
+
+ if (off < 0 || off > n)
+ {
+ return pos_type(off_type(-1));
+ }
+ else
+ {
+ this->setp(this->pbase(), this->pbase() + n);
+ this->pbump(static_cast<int>(off));
+ }
+
+ return pos_type(off);
+ }
+
+ pos_type seekpos(pos_type pos, std::ios_base::openmode mode
+ = std::ios_base::out) override
+ {
+
+ (void)mode; // Always out
+
+ return seekoff_beg(pos - pos_type(off_type(0)));
+ }
+};
+
+template<class CharT, class Traits>
+class basic_obufferedstream :
+ public std::basic_ostream<CharT, Traits>
+{
+public:
+ typedef typename std::basic_ios<CharT, Traits>::char_type char_type;
+ typedef typename std::basic_ios<char_type, Traits>::int_type int_type;
+ typedef typename std::basic_ios<char_type, Traits>::pos_type pos_type;
+ typedef typename std::basic_ios<char_type, Traits>::off_type off_type;
+ typedef typename std::basic_ios<char_type, Traits>::traits_type traits_type;
+
+private:
+ typedef basic_ovectorbuf<CharT, Traits> base_ouputbuf;
+ typedef std::basic_ios<char_type, Traits> base_ios;
+
+ basic_ovectorbuf<CharT, Traits> buf_;
+
+public:
+ basic_obufferedstream() JSONCONS_NOEXCEPT
+ : std::basic_ostream<CharT, Traits>( (std::basic_streambuf<CharT, Traits>*)(&buf_)),
+ buf_()
+ {}
+ basic_obufferedstream(std::size_t length) JSONCONS_NOEXCEPT
+ : std::basic_ostream<CharT, Traits>( (std::basic_streambuf<CharT, Traits>*)(&buf_)),
+ buf_(length)
+ {}
+
+ basic_obufferedstream(const basic_obufferedstream<CharT,Traits>&) = delete;
+
+ //basic_obufferedstream(basic_obufferedstream<CharT,Traits>&&) = default;
+
+ virtual ~basic_obufferedstream() JSONCONS_NOEXCEPT
+ {
+ }
+
+ basic_obufferedstream<CharT,Traits>& operator=(const basic_obufferedstream<CharT,Traits>&) = delete;
+
+ //basic_obufferedstream<CharT,Traits>& operator=(basic_obufferedstream<CharT,Traits>&&) = default;
+
+ const CharT* data() const
+ {
+ return buf_.data();
+ }
+
+ size_t length() const
+ {
+ return buf_.length();
+ }
+
+ void set_locale(const std::locale& loc)
+ {
+ std::locale result = std::basic_ostream<CharT, Traits>::imbue(loc);
+ //this->pubimbue(loc);
+ }
+
+ void clear_sequence()
+ {
+ this->clear();
+ this->seekp(0, std::ios::beg);
+ }
+};
+
+}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/detail/type_traits_helper.hpp b/vendor/jsoncons-0.104.0/jsoncons/detail/type_traits_helper.hpp
new file mode 100644
index 00000000..4dce8e63
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/detail/type_traits_helper.hpp
@@ -0,0 +1,226 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_DETAIL_TYPETRAITSHELPER_HPP
+#define JSONCONS_DETAIL_TYPETRAITSHELPER_HPP
+
+#include <stdexcept>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <cstdlib>
+#include <cmath>
+#include <cstdarg>
+#include <locale>
+#include <limits>
+#include <type_traits>
+#include <algorithm>
+#include <memory>
+#include <iterator>
+#include <exception>
+#include <array>
+#include <initializer_list>
+#include <jsoncons/jsoncons_config.hpp>
+#include <jsoncons/json_exception.hpp>
+#include <jsoncons/detail/obufferedstream.hpp>
+
+namespace jsoncons
+{
+// static_max
+
+template <size_t arg1, size_t ... argn>
+struct static_max;
+
+template <size_t arg>
+struct static_max<arg>
+{
+ static const size_t value = arg;
+};
+
+template <size_t arg1, size_t arg2, size_t ... argn>
+struct static_max<arg1,arg2,argn ...>
+{
+ static const size_t value = arg1 >= arg2 ?
+ static_max<arg1,argn...>::value :
+ static_max<arg2,argn...>::value;
+};
+
+// type_wrapper
+
+template <class T>
+struct type_wrapper
+{
+ typedef T* pointer_type;
+ typedef const T* const_pointer_type;
+ typedef T value_type;
+ typedef T& reference;
+ typedef const T& const_reference;
+};
+
+template <class T>
+struct type_wrapper<const T>
+{
+ typedef T* pointer_type;
+ typedef const T* const_pointer_type;
+ typedef T value_type;
+ typedef T& reference;
+ typedef const T& const_reference;
+};
+
+template <class T>
+struct type_wrapper<T&>
+{
+ typedef T* pointer_type;
+ typedef const T* const_pointer_type;
+ typedef T value_type;
+ typedef T& reference;
+ typedef const T& const_reference;
+};
+
+template <class T>
+struct type_wrapper<const T&>
+{
+ typedef T* pointer_type;
+ typedef const T* const_pointer_type;
+ typedef T value_type;
+ typedef T& reference;
+ typedef const T& const_reference;
+};
+
+// json_literals
+
+namespace detail {
+JSONCONS_DEFINE_LITERAL(null_literal,"null")
+JSONCONS_DEFINE_LITERAL(true_literal,"true")
+JSONCONS_DEFINE_LITERAL(false_literal,"false")
+}
+
+inline
+unsigned char to_hex_character(unsigned char c)
+{
+ JSONCONS_ASSERT(c <= 0xF);
+
+ return (c < 10) ? ('0' + c) : ('A' - 10 + c);
+}
+
+inline
+bool is_control_character(uint32_t c)
+{
+ return c <= 0x1F || c == 0x7f;
+}
+
+inline
+bool is_non_ascii_codepoint(uint32_t cp)
+{
+ return cp >= 0x80;
+}
+
+template <typename T>
+struct is_stateless
+ : public std::integral_constant<bool,
+ (std::is_default_constructible<T>::value &&
+ std::is_empty<T>::value)>
+{};
+
+// type traits extensions
+
+
+namespace detail {
+
+// to_plain_pointer
+
+template<class Pointer> inline
+typename std::pointer_traits<Pointer>::element_type* to_plain_pointer(Pointer ptr)
+{
+ return (std::addressof(*ptr));
+}
+
+template<class T> inline
+T * to_plain_pointer(T * ptr)
+{
+ return (ptr);
+}
+
+// is_string_like
+
+template <class T, class Enable=void>
+struct is_string_like : std::false_type {};
+
+template <class T>
+struct is_string_like<T,
+ typename std::enable_if<!std::is_void<typename T::traits_type>::value
+>::type> : std::true_type {};
+
+// is_integer_like
+
+template <class T, class Enable=void>
+struct is_integer_like : std::false_type {};
+
+template <class T>
+struct is_integer_like<T,
+ typename std::enable_if<std::is_integral<T>::value &&
+ std::is_signed<T>::value &&
+ !std::is_same<T,bool>::value>::type> : std::true_type {};
+
+// is_uinteger_like
+
+template <class T, class Enable=void>
+struct is_uinteger_like : std::false_type {};
+
+template <class T>
+struct is_uinteger_like<T,
+ typename std::enable_if<std::is_integral<T>::value &&
+ !std::is_signed<T>::value &&
+ !std::is_same<T,bool>::value>::type> : std::true_type {};
+
+// is_floating_point_like
+
+template <class T, class Enable=void>
+struct is_floating_point_like : std::false_type {};
+
+template <class T>
+struct is_floating_point_like<T,
+ typename std::enable_if<std::is_floating_point<T>::value>::type> : std::true_type {};
+
+// is_map_like
+
+template <class T, class Enable=void>
+struct is_map_like : std::false_type {};
+
+template <class T>
+struct is_map_like<T,
+ typename std::enable_if<!std::is_void<typename T::mapped_type>::value>::type>
+ : std::true_type {};
+
+// is_array_like
+template<class T>
+struct is_array_like : std::false_type {};
+
+template<class E, size_t N>
+struct is_array_like<std::array<E, N>> : std::true_type {};
+
+// is_vector_like
+
+template <class T, class Enable=void>
+struct is_vector_like : std::false_type {};
+
+template <class T>
+struct is_vector_like<T,
+ typename std::enable_if<!std::is_void<typename T::value_type>::value &&
+ !is_array_like<T>::value &&
+ !is_string_like<T>::value &&
+ !is_map_like<T>::value
+>::type>
+ : std::true_type {};
+
+}
+
+}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/detail/unicode_traits.hpp b/vendor/jsoncons-0.104.0/jsoncons/detail/unicode_traits.hpp
new file mode 100644
index 00000000..affbb9b7
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/detail/unicode_traits.hpp
@@ -0,0 +1,1463 @@
+// Copyright 2016 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/unicode_traits for latest version
+
+/*
+ * Includes code derived from Unicode, Inc decomposition code in ConvertUTF.h and ConvertUTF.c
+ * http://www.unicode.org/
+ *
+ * "Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard."
+*/
+
+#ifndef UNICONS_UNICODE_TRAITS_HPP
+#define UNICONS_UNICODE_TRAITS_HPP
+
+#if defined (__clang__)
+#if defined(_GLIBCXX_USE_NOEXCEPT)
+#define UNICONS_NOEXCEPT _GLIBCXX_USE_NOEXCEPT
+#else
+#define UNICONS_NOEXCEPT noexcept
+#endif
+#elif defined(__GNUC__)
+#define UNICONS_NOEXCEPT _GLIBCXX_USE_NOEXCEPT
+#elif defined(_MSC_VER)
+#if _MSC_VER >= 1900
+#define UNICONS_NOEXCEPT noexcept
+#else
+#define UNICONS_NOEXCEPT
+#endif
+#else
+#define UNICONS_NOEXCEPT
+#endif
+
+#include <string>
+#include <iterator>
+#include <type_traits>
+#include <system_error>
+
+namespace unicons {
+
+/*
+ * Magic values subtracted from a buffer value during UTF8 conversion.
+ * This table contains as many values as there might be trailing bytes
+ * in a UTF-8 sequence. Source: ConvertUTF.c
+ */
+const uint32_t offsets_from_utf8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
+ 0x03C82080UL, 0xFA082080UL, 0x82082080UL };
+
+/*
+ * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
+ * into the first byte, depending on how many bytes follow. There are
+ * as many entries in this table as there are UTF-8 sequence types.
+ * (I.e., one byte sequence, two byte... etc.). Remember that sequencs
+ * for *legal* UTF-8 will be 4 or fewer bytes total. Source: ConvertUTF.c
+ */
+const uint8_t first_byte_mark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+/*
+ * Index into the table below with the first byte of a UTF-8 sequence to
+ * get the number of trailing bytes that are supposed to follow it.
+ * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
+ * left as-is for anyone who may want to do such conversion, which was
+ * allowed in earlier algorithms. Source: ConvertUTF.c
+ */
+const uint8_t trailing_bytes_for_utf8[256] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
+};
+
+// Some fundamental constants. Source: ConvertUTF.h
+const uint32_t replacement_char = 0x0000FFFD;
+const uint32_t max_bmp = 0x0000FFFF;
+const uint32_t max_utf16 = 0x0010FFFF;
+const uint32_t max_utf32 = 0x7FFFFFFF;
+const uint32_t max_legal_utf32 = 0x0010FFFF;
+
+const int half_shift = 10; // used for shifting by 10 bits
+const uint32_t half_base = 0x0010000UL;
+const uint32_t half_mask = 0x3FFUL;
+
+const uint16_t sur_high_start = 0xD800;
+const uint16_t sur_high_end = 0xDBFF;
+const uint16_t sur_low_start = 0xDC00;
+const uint16_t sur_low_end = 0xDFFF;
+
+inline
+static bool is_continuation_byte(unsigned char ch)
+{
+ return (ch & 0xC0) == 0x80;
+}
+
+inline
+bool is_high_surrogate(uint32_t ch) UNICONS_NOEXCEPT
+{
+ return (ch >= sur_high_start && ch <= sur_high_end);
+}
+
+inline
+bool is_low_surrogate(uint32_t ch) UNICONS_NOEXCEPT
+{
+ return (ch >= sur_low_start && ch <= sur_low_end);
+}
+
+inline
+bool is_surrogate(uint32_t ch) UNICONS_NOEXCEPT
+{
+ return (ch >= sur_high_start && ch <= sur_low_end);
+}
+
+enum class conv_flags
+{
+ strict = 0,
+ lenient
+};
+
+// conv_errc
+
+enum class conv_errc
+{
+ ok = 0,
+ over_long_utf8_sequence = 1, // over long utf8 sequence
+ expected_continuation_byte, // expected continuation byte
+ unpaired_high_surrogate, // unpaired high surrogate UTF-16
+ illegal_surrogate_value, // UTF-16 surrogate values are illegal in UTF-32
+ source_exhausted, // partial character in source, but hit end
+ source_illegal // source sequence is illegal/malformed
+};
+
+class Unicode_traits_error_category_impl_
+ : public std::error_category
+{
+public:
+ virtual const char* name() const UNICONS_NOEXCEPT
+ {
+ return "unicons conversion error";
+ }
+ virtual std::string message(int ev) const
+ {
+ switch (static_cast<conv_errc>(ev))
+ {
+ case conv_errc::over_long_utf8_sequence:
+ return "Over long utf8 sequence";
+ case conv_errc::expected_continuation_byte:
+ return "Expected continuation byte";
+ case conv_errc::unpaired_high_surrogate:
+ return "Unpaired high surrogate UTF-16";
+ case conv_errc::illegal_surrogate_value:
+ return "UTF-16 surrogate values are illegal in UTF-32";
+ case conv_errc::source_exhausted:
+ return "Partial character in source, but hit end";
+ case conv_errc::source_illegal:
+ return "Source sequence is illegal/malformed";
+ default:
+ return "";
+ break;
+ }
+ }
+};
+
+inline
+const std::error_category& unicode_traits_error_category()
+{
+ static Unicode_traits_error_category_impl_ instance;
+ return instance;
+}
+
+inline
+std::error_code make_error_code(conv_errc result)
+{
+ return std::error_code(static_cast<int>(result),unicode_traits_error_category());
+}
+
+// encoding_errc
+
+enum class encoding_errc
+{
+ ok = 0,
+ expected_u8_found_u16 = 1,
+ expected_u8_found_u32,
+ expected_u16_found_fffe,
+ expected_u32_found_fffe
+};
+
+class Encoding_errc_impl_
+ : public std::error_category
+{
+public:
+ virtual const char* name() const UNICONS_NOEXCEPT
+ {
+ return "unicons encoding error";
+ }
+ virtual std::string message(int ev) const
+ {
+ switch (static_cast<encoding_errc>(ev))
+ {
+ case encoding_errc::expected_u8_found_u16:
+ return "Expected UTF-8, found UTF-16";
+ case encoding_errc::expected_u8_found_u32:
+ return "Expected UTF-8, found UTF-32";
+ case encoding_errc::expected_u16_found_fffe:
+ return "Expected UTF-16, found non character";
+ case encoding_errc::expected_u32_found_fffe:
+ return "Expected UTF-32, found non character";
+ default:
+ return "";
+ break;
+ }
+ }
+};
+
+inline
+const std::error_category& encoding_error_category()
+{
+ static Encoding_errc_impl_ instance;
+ return instance;
+}
+
+inline
+std::error_code make_error_code(encoding_errc result)
+{
+ return std::error_code(static_cast<int>(result),encoding_error_category());
+}
+}
+
+namespace std {
+ template<>
+ struct is_error_code_enum<unicons::conv_errc> : public true_type
+ {
+ };
+ template<>
+ struct is_error_code_enum<unicons::encoding_errc> : public true_type
+ {
+ };
+}
+
+namespace unicons {
+
+// utf8
+
+template <class Iterator>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<Iterator>::value_type>::value
+ && sizeof(typename std::iterator_traits<Iterator>::value_type) == sizeof(uint8_t),
+ conv_errc >::type
+is_legal_utf8(Iterator first, size_t length)
+{
+ uint8_t a;
+ Iterator srcptr = first+length;
+ switch (length) {
+ default:
+ return conv_errc::over_long_utf8_sequence;
+ case 4:
+ if (((a = (*--srcptr))& 0xC0) != 0x80)
+ return conv_errc::expected_continuation_byte;
+ // FALLTHRU
+ case 3:
+ if (((a = (*--srcptr))& 0xC0) != 0x80)
+ return conv_errc::expected_continuation_byte;
+ // FALLTHRU
+ case 2:
+ if (((a = (*--srcptr))& 0xC0) != 0x80)
+ return conv_errc::expected_continuation_byte;
+
+ switch (static_cast<uint8_t>(*first))
+ {
+ /* no fall-through in this inner switch */
+ case 0xE0: if (a < 0xA0) return conv_errc::source_illegal; break;
+ case 0xED: if (a > 0x9F) return conv_errc::source_illegal; break;
+ case 0xF0: if (a < 0x90) return conv_errc::source_illegal; break;
+ case 0xF4: if (a > 0x8F) return conv_errc::source_illegal; break;
+ default: if (a < 0x80) return conv_errc::source_illegal;
+ }
+
+ // FALLTHRU
+ case 1:
+ if (static_cast<uint8_t>(*first) >= 0x80 && static_cast<uint8_t>(*first) < 0xC2)
+ return conv_errc::source_illegal;
+ // FALLTHRU
+ }
+ if (static_cast<uint8_t>(*first) > 0xF4)
+ return conv_errc::source_illegal;
+
+ return conv_errc();
+}
+
+template <class...> using void_t = void;
+
+template <class, class, class = void>
+struct is_output_iterator : std::false_type {};
+
+template <class I, class E>
+struct is_output_iterator<I, E, void_t<
+ typename std::iterator_traits<I>::iterator_category,
+ decltype(*std::declval<I>() = std::declval<E>())>> : std::true_type {};
+
+// is_same_size fixes issue with vs2013
+
+// primary template
+template<class T1, class T2, class Enable = void>
+struct is_same_size : std::false_type
+{
+};
+
+// specialization for non void types
+template<class T1, class T2>
+struct is_same_size<T1, T2, typename std::enable_if<!std::is_void<T1>::value && !std::is_void<T2>::value>::type>
+{
+ static const bool value = (sizeof(T1) == sizeof(T2));
+};
+
+template<class OutputIt, class CharT, class Enable = void>
+struct is_compatible_output_iterator : std::false_type {};
+
+template<class OutputIt, class CharT>
+struct is_compatible_output_iterator<OutputIt,CharT,
+ typename std::enable_if<is_output_iterator<OutputIt,CharT>::value
+ && std::is_void<typename std::iterator_traits<OutputIt>::value_type>::value
+ && std::is_integral<typename OutputIt::container_type::value_type>::value
+ && !std::is_void<typename OutputIt::container_type::value_type>::value
+ && is_same_size<typename OutputIt::container_type::value_type,CharT>::value>::type
+> : std::true_type {};
+
+template<class OutputIt, class CharT>
+struct is_compatible_output_iterator<OutputIt,CharT,
+ typename std::enable_if<is_output_iterator<OutputIt,CharT>::value
+ && std::is_integral<typename std::iterator_traits<OutputIt>::value_type>::value
+ && is_same_size<typename std::iterator_traits<OutputIt>::value_type,CharT>::value>::type
+> : std::true_type {};
+
+template<class OutputIt, class CharT>
+struct is_compatible_output_iterator<OutputIt,CharT,
+ typename std::enable_if<is_output_iterator<OutputIt,CharT>::value
+ && std::is_void<typename std::iterator_traits<OutputIt>::value_type>::value
+ && is_same_size<typename OutputIt::char_type,CharT>::value>::type
+> : std::true_type {};
+
+// convert
+
+template <class Iterator>
+struct convert_result
+{
+ Iterator it;
+ conv_errc ec;
+};
+
+template <class InputIt,class OutputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value && sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint8_t)
+ && is_compatible_output_iterator<OutputIt,uint8_t>::value,convert_result<InputIt>>::type
+convert(InputIt first, InputIt last, OutputIt target, conv_flags flags=conv_flags::strict)
+{
+ (void)flags;
+
+ conv_errc result = conv_errc();
+ while (first != last)
+ {
+ size_t length = trailing_bytes_for_utf8[static_cast<uint8_t>(*first)] + 1;
+ if (length > (size_t)(last - first))
+ {
+ return convert_result<InputIt>{first, conv_errc::source_exhausted};
+ }
+ if ((result=is_legal_utf8(first, length)) != conv_errc())
+ {
+ return convert_result<InputIt>{first,result};
+ }
+
+ switch (length) {
+ case 4: *target++ = (static_cast<uint8_t>(*first++));
+ case 3: *target++ = (static_cast<uint8_t>(*first++));
+ case 2: *target++ = (static_cast<uint8_t>(*first++));
+ case 1: *target++ = (static_cast<uint8_t>(*first++));
+ }
+ }
+ return convert_result<InputIt>{first,result} ;
+}
+
+template <class InputIt,class OutputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value && sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint8_t)
+ && is_compatible_output_iterator<OutputIt,uint16_t>::value,convert_result<InputIt>>::type
+convert(InputIt first, InputIt last,
+ OutputIt target,
+ conv_flags flags = conv_flags::strict)
+{
+ conv_errc result = conv_errc();
+
+ while (first != last)
+ {
+ uint32_t ch = 0;
+ unsigned short extra_bytes_to_read = trailing_bytes_for_utf8[static_cast<uint8_t>(*first)];
+ if (extra_bytes_to_read >= last - first)
+ {
+ result = conv_errc::source_exhausted;
+ break;
+ }
+ /* Do this check whether lenient or strict */
+ if ((result=is_legal_utf8(first, extra_bytes_to_read+1)) != conv_errc())
+ {
+ break;
+ }
+ /*
+ * The cases all fall through. See "Note A" below.
+ */
+ switch (extra_bytes_to_read) {
+ case 5: ch += static_cast<uint8_t>(*first++); ch <<= 6; /* remember, illegal UTF-8 */
+ case 4: ch += static_cast<uint8_t>(*first++); ch <<= 6; /* remember, illegal UTF-8 */
+ case 3: ch += static_cast<uint8_t>(*first++); ch <<= 6;
+ case 2: ch += static_cast<uint8_t>(*first++); ch <<= 6;
+ case 1: ch += static_cast<uint8_t>(*first++); ch <<= 6;
+ case 0: ch += static_cast<uint8_t>(*first++);
+ }
+ ch -= offsets_from_utf8[extra_bytes_to_read];
+
+ if (ch <= max_bmp) { /* Target is a character <= 0xFFFF */
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (is_surrogate(ch) ) {
+ if (flags == conv_flags::strict) {
+ first -= (extra_bytes_to_read+1); /* return to the illegal value itself */
+ result = conv_errc::source_illegal;
+ break;
+ } else {
+ *target++ = (replacement_char);
+ }
+ } else {
+ *target++ = ((uint16_t)ch); /* normal case */
+ }
+ } else if (ch > max_utf16) {
+ if (flags == conv_flags::strict) {
+ result = conv_errc::source_illegal;
+ first -= (extra_bytes_to_read+1); /* return to the start */
+ break; /* Bail out; shouldn't continue */
+ } else {
+ *target++ = (replacement_char);
+ }
+ } else {
+ /* target is a character in range 0xFFFF - 0x10FFFF. */
+ ch -= half_base;
+ *target++ = ((uint16_t)((ch >> half_shift) + sur_high_start));
+ *target++ = ((uint16_t)((ch & half_mask) + sur_low_start));
+ }
+ }
+ return convert_result<InputIt>{first,result} ;
+}
+
+template <class InputIt,class OutputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value && sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint8_t)
+ && is_compatible_output_iterator<OutputIt,uint32_t>::value,convert_result<InputIt>>::type
+convert(InputIt first, InputIt last,
+ OutputIt target,
+ conv_flags flags = conv_flags::strict)
+{
+ conv_errc result = conv_errc();
+
+ while (first < last)
+ {
+ uint32_t ch = 0;
+ unsigned short extra_bytes_to_read = trailing_bytes_for_utf8[static_cast<uint8_t>(*first)];
+ if (extra_bytes_to_read >= last - first)
+ {
+ result = conv_errc::source_exhausted;
+ break;
+ }
+ /* Do this check whether lenient or strict */
+ if ((result=is_legal_utf8(first, extra_bytes_to_read+1)) != conv_errc()) {
+ break;
+ }
+ /*
+ * The cases all fall through. See "Note A" below.
+ */
+ switch (extra_bytes_to_read) {
+ case 5: ch += static_cast<uint8_t>(*first++); ch <<= 6;
+ case 4: ch += static_cast<uint8_t>(*first++); ch <<= 6;
+ case 3: ch += static_cast<uint8_t>(*first++); ch <<= 6;
+ case 2: ch += static_cast<uint8_t>(*first++); ch <<= 6;
+ case 1: ch += static_cast<uint8_t>(*first++); ch <<= 6;
+ case 0: ch += static_cast<uint8_t>(*first++);
+ }
+ ch -= offsets_from_utf8[extra_bytes_to_read];
+
+ if (ch <= max_legal_utf32) {
+ /*
+ * UTF-16 surrogate values are illegal in UTF-32, and anything
+ * over Plane 17 (> 0x10FFFF) is illegal.
+ */
+ if (is_surrogate(ch) ) {
+ if (flags == conv_flags::strict) {
+ first -= (extra_bytes_to_read+1); /* return to the illegal value itself */
+ result = conv_errc::source_illegal;
+ break;
+ } else {
+ *target++ = (replacement_char);
+ }
+ } else {
+ *target++ = (ch);
+ }
+ } else { /* i.e., ch > max_legal_utf32 */
+ result = conv_errc::source_illegal;
+ *target++ = (replacement_char);
+ }
+ }
+ return convert_result<InputIt>{first,result} ;
+}
+
+// utf16
+
+template <class InputIt,class OutputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value && sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint16_t)
+ && is_compatible_output_iterator<OutputIt,uint8_t>::value,convert_result<InputIt>>::type
+convert(InputIt first, InputIt last,
+ OutputIt target,
+ conv_flags flags = conv_flags::strict) {
+ conv_errc result = conv_errc();
+ while (first < last) {
+ unsigned short bytes_to_write = 0;
+ const uint32_t byteMask = 0xBF;
+ const uint32_t byteMark = 0x80;
+ uint32_t ch = *first++;
+ /* If we have a surrogate pair, convert to uint32_t first. */
+ if (is_high_surrogate(ch)) {
+ /* If the 16 bits following the high surrogate are in the first buffer... */
+ if (first < last) {
+ uint32_t ch2 = *first;
+ /* If it's a low surrogate, convert to uint32_t. */
+ if (ch2 >= sur_low_start && ch2 <= sur_low_end) {
+ ch = ((ch - sur_high_start) << half_shift)
+ + (ch2 - sur_low_start) + half_base;
+ ++first;
+ } else if (flags == conv_flags::strict) { /* it's an unpaired high surrogate */
+ --first; /* return to the illegal value itself */
+ result = conv_errc::unpaired_high_surrogate;
+ break;
+ }
+ } else { /* We don't have the 16 bits following the high surrogate. */
+ --first; /* return to the high surrogate */
+ result = conv_errc::source_exhausted;
+ break;
+ }
+ } else if (flags == conv_flags::strict) {
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (is_low_surrogate(ch)) {
+ --first; /* return to the illegal value itself */
+ result = conv_errc::source_illegal;
+ break;
+ }
+ }
+ /* Figure out how many bytes the result will require */
+ if (ch < (uint32_t)0x80) {
+ bytes_to_write = 1;
+ } else if (ch < (uint32_t)0x800) {
+ bytes_to_write = 2;
+ } else if (ch < (uint32_t)0x10000) {
+ bytes_to_write = 3;
+ } else if (ch < (uint32_t)0x110000) {
+ bytes_to_write = 4;
+ } else {
+ bytes_to_write = 3;
+ ch = replacement_char;
+ }
+
+ uint8_t byte1 = 0;
+ uint8_t byte2 = 0;
+ uint8_t byte3 = 0;
+ uint8_t byte4 = 0;
+
+ switch (bytes_to_write) { // note: everything falls through
+ case 4: byte4 = (uint8_t)((ch | byteMark) & byteMask); ch >>= 6;
+ case 3: byte3 = (uint8_t)((ch | byteMark) & byteMask); ch >>= 6;
+ case 2: byte2 = (uint8_t)((ch | byteMark) & byteMask); ch >>= 6;
+ case 1: byte1 = (uint8_t)(ch | first_byte_mark[bytes_to_write]);
+ }
+ switch (bytes_to_write)
+ {
+ case 4:
+ *target++ = (byte1);
+ *target++ = (byte2);
+ *target++ = (byte3);
+ *target++ = (byte4);
+ break;
+ case 3:
+ *target++ = (byte1);
+ *target++ = (byte2);
+ *target++ = (byte3);
+ break;
+ case 2:
+ *target++ = (byte1);
+ *target++ = (byte2);
+ break;
+ case 1:
+ *target++ = (byte1);
+ break;
+ }
+ }
+ return convert_result<InputIt>{first,result} ;
+}
+
+template <class InputIt,class OutputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value && sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint16_t)
+ && is_compatible_output_iterator<OutputIt,uint16_t>::value,convert_result<InputIt>>::type
+convert(InputIt first, InputIt last,
+ OutputIt target,
+ conv_flags flags = conv_flags::strict)
+{
+ conv_errc result = conv_errc();
+
+ while (first != last)
+ {
+ uint32_t ch = *first++;
+ /* If we have a surrogate pair, convert to uint32_t first. */
+ if (is_high_surrogate(ch))
+ {
+ /* If the 16 bits following the high surrogate are in the first buffer... */
+ if (first < last) {
+ uint32_t ch2 = *first;
+ /* If it's a low surrogate, */
+ if (ch2 >= sur_low_start && ch2 <= sur_low_end) {
+ *target++ = ((uint16_t)ch);
+ *target++ = ((uint16_t)ch2);
+ ++first;
+ } else if (flags == conv_flags::strict) { /* it's an unpaired high surrogate */
+ --first; /* return to the illegal value itself */
+ result = conv_errc::unpaired_high_surrogate;
+ break;
+ }
+ } else { /* We don't have the 16 bits following the high surrogate. */
+ --first; /* return to the high surrogate */
+ result = conv_errc::source_exhausted;
+ break;
+ }
+ } else if (is_low_surrogate(ch))
+ {
+ // illegal leading low surrogate
+ if (flags == conv_flags::strict) {
+ --first; /* return to the illegal value itself */
+ result = conv_errc::source_illegal;
+ break;
+ }
+ else
+ {
+ *target++ = ((uint16_t)ch);
+ }
+ }
+ else
+ {
+ *target++ = ((uint16_t)ch);
+ }
+ }
+ return convert_result<InputIt>{first,result} ;
+}
+
+template <class InputIt,class OutputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value && sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint16_t)
+ && is_compatible_output_iterator<OutputIt,uint32_t>::value,convert_result<InputIt>>::type
+convert(InputIt first, InputIt last,
+ OutputIt target,
+ conv_flags flags = conv_flags::strict)
+{
+ conv_errc result = conv_errc();
+
+ while (first != last)
+ {
+ uint32_t ch = *first++;
+ /* If we have a surrogate pair, convert to UTF32 first. */
+ if (is_high_surrogate(ch)) {
+ /* If the 16 bits following the high surrogate are in the first buffer... */
+ if (first < last) {
+ uint32_t ch2 = *first;
+ /* If it's a low surrogate, convert to UTF32. */
+ if (ch2 >= sur_low_start && ch2 <= sur_low_end ) {
+ ch = ((ch - sur_high_start) << half_shift)
+ + (ch2 - sur_low_start) + half_base;
+ ++first;
+ } else if (flags == conv_flags::strict) { /* it's an unpaired high surrogate */
+ --first; /* return to the illegal value itself */
+ result = conv_errc::source_illegal;
+ break;
+ }
+ } else { /* We don't have the 16 bits following the high surrogate. */
+ --first; /* return to the high surrogate */
+ result = conv_errc::source_exhausted;
+ break;
+ }
+ } else if (flags == conv_flags::strict) {
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (is_low_surrogate(ch) ) {
+ --first; /* return to the illegal value itself */
+ result = conv_errc::source_illegal;
+ break;
+ }
+ }
+ *target++ = (ch);
+ }
+ return convert_result<InputIt>{first,result} ;
+}
+
+// utf32
+
+template <class InputIt,class OutputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value && sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint32_t)
+ && is_compatible_output_iterator<OutputIt,uint8_t>::value,convert_result<InputIt>>::type
+convert(InputIt first, InputIt last,
+ OutputIt target,
+ conv_flags flags = conv_flags::strict)
+{
+ conv_errc result = conv_errc();
+ while (first < last) {
+ unsigned short bytes_to_write = 0;
+ const uint32_t byteMask = 0xBF;
+ const uint32_t byteMark = 0x80;
+ uint32_t ch = *first++;
+ if (flags == conv_flags::strict ) {
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (is_surrogate(ch)) {
+ --first; /* return to the illegal value itself */
+ result = conv_errc::illegal_surrogate_value;
+ break;
+ }
+ }
+ /*
+ * Figure out how many bytes the result will require. Turn any
+ * illegally large UTF32 things (> Plane 17) into replacement chars.
+ */
+ if (ch < (uint32_t)0x80) { bytes_to_write = 1;
+ } else if (ch < (uint32_t)0x800) { bytes_to_write = 2;
+ } else if (ch < (uint32_t)0x10000) { bytes_to_write = 3;
+ } else if (ch <= max_legal_utf32) { bytes_to_write = 4;
+ } else {
+ bytes_to_write = 3;
+ ch = replacement_char;
+ result = conv_errc::source_illegal;
+ }
+
+ uint8_t byte1 = 0;
+ uint8_t byte2 = 0;
+ uint8_t byte3 = 0;
+ uint8_t byte4 = 0;
+
+ switch (bytes_to_write) {
+ case 4:
+ byte4 = (uint8_t)((ch | byteMark) & byteMask); ch >>= 6;
+ // FALLTHRU
+ case 3:
+ byte3 = (uint8_t)((ch | byteMark) & byteMask); ch >>= 6;
+ // FALLTHRU
+ case 2:
+ byte2 = (uint8_t)((ch | byteMark) & byteMask); ch >>= 6;
+ // FALLTHRU
+ case 1:
+ byte1 = (uint8_t) (ch | first_byte_mark[bytes_to_write]);
+ }
+
+ switch (bytes_to_write)
+ {
+ case 4:
+ *target++ = (byte1);
+ *target++ = (byte2);
+ *target++ = (byte3);
+ *target++ = (byte4);
+ break;
+ case 3:
+ *target++ = (byte1);
+ *target++ = (byte2);
+ *target++ = (byte3);
+ break;
+ case 2:
+ *target++ = (byte1);
+ *target++ = (byte2);
+ break;
+ case 1:
+ *target++ = (byte1);
+ break;
+ }
+ }
+ return convert_result<InputIt>{first,result} ;
+}
+
+template <class InputIt,class OutputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value && sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint32_t)
+ && is_compatible_output_iterator<OutputIt,uint16_t>::value,convert_result<InputIt>>::type
+convert(InputIt first, InputIt last,
+ OutputIt target,
+ conv_flags flags = conv_flags::strict)
+{
+ conv_errc result = conv_errc();
+
+ while (first != last)
+ {
+ uint32_t ch = *first++;
+ if (ch <= max_bmp) { /* Target is a character <= 0xFFFF */
+ /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
+ if (is_surrogate(ch) ) {
+ if (flags == conv_flags::strict) {
+ --first; /* return to the illegal value itself */
+ result = conv_errc::source_illegal;
+ break;
+ } else {
+ *target++ = (replacement_char);
+ }
+ } else {
+ *target++ = ((uint16_t)ch); /* normal case */
+ }
+ } else if (ch > max_legal_utf32) {
+ if (flags == conv_flags::strict) {
+ result = conv_errc::source_illegal;
+ } else {
+ *target++ = (replacement_char);
+ }
+ } else {
+ /* target is a character in range 0xFFFF - 0x10FFFF. */
+ ch -= half_base;
+ *target++ = ((uint16_t)((ch >> half_shift) + sur_high_start));
+ *target++ = ((uint16_t)((ch & half_mask) + sur_low_start));
+ }
+ }
+ return convert_result<InputIt>{first,result} ;
+}
+
+template <class InputIt,class OutputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value && sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint32_t)
+ && is_compatible_output_iterator<OutputIt,uint32_t>::value,convert_result<InputIt>>::type
+convert(InputIt first, InputIt last,
+ OutputIt target,
+ conv_flags flags = conv_flags::strict)
+{
+ conv_errc result = conv_errc();
+
+ while (first != last)
+ {
+ uint32_t ch = *first++;
+ if (flags == conv_flags::strict ) {
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (is_surrogate(ch)) {
+ --first; /* return to the illegal value itself */
+ result = conv_errc::illegal_surrogate_value;
+ break;
+ }
+ }
+ if (ch <= max_legal_utf32)
+ {
+ *target++ = (ch);
+ }
+ else
+ {
+ *target++ = (replacement_char);
+ result = conv_errc::source_illegal;
+ }
+ }
+ return convert_result<InputIt>{first,result} ;
+}
+
+// validate
+
+template <class InputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value && sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint8_t)
+ ,convert_result<InputIt>>::type
+validate(InputIt first, InputIt last) UNICONS_NOEXCEPT
+{
+ conv_errc result = conv_errc();
+ while (first != last)
+ {
+ size_t length = trailing_bytes_for_utf8[static_cast<uint8_t>(*first)] + 1;
+ if (length > (size_t)(last - first))
+ {
+ return convert_result<InputIt>{first, conv_errc::source_exhausted};
+ }
+ if ((result=is_legal_utf8(first, length)) != conv_errc())
+ {
+ return convert_result<InputIt>{first,result} ;
+ }
+ first += length;
+ }
+ return convert_result<InputIt>{first,result} ;
+}
+
+// utf16
+
+template <class InputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value && sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint16_t)
+ ,convert_result<InputIt>>::type
+validate(InputIt first, InputIt last) UNICONS_NOEXCEPT
+{
+ conv_errc result = conv_errc();
+
+ while (first != last)
+ {
+ uint32_t ch = *first++;
+ /* If we have a surrogate pair, validate to uint32_t first. */
+ if (is_high_surrogate(ch))
+ {
+ /* If the 16 bits following the high surrogate are in the first buffer... */
+ if (first < last) {
+ uint32_t ch2 = *first;
+ /* If it's a low surrogate, */
+ if (ch2 >= sur_low_start && ch2 <= sur_low_end) {
+ ++first;
+ } else {
+ --first; /* return to the illegal value itself */
+ result = conv_errc::unpaired_high_surrogate;
+ break;
+ }
+ } else { /* We don't have the 16 bits following the high surrogate. */
+ --first; /* return to the high surrogate */
+ result = conv_errc::source_exhausted;
+ break;
+ }
+ } else if (is_low_surrogate(ch))
+ {
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ --first; /* return to the illegal value itself */
+ result = conv_errc::source_illegal;
+ break;
+ }
+ }
+ return convert_result<InputIt>{first,result} ;
+}
+
+
+// utf32
+
+
+template <class InputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value && sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint32_t)
+ ,convert_result<InputIt>>::type
+validate(InputIt first, InputIt last) UNICONS_NOEXCEPT
+{
+ conv_errc result = conv_errc();
+
+ while (first != last)
+ {
+ uint32_t ch = *first++;
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (is_surrogate(ch)) {
+ --first; /* return to the illegal value itself */
+ result = conv_errc::illegal_surrogate_value;
+ break;
+ }
+ if (!(ch <= max_legal_utf32))
+ {
+ result = conv_errc::source_illegal;
+ }
+ }
+ return convert_result<InputIt>{first,result} ;
+}
+
+// sequence
+
+template <class Iterator>
+class sequence
+{
+ Iterator first_;
+ size_t length_;
+public:
+ sequence(Iterator first, size_t length)
+ : first_(first), length_(length)
+ {
+ }
+
+ Iterator begin() const
+ {
+ return first_;
+ }
+
+ size_t length() const
+ {
+ return length_;
+ }
+
+ template <class CharT = typename std::iterator_traits<Iterator>::value_type>
+ typename std::enable_if<sizeof(CharT) == sizeof(uint8_t),uint32_t>::type
+ codepoint() const UNICONS_NOEXCEPT
+ {
+ uint32_t ch = 0;
+ Iterator it = first_;
+ switch (length_)
+ {
+ default:
+ return replacement_char;
+ break;
+ case 4:
+ ch += static_cast<uint8_t>(*it++); ch <<= 6;
+ // FALLTHRU
+ case 3:
+ ch += static_cast<uint8_t>(*it++); ch <<= 6;
+ // FALLTHRU
+ case 2:
+ ch += static_cast<uint8_t>(*it++); ch <<= 6;
+ // FALLTHRU
+ case 1:
+ ch += static_cast<uint8_t>(*it++);
+ ch -= offsets_from_utf8[length_ - 1];
+ break;
+ }
+ if (ch <= max_legal_utf32)
+ {
+ if (is_surrogate(ch))
+ {
+ ch = replacement_char;
+ }
+ }
+ else // ch > max_legal_utf32
+ {
+ ch = replacement_char;
+ }
+ return ch;
+ }
+
+ template <class CharT = typename std::iterator_traits<Iterator>::value_type>
+ typename std::enable_if<sizeof(CharT) == sizeof(uint16_t),uint32_t>::type
+ codepoint() const UNICONS_NOEXCEPT
+ {
+ if (length_ == 0)
+ {
+ return replacement_char;
+ }
+ if (length_ == 2)
+ {
+ uint32_t ch = *first_;
+ uint32_t ch2 = *(first_+ 1);
+ ch = ((ch - sur_high_start) << half_shift)
+ + (ch2 - sur_low_start) + half_base;
+ return ch;
+ }
+ else
+ {
+ return *first_;
+ }
+ }
+
+ template <class CharT = typename std::iterator_traits<Iterator>::value_type>
+ typename std::enable_if<sizeof(CharT) == sizeof(uint32_t),uint32_t>::type
+ codepoint() const UNICONS_NOEXCEPT
+ {
+ if (length_ == 0)
+ {
+ return replacement_char;
+ }
+ return *(first_);
+ }
+};
+
+// sequence_generator
+
+template <class Iterator>
+class sequence_generator
+{
+ Iterator begin_;
+ Iterator last_;
+ conv_flags flags_;
+ size_t length_;
+ conv_errc err_cd_;
+public:
+ typedef sequence<Iterator> sequence_type;
+
+ sequence_generator(Iterator first, Iterator last,
+ conv_flags flags = conv_flags::strict) UNICONS_NOEXCEPT
+ : begin_(first), last_(last), flags_(flags),
+ length_(0), err_cd_(conv_errc())
+ {
+ next();
+ }
+
+ bool done() const UNICONS_NOEXCEPT
+ {
+ return err_cd_ != conv_errc() || begin_ == last_;
+ }
+
+ conv_errc status() const UNICONS_NOEXCEPT
+ {
+ return err_cd_;
+ }
+
+ sequence_type get() const UNICONS_NOEXCEPT
+ {
+ return sequence<Iterator>(begin_,length_);
+ }
+
+ template <class CharT = typename std::iterator_traits<Iterator>::value_type>
+ typename std::enable_if<sizeof(CharT) == sizeof(uint8_t)>::type
+ next() UNICONS_NOEXCEPT
+ {
+ begin_ += length_;
+ if (begin_ != last_)
+ {
+ size_t length = trailing_bytes_for_utf8[static_cast<uint8_t>(*begin_)] + 1;
+ if (length > (size_t)(last_ - begin_))
+ {
+ err_cd_ = conv_errc::source_exhausted;
+ }
+ else if ((err_cd_ = is_legal_utf8(begin_, length)) != conv_errc())
+ {
+ }
+ else
+ {
+ length_ = length;
+ }
+ }
+ }
+
+ template <class CharT = typename std::iterator_traits<Iterator>::value_type>
+ typename std::enable_if<sizeof(CharT) == sizeof(uint16_t)>::type
+ next() UNICONS_NOEXCEPT
+ {
+ begin_ += length_;
+ if (begin_ != last_)
+ {
+ if (begin_ != last_)
+ {
+
+ Iterator it = begin_;
+
+ uint32_t ch = *it++;
+ /* If we have a surrogate pair, validate to uint32_t it. */
+ if (is_high_surrogate(ch))
+ {
+ /* If the 16 bits following the high surrogate are in the it buffer... */
+ if (it < last_) {
+ uint32_t ch2 = *it;
+ /* If it's a low surrogate, */
+ if (ch2 >= sur_low_start && ch2 <= sur_low_end)
+ {
+ ++it;
+ length_ = 2;
+ }
+ else
+ {
+ err_cd_ = conv_errc::unpaired_high_surrogate;
+ }
+ }
+ else
+ {
+ // We don't have the 16 bits following the high surrogate.
+ err_cd_ = conv_errc::source_exhausted;
+ }
+ }
+ else if (is_low_surrogate(ch))
+ {
+ /* leading low surrogate */
+ err_cd_ = conv_errc::source_illegal;
+ }
+ else
+ {
+ length_ = 1;
+ }
+ }
+ }
+ }
+
+ template <class CharT = typename std::iterator_traits<Iterator>::value_type>
+ typename std::enable_if<sizeof(CharT) == sizeof(uint32_t)>::type
+ next() UNICONS_NOEXCEPT
+ {
+ begin_ += length_;
+ length_ = 1;
+ }
+};
+
+template <class Iterator>
+sequence_generator<Iterator> make_sequence_generator(Iterator first, Iterator last,
+ conv_flags flags = conv_flags::strict)
+{
+ return sequence_generator<Iterator>(first, last, flags);
+}
+
+template <class InputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value
+ && (sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint8_t) || sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint16_t)),
+ sequence<InputIt>>::type
+sequence_at(InputIt first, InputIt last, size_t index)
+{
+ sequence_generator<InputIt> g(first, last, unicons::conv_flags::strict);
+
+ size_t count = 0;
+ while (!g.done() && count < index)
+ {
+ g.next();
+ ++count;
+ }
+ return (!g.done() && count == index) ? g.get() : sequence<InputIt>(last,0);
+}
+
+template <class InputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value && sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint32_t),
+ sequence<InputIt>>::type
+sequence_at(InputIt first, InputIt last, size_t index)
+{
+ size_t size = std::distance(first,last);
+ return index < size ? sequence<InputIt>(first+index,1) : sequence<InputIt>(last,0);
+}
+
+// u8_length
+
+template <class InputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value && sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint8_t),size_t>::type
+u8_length(InputIt first, InputIt last) UNICONS_NOEXCEPT
+{
+ return std::distance(first,last);
+}
+
+// utf16
+
+template <class InputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value && sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint16_t),size_t>::type
+u8_length(InputIt first, InputIt last) UNICONS_NOEXCEPT
+{
+ conv_flags flags = conv_flags::strict;
+ size_t count = 0;
+ for (InputIt p = first; p != last; ++p)
+ {
+ uint32_t ch = *p;
+ if (is_high_surrogate(ch)) {
+ /* If the 16 bits following the high surrogate are in the p buffer... */
+ if (p < last) {
+ uint32_t ch2 = *(++p);
+ /* If it's a low surrogate, convert to uint32_t. */
+ if (ch2 >= sur_low_start && ch2 <= sur_low_end) {
+ ch = ((ch - sur_high_start) << half_shift)
+ + (ch2 - sur_low_start) + half_base;
+
+ } else if (flags == conv_flags::strict) { /* it's an unpaired high surrogate */
+ break;
+ }
+ } else { /* We don't have the 16 bits following the high surrogate. */
+ break;
+ }
+ } else if (flags == conv_flags::strict) {
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (is_low_surrogate(ch)) {
+ break;
+ }
+ }
+ if (ch < (uint32_t)0x80) {
+ ++count;
+ } else if (ch < (uint32_t)0x800) {
+ count += 2;
+ } else if (ch < (uint32_t)0x10000) {
+ count += 3;
+ } else if (ch < (uint32_t)0x110000) {
+ count += 4;
+ } else {
+ count += 3;
+ }
+ }
+ return count;
+}
+
+
+// utf32
+
+template <class InputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value && sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint32_t),size_t>::type
+u8_length(InputIt first, InputIt last) UNICONS_NOEXCEPT
+{
+ size_t count = 0;
+ for (InputIt p = first; p < last; ++p)
+ {
+ uint32_t ch = *p;
+ if (ch < (uint32_t)0x80) {
+ ++count;
+ } else if (ch < (uint32_t)0x800) {
+ count += 2;
+ } else if (ch < (uint32_t)0x10000) {
+ count += 3;
+ } else if (ch <= max_legal_utf32) {
+ count += 4;
+ } else {
+ count += 3;
+ }
+ }
+ return count;
+}
+
+// u32_length
+
+template <class InputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value
+ && (sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint8_t) || sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint16_t)),
+ size_t>::type
+u32_length(InputIt first, InputIt last) UNICONS_NOEXCEPT
+{
+ sequence_generator<InputIt> g(first, last, unicons::conv_flags::strict);
+
+ size_t count = 0;
+ while (!g.done())
+ {
+ g.next();
+ ++count;
+ }
+ return count;
+}
+
+template <class InputIt>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<InputIt>::value_type>::value && sizeof(typename std::iterator_traits<InputIt>::value_type) == sizeof(uint32_t),
+ size_t>::type
+u32_length(InputIt first, InputIt last) UNICONS_NOEXCEPT
+{
+ return std::distance(first,last);
+}
+
+enum class encoding {u8,u16le,u16be,u32le,u32be,undetected};
+
+template <class Iterator>
+struct detect_encoding_result
+{
+ Iterator it;
+ encoding ec;
+};
+
+template <class Iterator>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<Iterator>::value_type>::value && sizeof(typename std::iterator_traits<Iterator>::value_type) == sizeof(uint8_t),
+ detect_encoding_result<Iterator>>::type
+detect_encoding(Iterator first, Iterator last) UNICONS_NOEXCEPT
+{
+ Iterator it1 = first;
+ if (std::distance(first,last) < 4)
+ {
+ if (std::distance(first,last) == 3)
+ {
+ Iterator it2 = ++first;
+ Iterator it3 = ++first;
+ if (static_cast<uint8_t>(*it1) == 0xEF && static_cast<uint8_t>(*it2) == 0xBB && static_cast<uint8_t>(*it3) == 0xBF)
+ {
+ return detect_encoding_result<Iterator>{last,encoding::u8};
+ }
+ }
+ return detect_encoding_result<Iterator>{it1,encoding::undetected};
+ }
+ else
+ {
+ Iterator it2 = ++first;
+ Iterator it3 = ++first;
+ Iterator it4 = ++first;
+
+ uint32_t bom = static_cast<uint8_t>(*it1) | (static_cast<uint8_t>(*it2) << 8) | (static_cast<uint8_t>(*it3) << 16) | (static_cast<uint8_t>(*it4) << 24);
+ if (bom == 0xFFFE0000)
+ {
+ return detect_encoding_result<Iterator>{it4++,encoding::u32be};
+ }
+ else if (bom == 0x0000FEFF)
+ {
+ return detect_encoding_result<Iterator>{first,encoding::u32le};
+ }
+ else if ((bom & 0xFFFF) == 0xFFFE)
+ {
+ return detect_encoding_result<Iterator>{it3,encoding::u16be};
+ }
+ else if ((bom & 0xFFFF) == 0xFEFF)
+ {
+ return detect_encoding_result<Iterator>{it3,encoding::u16le};
+ }
+ else if ((bom & 0xFFFFFF) == 0xBFBBEF)
+ {
+ return detect_encoding_result<Iterator>{it4,encoding::u8};
+ }
+ else
+ {
+ uint32_t pattern = (static_cast<uint8_t>(*it1) ? 1 : 0) | (static_cast<uint8_t>(*it2) ? 2 : 0) | (static_cast<uint8_t>(*it3) ? 4 : 0) | (static_cast<uint8_t>(*it4) ? 8 : 0);
+ switch (pattern) {
+ case 0x08:
+ return detect_encoding_result<Iterator>{it1,encoding::u32be};
+ case 0x0A:
+ return detect_encoding_result<Iterator>{it1,encoding::u16be};
+ case 0x01:
+ return detect_encoding_result<Iterator>{it1,encoding::u32le};
+ case 0x05:
+ return detect_encoding_result<Iterator>{it1,encoding::u16le};
+ case 0x0F:
+ return detect_encoding_result<Iterator>{it1,encoding::u8};
+ default:
+ return detect_encoding_result<Iterator>{it1,encoding::undetected};
+ }
+ }
+ }
+}
+
+template <class Iterator>
+struct skip_bom_result
+{
+ Iterator it;
+ encoding_errc ec;
+};
+
+template <class Iterator>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<Iterator>::value_type>::value && sizeof(typename std::iterator_traits<Iterator>::value_type) == sizeof(uint8_t),
+ skip_bom_result<Iterator>>::type
+skip_bom(Iterator first, Iterator last) UNICONS_NOEXCEPT
+{
+ auto result = unicons::detect_encoding(first,last);
+ switch (result.ec)
+ {
+ case unicons::encoding::u8:
+ return skip_bom_result<Iterator>{result.it,encoding_errc()};
+ break;
+ case unicons::encoding::u16le:
+ case unicons::encoding::u16be:
+ return skip_bom_result<Iterator>{result.it,encoding_errc::expected_u8_found_u16};
+ break;
+ case unicons::encoding::u32le:
+ case unicons::encoding::u32be:
+ return skip_bom_result<Iterator>{result.it,encoding_errc::expected_u8_found_u32};
+ break;
+ default:
+ return skip_bom_result<Iterator>{result.it,encoding_errc()};
+ break;
+ }
+}
+
+template <class Iterator>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<Iterator>::value_type>::value && sizeof(typename std::iterator_traits<Iterator>::value_type) == sizeof(uint16_t),
+ skip_bom_result<Iterator>>::type
+skip_bom(Iterator first, Iterator last) UNICONS_NOEXCEPT
+{
+ if (first == last)
+ {
+ return skip_bom_result<Iterator>{first,encoding_errc()};
+ }
+ uint16_t bom = static_cast<uint16_t>(*first);
+ if (bom == 0xFEFF)
+ {
+ return skip_bom_result<Iterator>{++first,encoding_errc()};
+ }
+ else if (bom == 0xFFFE)
+ {
+ return skip_bom_result<Iterator>{last,encoding_errc::expected_u16_found_fffe};
+ }
+ else
+ {
+ return skip_bom_result<Iterator>{first,encoding_errc()};
+ }
+}
+
+template <class Iterator>
+typename std::enable_if<std::is_integral<typename std::iterator_traits<Iterator>::value_type>::value && sizeof(typename std::iterator_traits<Iterator>::value_type) == sizeof(uint32_t),
+ skip_bom_result<Iterator>>::type
+skip_bom(Iterator first, Iterator last) UNICONS_NOEXCEPT
+{
+ if (first == last)
+ {
+ return skip_bom_result<Iterator>{first,encoding_errc()};
+ }
+ uint32_t bom = static_cast<uint32_t>(*first);
+ if (bom == 0xFEFF0000)
+ {
+ return skip_bom_result<Iterator>{++first,encoding_errc()};
+ }
+ else if (bom == 0xFFFE0000)
+ {
+ return skip_bom_result<Iterator>{last,encoding_errc::expected_u32_found_fffe};
+ }
+ else
+ {
+ return skip_bom_result<Iterator>{first,encoding_errc()};
+ }
+}
+
+}
+
+#endif
+
diff --git a/vendor/jsoncons-0.104.0/jsoncons/detail/writer.hpp b/vendor/jsoncons-0.104.0/jsoncons/detail/writer.hpp
new file mode 100644
index 00000000..c832f06f
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/detail/writer.hpp
@@ -0,0 +1,155 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_DETAIL_WRITERS_HPP
+#define JSONCONS_DETAIL_WRITERS_HPP
+
+#include <stdexcept>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <cstdlib>
+#include <cmath>
+#include <cstdarg>
+#include <locale>
+#include <limits>
+#include <type_traits>
+#include <algorithm>
+#include <exception>
+#include <jsoncons/jsoncons_config.hpp>
+#include <jsoncons/detail/type_traits_helper.hpp>
+
+namespace jsoncons { namespace detail {
+
+template <class CharT>
+class ostream_buffered_writer
+{
+public:
+ typedef basic_string_view_ext<CharT> string_view_type;
+ typedef CharT char_type;
+ typedef std::basic_ostream<CharT> output_type;
+private:
+ static const size_t default_buffer_length = 16384;
+
+ std::basic_ostream<CharT>& os_;
+ std::vector<CharT> buffer_;
+ CharT * begin_buffer_;
+ const CharT* end_buffer_;
+ CharT* p_;
+
+ // Noncopyable and nonmoveable
+ ostream_buffered_writer(const ostream_buffered_writer&) = delete;
+ ostream_buffered_writer& operator=(const ostream_buffered_writer&) = delete;
+
+public:
+ ostream_buffered_writer(std::basic_ostream<CharT>& os)
+ : os_(os), buffer_(default_buffer_length), begin_buffer_(buffer_.data()), end_buffer_(begin_buffer_+buffer_.size()), p_(begin_buffer_)
+ {
+ }
+ ostream_buffered_writer(std::basic_ostream<CharT>& os, size_t buflen)
+ : os_(os), buffer_(buflen), begin_buffer_(buffer_.data()), end_buffer_(begin_buffer_+buffer_.size()), p_(begin_buffer_)
+ {
+ }
+ ~ostream_buffered_writer()
+ {
+ os_.write(begin_buffer_, buffer_length());
+ os_.flush();
+ }
+
+ void flush()
+ {
+ os_.write(begin_buffer_, buffer_length());
+ p_ = buffer_.data();
+ }
+
+ void write(const CharT* s, size_t length)
+ {
+ size_t diff = end_buffer_ - p_;
+ if (diff >= length)
+ {
+ std::memcpy(p_, s, length*sizeof(CharT));
+ p_ += length;
+ }
+ else
+ {
+ os_.write(begin_buffer_, buffer_length());
+ os_.write(s,length);
+ p_ = begin_buffer_;
+ }
+ }
+
+ void write(const string_view_type& s)
+ {
+ write(s.data(),s.length());
+ }
+
+ void put(CharT ch)
+ {
+ if (p_ < end_buffer_)
+ {
+ *p_++ = ch;
+ }
+ else
+ {
+ os_.write(begin_buffer_, buffer_length());
+ p_ = begin_buffer_;
+ put(ch);
+ }
+ }
+private:
+
+ size_t buffer_length() const
+ {
+ return p_ - begin_buffer_;
+ }
+};
+
+template <class CharT>
+class string_writer
+{
+public:
+ typedef basic_string_view_ext<CharT> string_view_type;
+ typedef CharT char_type;
+ typedef std::basic_string<CharT> output_type;
+private:
+ std::basic_string<CharT>& s_;
+
+ // Noncopyable and nonmoveable
+ string_writer(const string_writer&) = delete;
+ string_writer& operator=(const string_writer&) = delete;
+public:
+
+ string_writer(std::basic_string<CharT>& s)
+ : s_(s)
+ {
+ }
+
+ void flush()
+ {
+ }
+
+ void write(const CharT* s, size_t length)
+ {
+ s_.append(s,length);
+ }
+
+ void write(const string_view_type& s)
+ {
+ s_.append(s.data(),s.length());
+ }
+
+ void put(CharT ch)
+ {
+ s_.push_back(ch);
+ }
+};
+
+}}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/json.hpp b/vendor/jsoncons-0.104.0/jsoncons/json.hpp
new file mode 100644
index 00000000..fe9aec4e
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/json.hpp
@@ -0,0 +1,4959 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSON_HPP
+#define JSONCONS_JSON_HPP
+
+#include <limits>
+#include <string>
+#include <vector>
+#include <exception>
+#include <cstdlib>
+#include <cstring>
+#include <ostream>
+#include <memory>
+#include <typeinfo>
+#include <cstring>
+#include <jsoncons/version.hpp>
+#include <jsoncons/json_exception.hpp>
+#include <jsoncons/jsoncons_utilities.hpp>
+#include <jsoncons/json_structures.hpp>
+#include <jsoncons/json_output_handler.hpp>
+#include <jsoncons/serialization_options.hpp>
+#include <jsoncons/json_serializer.hpp>
+#include <jsoncons/json_decoder.hpp>
+#include <jsoncons/json_reader.hpp>
+#include <jsoncons/json_type_traits.hpp>
+#include <jsoncons/json_error_category.hpp>
+#include <jsoncons/detail/heap_only_string.hpp>
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wswitch"
+#endif
+
+namespace jsoncons {
+
+struct sorted_policy
+{
+ static const bool preserve_order = false;
+
+ template <class T,class Allocator>
+ using object_storage = std::vector<T,Allocator>;
+
+ template <class T,class Allocator>
+ using array_storage = std::vector<T,Allocator>;
+
+ template <class CharT, class CharTraits, class Allocator>
+ using key_storage = std::basic_string<CharT, CharTraits,Allocator>;
+
+ template <class CharT, class CharTraits, class Allocator>
+ using string_storage = std::basic_string<CharT, CharTraits,Allocator>;
+
+ typedef default_parse_error_handler parse_error_handler_type;
+};
+
+struct preserve_order_policy : public sorted_policy
+{
+ static const bool preserve_order = true;
+};
+
+template <typename IteratorT>
+class range
+{
+ IteratorT first_;
+ IteratorT last_;
+public:
+ range(const IteratorT& first, const IteratorT& last)
+ : first_(first), last_(last)
+ {
+ }
+
+public:
+ IteratorT begin()
+ {
+ return first_;
+ }
+ IteratorT end()
+ {
+ return last_;
+ }
+};
+
+enum class json_type_tag : uint8_t
+{
+ null_t = 0,
+ empty_object_t,
+ bool_t,
+ integer_t,
+ uinteger_t,
+ double_t,
+ small_string_t,
+ string_t,
+ byte_string_t,
+ array_t,
+ object_t
+};
+
+template <class CharT,
+ class ImplementationPolicy = sorted_policy,
+ class Allocator = std::allocator<CharT>>
+class basic_json
+{
+public:
+
+ typedef Allocator allocator_type;
+
+ typedef ImplementationPolicy implementation_policy;
+
+ typedef typename ImplementationPolicy::parse_error_handler_type parse_error_handler_type;
+
+ typedef CharT char_type;
+ typedef typename std::char_traits<char_type> char_traits_type;
+
+ typedef basic_string_view_ext<char_type,char_traits_type> string_view_type;
+
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<char_type> char_allocator_type;
+ using string_storage_type = typename implementation_policy::template string_storage<CharT,char_traits_type,char_allocator_type>;
+ using key_storage_type = typename implementation_policy::template key_storage<CharT,char_traits_type,char_allocator_type>;
+
+ // string_type is for interface only, not storage
+ typedef std::basic_string<CharT,char_traits_type,char_allocator_type> string_type;
+
+ typedef basic_json<CharT,ImplementationPolicy,Allocator> value_type;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef key_value_pair<key_storage_type,value_type> key_value_pair_type;
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+ typedef value_type json_type;
+ typedef key_value_pair_type kvp_type;
+ typedef key_value_pair_type member_type;
+ typedef jsoncons::null_type null_type;
+#endif
+
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<basic_json> val_allocator_type;
+ using array_storage_type = typename implementation_policy::template array_storage<basic_json, val_allocator_type>;
+
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<uint8_t> byte_allocator_type;
+ using byte_string_storage_type = typename implementation_policy::template array_storage<uint8_t, byte_allocator_type>;
+
+ typedef json_array<basic_json> array;
+
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<key_value_pair_type> kvp_allocator_type;
+
+ using object_storage_type = typename implementation_policy::template object_storage<key_value_pair_type , kvp_allocator_type>;
+ typedef json_object<key_storage_type,basic_json,implementation_policy::preserve_order> object;
+
+ typedef typename std::allocator_traits<Allocator>:: template rebind_alloc<array> array_allocator;
+ typedef typename std::allocator_traits<Allocator>:: template rebind_alloc<object> object_allocator;
+
+ typedef typename object::iterator object_iterator;
+ typedef typename object::const_iterator const_object_iterator;
+ typedef typename array::iterator array_iterator;
+ typedef typename array::const_iterator const_array_iterator;
+
+ struct variant
+ {
+ struct data_base
+ {
+ json_type_tag type_id_;
+
+ data_base(json_type_tag id)
+ : type_id_(id)
+ {}
+ };
+
+ class null_data final : public data_base
+ {
+ public:
+ null_data()
+ : data_base(json_type_tag::null_t)
+ {
+ }
+ };
+
+ class empty_object_data final : public data_base
+ {
+ public:
+ empty_object_data()
+ : data_base(json_type_tag::empty_object_t)
+ {
+ }
+ };
+
+ class bool_data final : public data_base
+ {
+ bool val_;
+ public:
+ bool_data(bool val)
+ : data_base(json_type_tag::bool_t),val_(val)
+ {
+ }
+
+ bool_data(const bool_data& val)
+ : data_base(json_type_tag::bool_t),val_(val.val_)
+ {
+ }
+
+ bool value() const
+ {
+ return val_;
+ }
+
+ };
+
+ class integer_data final : public data_base
+ {
+ int64_t val_;
+ public:
+ integer_data(int64_t val)
+ : data_base(json_type_tag::integer_t),val_(val)
+ {
+ }
+
+ integer_data(const integer_data& val)
+ : data_base(json_type_tag::integer_t),val_(val.val_)
+ {
+ }
+
+ int64_t value() const
+ {
+ return val_;
+ }
+ };
+
+ class uinteger_data final : public data_base
+ {
+ uint64_t val_;
+ public:
+ uinteger_data(uint64_t val)
+ : data_base(json_type_tag::uinteger_t),val_(val)
+ {
+ }
+
+ uinteger_data(const uinteger_data& val)
+ : data_base(json_type_tag::uinteger_t),val_(val.val_)
+ {
+ }
+
+ uint64_t value() const
+ {
+ return val_;
+ }
+ };
+
+ class double_data final : public data_base
+ {
+ chars_format format_;
+ uint8_t precision_;
+ uint8_t decimal_places_;
+ double val_;
+ public:
+ double_data(double val)
+ : data_base(json_type_tag::double_t),
+ precision_(0),
+ decimal_places_(0),
+ val_(val)
+ {
+ }
+ double_data(double val, const number_format& fmt)
+ : data_base(json_type_tag::double_t),
+ format_(fmt.floating_point_format()),
+ precision_(fmt.precision()),
+ decimal_places_(fmt.decimal_places()),
+ val_(val)
+ {
+ }
+
+ double_data(const double_data& val)
+ : data_base(json_type_tag::double_t),
+ precision_(val.precision_),
+ decimal_places_(val.decimal_places_),
+ val_(val.val_)
+ {
+ }
+
+ double value() const
+ {
+ return val_;
+ }
+
+ uint8_t precision() const
+ {
+ return precision_;
+ }
+
+ uint8_t decimal_places() const
+ {
+ return precision_;
+ }
+ };
+
+ class small_string_data final : public data_base
+ {
+ static const size_t capacity = 14/sizeof(char_type);
+ uint8_t length_;
+ char_type data_[capacity];
+ public:
+ static const size_t max_length = (14 / sizeof(char_type)) - 1;
+
+ small_string_data(const char_type* p, uint8_t length)
+ : data_base(json_type_tag::small_string_t), length_(length)
+ {
+ JSONCONS_ASSERT(length <= max_length);
+ std::memcpy(data_,p,length*sizeof(char_type));
+ data_[length] = 0;
+ }
+
+ small_string_data(const small_string_data& val)
+ : data_base(json_type_tag::small_string_t), length_(val.length_)
+ {
+ std::memcpy(data_,val.data_,val.length_*sizeof(char_type));
+ data_[length_] = 0;
+ }
+
+ uint8_t length() const
+ {
+ return length_;
+ }
+
+ const char_type* data() const
+ {
+ return data_;
+ }
+
+ const char_type* c_str() const
+ {
+ return data_;
+ }
+ };
+
+ // string_data
+ class string_data final : public data_base
+ {
+ typedef typename detail::heap_only_string_factory<char_type, Allocator>::string_pointer pointer;
+
+ pointer ptr_;
+ public:
+ string_data(const string_data& val)
+ : data_base(json_type_tag::string_t)
+ {
+ ptr_ = detail::heap_only_string_factory<char_type,Allocator>::create(val.data(),val.length(),val.get_allocator());
+ }
+
+ string_data(string_data&& val)
+ : data_base(json_type_tag::string_t), ptr_(nullptr)
+ {
+ std::swap(val.ptr_,ptr_);
+ }
+
+ string_data(const string_data& val, const Allocator& a)
+ : data_base(json_type_tag::string_t)
+ {
+ ptr_ = detail::heap_only_string_factory<char_type,Allocator>::create(val.data(),val.length(),a);
+ }
+
+ string_data(const char_type* data, size_t length, const Allocator& a)
+ : data_base(json_type_tag::string_t)
+ {
+ ptr_ = detail::heap_only_string_factory<char_type,Allocator>::create(data,length,a);
+ }
+
+ ~string_data()
+ {
+ if (ptr_ != nullptr)
+ {
+ detail::heap_only_string_factory<char_type,Allocator>::destroy(ptr_);
+ }
+ }
+
+ void swap(string_data& val)
+ {
+ std::swap(val.ptr_,ptr_);
+ }
+
+ const char_type* data() const
+ {
+ return ptr_->data();
+ }
+
+ const char_type* c_str() const
+ {
+ return ptr_->c_str();
+ }
+
+ size_t length() const
+ {
+ return ptr_->length();
+ }
+
+ allocator_type get_allocator() const
+ {
+ return ptr_->get_allocator();
+ }
+ };
+
+ // byte_string_data
+ class byte_string_data final : public data_base
+ {
+ typedef typename std::allocator_traits<Allocator>:: template rebind_alloc<byte_string_storage_type> string_holder_allocator_type;
+ typedef typename std::allocator_traits<string_holder_allocator_type>::pointer pointer;
+
+ pointer ptr_;
+
+ template <typename... Args>
+ void create(string_holder_allocator_type allocator, Args&& ... args)
+ {
+ typename std::allocator_traits<Allocator>:: template rebind_alloc<byte_string_storage_type> alloc(allocator);
+ ptr_ = alloc.allocate(1);
+ try
+ {
+ std::allocator_traits<string_holder_allocator_type>:: template rebind_traits<byte_string_storage_type>::construct(alloc, detail::to_plain_pointer(ptr_), std::forward<Args>(args)...);
+ }
+ catch (...)
+ {
+ alloc.deallocate(ptr_,1);
+ throw;
+ }
+ }
+ public:
+ byte_string_data(const byte_string_data& val)
+ : data_base(json_type_tag::byte_string_t)
+ {
+ create(val.ptr_->get_allocator(), *(val.ptr_));
+ }
+
+ byte_string_data(byte_string_data&& val)
+ : data_base(json_type_tag::byte_string_t), ptr_(nullptr)
+ {
+ std::swap(val.ptr_,ptr_);
+ }
+
+ byte_string_data(const byte_string_data& val, const Allocator& a)
+ : data_base(json_type_tag::byte_string_t)
+ {
+ create(string_holder_allocator_type(a), *(val.ptr_), a);
+ }
+
+ byte_string_data(const uint8_t* data, size_t length, const Allocator& a)
+ : data_base(json_type_tag::byte_string_t)
+ {
+ create(string_holder_allocator_type(a), data, data+length, a);
+ }
+
+ ~byte_string_data()
+ {
+ if (ptr_ != nullptr)
+ {
+ typename std::allocator_traits<string_holder_allocator_type>:: template rebind_alloc<byte_string_storage_type> alloc(ptr_->get_allocator());
+ std::allocator_traits<string_holder_allocator_type>:: template rebind_traits<byte_string_storage_type>::destroy(alloc, detail::to_plain_pointer(ptr_));
+ alloc.deallocate(ptr_,1);
+ }
+ }
+
+ void swap(byte_string_data& val)
+ {
+ std::swap(val.ptr_,ptr_);
+ }
+
+ const uint8_t* data() const
+ {
+ return ptr_->data();
+ }
+
+ size_t length() const
+ {
+ return ptr_->size();
+ }
+
+ allocator_type get_allocator() const
+ {
+ return ptr_->get_allocator();
+ }
+ };
+
+ // array_data
+ class array_data final : public data_base
+ {
+ typedef typename std::allocator_traits<array_allocator>::pointer pointer;
+ pointer ptr_;
+
+ template <typename... Args>
+ void create(array_allocator allocator, Args&& ... args)
+ {
+ typename std::allocator_traits<Allocator>:: template rebind_alloc<array> alloc(allocator);
+ ptr_ = alloc.allocate(1);
+ try
+ {
+ std::allocator_traits<array_allocator>:: template rebind_traits<array>::construct(alloc, detail::to_plain_pointer(ptr_), std::forward<Args>(args)...);
+ }
+ catch (...)
+ {
+ alloc.deallocate(ptr_,1);
+ throw;
+ }
+ }
+ public:
+ array_data(const array& val)
+ : data_base(json_type_tag::array_t)
+ {
+ create(val.get_allocator(), val);
+ }
+
+ array_data(const array& val, const Allocator& a)
+ : data_base(json_type_tag::array_t)
+ {
+ create(array_allocator(a), val, a);
+ }
+
+ array_data(const array_data& val)
+ : data_base(json_type_tag::array_t)
+ {
+ create(val.ptr_->get_allocator(), *(val.ptr_));
+ }
+
+ array_data(array_data&& val)
+ : data_base(json_type_tag::array_t), ptr_(nullptr)
+ {
+ std::swap(val.ptr_, ptr_);
+ }
+
+ array_data(const array_data& val, const Allocator& a)
+ : data_base(json_type_tag::array_t)
+ {
+ create(array_allocator(a), *(val.ptr_), a);
+ }
+ ~array_data()
+ {
+ if (ptr_ != nullptr)
+ {
+ typename std::allocator_traits<array_allocator>:: template rebind_alloc<array> alloc(ptr_->get_allocator());
+ std::allocator_traits<array_allocator>:: template rebind_traits<array>::destroy(alloc, detail::to_plain_pointer(ptr_));
+ alloc.deallocate(ptr_,1);
+ }
+ }
+
+ allocator_type get_allocator() const
+ {
+ return ptr_->get_allocator();
+ }
+
+ void swap(array_data& val)
+ {
+ std::swap(val.ptr_,ptr_);
+ }
+
+ array& value()
+ {
+ return *ptr_;
+ }
+
+ const array& value() const
+ {
+ return *ptr_;
+ }
+ };
+
+ // object_data
+ class object_data final : public data_base
+ {
+ typedef typename std::allocator_traits<object_allocator>::pointer pointer;
+ pointer ptr_;
+
+ template <typename... Args>
+ void create(Allocator allocator, Args&& ... args)
+ {
+ typename std::allocator_traits<object_allocator>:: template rebind_alloc<object> alloc(allocator);
+ ptr_ = alloc.allocate(1);
+ try
+ {
+ std::allocator_traits<object_allocator>:: template rebind_traits<object>::construct(alloc, detail::to_plain_pointer(ptr_), std::forward<Args>(args)...);
+ }
+ catch (...)
+ {
+ alloc.deallocate(ptr_,1);
+ throw;
+ }
+ }
+ public:
+ explicit object_data(const Allocator& a)
+ : data_base(json_type_tag::object_t)
+ {
+ create(a,a);
+ }
+
+ explicit object_data(const object& val)
+ : data_base(json_type_tag::object_t)
+ {
+ create(val.get_allocator(), val);
+ }
+
+ explicit object_data(const object& val, const Allocator& a)
+ : data_base(json_type_tag::object_t)
+ {
+ create(object_allocator(a), val, a);
+ }
+
+ explicit object_data(const object_data& val)
+ : data_base(json_type_tag::object_t)
+ {
+ create(val.ptr_->get_allocator(), *(val.ptr_));
+ }
+
+ explicit object_data(object_data&& val)
+ : data_base(json_type_tag::object_t), ptr_(nullptr)
+ {
+ std::swap(val.ptr_,ptr_);
+ }
+
+ explicit object_data(const object_data& val, const Allocator& a)
+ : data_base(json_type_tag::object_t)
+ {
+ create(object_allocator(a), *(val.ptr_), a);
+ }
+
+ ~object_data()
+ {
+ if (ptr_ != nullptr)
+ {
+ typename std::allocator_traits<Allocator>:: template rebind_alloc<object> alloc(ptr_->get_allocator());
+ std::allocator_traits<Allocator>:: template rebind_traits<object>::destroy(alloc, detail::to_plain_pointer(ptr_));
+ alloc.deallocate(ptr_,1);
+ }
+ }
+
+ void swap(object_data& val)
+ {
+ std::swap(val.ptr_,ptr_);
+ }
+
+ object& value()
+ {
+ return *ptr_;
+ }
+
+ const object& value() const
+ {
+ return *ptr_;
+ }
+
+ allocator_type get_allocator() const
+ {
+ return ptr_->get_allocator();
+ }
+ };
+
+ private:
+ static const size_t data_size = static_max<sizeof(uinteger_data),sizeof(double_data),sizeof(small_string_data), sizeof(string_data), sizeof(array_data), sizeof(object_data)>::value;
+ static const size_t data_align = static_max<JSONCONS_ALIGNOF(uinteger_data),JSONCONS_ALIGNOF(double_data),JSONCONS_ALIGNOF(small_string_data),JSONCONS_ALIGNOF(string_data),JSONCONS_ALIGNOF(array_data),JSONCONS_ALIGNOF(object_data)>::value;
+
+ typedef typename std::aligned_storage<data_size,data_align>::type data_t;
+
+ data_t data_;
+ public:
+ variant()
+ {
+ new(reinterpret_cast<void*>(&data_))empty_object_data();
+ }
+
+ variant(const Allocator& a)
+ {
+ new(reinterpret_cast<void*>(&data_))object_data(a);
+ }
+
+ variant(const variant& val)
+ {
+ Init_(val);
+ }
+
+ variant(const variant& val, const Allocator& allocator)
+ {
+ Init_(val,allocator);
+ }
+
+ variant(variant&& val) JSONCONS_NOEXCEPT
+ {
+ Init_rv_(std::forward<variant>(val));
+ }
+
+ variant(variant&& val, const Allocator& allocator) JSONCONS_NOEXCEPT
+ {
+ Init_rv_(std::forward<variant>(val), allocator,
+ typename std::allocator_traits<Allocator>::propagate_on_container_move_assignment());
+ }
+
+ explicit variant(null_type)
+ {
+ new(reinterpret_cast<void*>(&data_))null_data();
+ }
+ explicit variant(bool val)
+ {
+ new(reinterpret_cast<void*>(&data_))bool_data(val);
+ }
+ explicit variant(int64_t val)
+ {
+ new(reinterpret_cast<void*>(&data_))integer_data(val);
+ }
+ explicit variant(uint64_t val, const Allocator&)
+ {
+ new(reinterpret_cast<void*>(&data_))uinteger_data(val);
+ }
+ explicit variant(uint64_t val)
+ {
+ new(reinterpret_cast<void*>(&data_))uinteger_data(val);
+ }
+ variant(double val)
+ {
+ new(reinterpret_cast<void*>(&data_))double_data(val);
+ }
+ variant(double val, const number_format& fmt)
+ {
+ new(reinterpret_cast<void*>(&data_))double_data(val, fmt);
+ }
+ variant(const char_type* s, size_t length)
+ {
+ if (length <= small_string_data::max_length)
+ {
+ new(reinterpret_cast<void*>(&data_))small_string_data(s, static_cast<uint8_t>(length));
+ }
+ else
+ {
+ new(reinterpret_cast<void*>(&data_))string_data(s, length, char_allocator_type());
+ }
+ }
+ variant(const uint8_t* s, size_t length)
+ {
+ new(reinterpret_cast<void*>(&data_))byte_string_data(s, length, byte_allocator_type());
+ }
+
+ variant(const uint8_t* s, size_t length, const Allocator& alloc)
+ {
+ new(reinterpret_cast<void*>(&data_))byte_string_data(s, length, alloc);
+ }
+
+ variant(const char_type* s)
+ {
+ size_t length = char_traits_type::length(s);
+ if (length <= small_string_data::max_length)
+ {
+ new(reinterpret_cast<void*>(&data_))small_string_data(s, static_cast<uint8_t>(length));
+ }
+ else
+ {
+ new(reinterpret_cast<void*>(&data_))string_data(s, length, char_allocator_type());
+ }
+ }
+
+ variant(const char_type* s, const Allocator& alloc)
+ {
+ size_t length = char_traits_type::length(s);
+ if (length <= small_string_data::max_length)
+ {
+ new(reinterpret_cast<void*>(&data_))small_string_data(s, static_cast<uint8_t>(length));
+ }
+ else
+ {
+ new(reinterpret_cast<void*>(&data_))string_data(s, length, alloc);
+ }
+ }
+
+ variant(const char_type* s, size_t length, const Allocator& alloc)
+ {
+ if (length <= small_string_data::max_length)
+ {
+ new(reinterpret_cast<void*>(&data_))small_string_data(s, static_cast<uint8_t>(length));
+ }
+ else
+ {
+ new(reinterpret_cast<void*>(&data_))string_data(s, length, alloc);
+ }
+ }
+ variant(const object& val)
+ {
+ new(reinterpret_cast<void*>(&data_))object_data(val);
+ }
+ variant(const object& val, const Allocator& alloc)
+ {
+ new(reinterpret_cast<void*>(&data_))object_data(val, alloc);
+ }
+ variant(const array& val)
+ {
+ new(reinterpret_cast<void*>(&data_))array_data(val);
+ }
+ variant(const array& val, const Allocator& alloc)
+ {
+ new(reinterpret_cast<void*>(&data_))array_data(val,alloc);
+ }
+
+ ~variant()
+ {
+ Destroy_();
+ }
+
+ void Destroy_()
+ {
+ switch (type_id())
+ {
+ case json_type_tag::string_t:
+ reinterpret_cast<string_data*>(&data_)->~string_data();
+ break;
+ case json_type_tag::byte_string_t:
+ reinterpret_cast<byte_string_data*>(&data_)->~byte_string_data();
+ break;
+ case json_type_tag::object_t:
+ reinterpret_cast<object_data*>(&data_)->~object_data();
+ break;
+ case json_type_tag::array_t:
+ reinterpret_cast<array_data*>(&data_)->~array_data();
+ break;
+ default:
+ break;
+ }
+ }
+
+ variant& operator=(const variant& val)
+ {
+ if (this !=&val)
+ {
+ Destroy_();
+ switch (val.type_id())
+ {
+ case json_type_tag::null_t:
+ new(reinterpret_cast<void*>(&data_))null_data();
+ break;
+ case json_type_tag::empty_object_t:
+ new(reinterpret_cast<void*>(&data_))empty_object_data();
+ break;
+ case json_type_tag::bool_t:
+ new(reinterpret_cast<void*>(&data_))bool_data(*(val.bool_data_cast()));
+ break;
+ case json_type_tag::integer_t:
+ new(reinterpret_cast<void*>(&data_))integer_data(*(val.integer_data_cast()));
+ break;
+ case json_type_tag::uinteger_t:
+ new(reinterpret_cast<void*>(&data_))uinteger_data(*(val.uinteger_data_cast()));
+ break;
+ case json_type_tag::double_t:
+ new(reinterpret_cast<void*>(&data_))double_data(*(val.double_data_cast()));
+ break;
+ case json_type_tag::small_string_t:
+ new(reinterpret_cast<void*>(&data_))small_string_data(*(val.small_string_data_cast()));
+ break;
+ case json_type_tag::string_t:
+ new(reinterpret_cast<void*>(&data_))string_data(*(val.string_data_cast()));
+ break;
+ case json_type_tag::byte_string_t:
+ new(reinterpret_cast<void*>(&data_))byte_string_data(*(val.byte_string_data_cast()));
+ break;
+ case json_type_tag::array_t:
+ new(reinterpret_cast<void*>(&data_))array_data(*(val.array_data_cast()));
+ break;
+ case json_type_tag::object_t:
+ new(reinterpret_cast<void*>(&data_))object_data(*(val.object_data_cast()));
+ break;
+ default:
+ JSONCONS_UNREACHABLE();
+ break;
+ }
+ }
+ return *this;
+ }
+
+ variant& operator=(variant&& val) JSONCONS_NOEXCEPT
+ {
+ if (this !=&val)
+ {
+ swap(val);
+ }
+ return *this;
+ }
+
+ json_type_tag type_id() const
+ {
+ return reinterpret_cast<const data_base*>(&data_)->type_id_;
+ }
+
+ const null_data* null_data_cast() const
+ {
+ return reinterpret_cast<const null_data*>(&data_);
+ }
+
+ const empty_object_data* empty_object_data_cast() const
+ {
+ return reinterpret_cast<const empty_object_data*>(&data_);
+ }
+
+ const bool_data* bool_data_cast() const
+ {
+ return reinterpret_cast<const bool_data*>(&data_);
+ }
+
+ const integer_data* integer_data_cast() const
+ {
+ return reinterpret_cast<const integer_data*>(&data_);
+ }
+
+ const uinteger_data* uinteger_data_cast() const
+ {
+ return reinterpret_cast<const uinteger_data*>(&data_);
+ }
+
+ const double_data* double_data_cast() const
+ {
+ return reinterpret_cast<const double_data*>(&data_);
+ }
+
+ const small_string_data* small_string_data_cast() const
+ {
+ return reinterpret_cast<const small_string_data*>(&data_);
+ }
+
+ string_data* string_data_cast()
+ {
+ return reinterpret_cast<string_data*>(&data_);
+ }
+
+ const string_data* string_data_cast() const
+ {
+ return reinterpret_cast<const string_data*>(&data_);
+ }
+
+ byte_string_data* byte_string_data_cast()
+ {
+ return reinterpret_cast<byte_string_data*>(&data_);
+ }
+
+ const byte_string_data* byte_string_data_cast() const
+ {
+ return reinterpret_cast<const byte_string_data*>(&data_);
+ }
+
+ object_data* object_data_cast()
+ {
+ return reinterpret_cast<object_data*>(&data_);
+ }
+
+ const object_data* object_data_cast() const
+ {
+ return reinterpret_cast<const object_data*>(&data_);
+ }
+
+ array_data* array_data_cast()
+ {
+ return reinterpret_cast<array_data*>(&data_);
+ }
+
+ const array_data* array_data_cast() const
+ {
+ return reinterpret_cast<const array_data*>(&data_);
+ }
+
+ string_view_type as_string_view() const
+ {
+ switch (type_id())
+ {
+ case json_type_tag::small_string_t:
+ return string_view_type(small_string_data_cast()->data(),small_string_data_cast()->length());
+ case json_type_tag::string_t:
+ return string_view_type(string_data_cast()->data(),string_data_cast()->length());
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not a string"));
+ }
+ }
+
+ byte_string_view as_byte_string_view() const
+ {
+ switch (type_id())
+ {
+ case json_type_tag::byte_string_t:
+ return byte_string_view(byte_string_data_cast()->data(),byte_string_data_cast()->length());
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not a byte string"));
+ }
+ }
+
+ bool operator==(const variant& rhs) const
+ {
+ if (this ==&rhs)
+ {
+ return true;
+ }
+ switch (type_id())
+ {
+ case json_type_tag::null_t:
+ switch (rhs.type_id())
+ {
+ case json_type_tag::null_t:
+ return true;
+ default:
+ return false;
+ }
+ break;
+ case json_type_tag::empty_object_t:
+ switch (rhs.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ return true;
+ case json_type_tag::object_t:
+ return rhs.object_data_cast()->value().size() == 0;
+ default:
+ return false;
+ }
+ break;
+ case json_type_tag::bool_t:
+ switch (rhs.type_id())
+ {
+ case json_type_tag::bool_t:
+ return bool_data_cast()->value() == rhs.bool_data_cast()->value();
+ default:
+ return false;
+ }
+ break;
+ case json_type_tag::integer_t:
+ switch (rhs.type_id())
+ {
+ case json_type_tag::integer_t:
+ return integer_data_cast()->value() == rhs.integer_data_cast()->value();
+ case json_type_tag::uinteger_t:
+ return integer_data_cast()->value() >= 0 ? static_cast<uint64_t>(integer_data_cast()->value()) == rhs.uinteger_data_cast()->value() : false;
+ case json_type_tag::double_t:
+ return static_cast<double>(integer_data_cast()->value()) == rhs.double_data_cast()->value();
+ default:
+ return false;
+ }
+ break;
+ case json_type_tag::uinteger_t:
+ switch (rhs.type_id())
+ {
+ case json_type_tag::integer_t:
+ return rhs.integer_data_cast()->value() >= 0 ? uinteger_data_cast()->value() == static_cast<uint64_t>(rhs.integer_data_cast()->value()) : false;
+ case json_type_tag::uinteger_t:
+ return uinteger_data_cast()->value() == rhs.uinteger_data_cast()->value();
+ case json_type_tag::double_t:
+ return static_cast<double>(uinteger_data_cast()->value()) == rhs.double_data_cast()->value();
+ default:
+ return false;
+ }
+ break;
+ case json_type_tag::double_t:
+ switch (rhs.type_id())
+ {
+ case json_type_tag::integer_t:
+ return double_data_cast()->value() == static_cast<double>(rhs.integer_data_cast()->value());
+ case json_type_tag::uinteger_t:
+ return double_data_cast()->value() == static_cast<double>(rhs.uinteger_data_cast()->value());
+ case json_type_tag::double_t:
+ return double_data_cast()->value() == rhs.double_data_cast()->value();
+ default:
+ return false;
+ }
+ break;
+ case json_type_tag::small_string_t:
+ switch (rhs.type_id())
+ {
+ case json_type_tag::small_string_t:
+ return as_string_view() == rhs.as_string_view();
+ case json_type_tag::string_t:
+ return as_string_view() == rhs.as_string_view();
+ default:
+ return false;
+ }
+ break;
+ case json_type_tag::byte_string_t:
+ switch (rhs.type_id())
+ {
+ case json_type_tag::byte_string_t:
+ {
+ return as_byte_string_view() == rhs.as_byte_string_view();
+ }
+ default:
+ return false;
+ }
+ break;
+ case json_type_tag::string_t:
+ switch (rhs.type_id())
+ {
+ case json_type_tag::small_string_t:
+ return as_string_view() == rhs.as_string_view();
+ case json_type_tag::string_t:
+ return as_string_view() == rhs.as_string_view();
+ default:
+ return false;
+ }
+ break;
+ case json_type_tag::array_t:
+ switch (rhs.type_id())
+ {
+ case json_type_tag::array_t:
+ return array_data_cast()->value() == rhs.array_data_cast()->value();
+ default:
+ return false;
+ }
+ break;
+ case json_type_tag::object_t:
+ switch (rhs.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ return object_data_cast()->value().size() == 0;
+ case json_type_tag::object_t:
+ return object_data_cast()->value() == rhs.object_data_cast()->value();
+ default:
+ return false;
+ }
+ break;
+ default:
+ JSONCONS_UNREACHABLE();
+ break;
+ }
+ }
+
+ bool operator!=(const variant& rhs) const
+ {
+ return !(*this == rhs);
+ }
+
+ template <class Alloc = allocator_type>
+ typename std::enable_if<std::is_pod<typename std::allocator_traits<Alloc>::pointer>::value,void>::type
+ swap(variant& other) JSONCONS_NOEXCEPT
+ {
+ if (this ==&other)
+ {
+ return;
+ }
+
+ std::swap(data_,other.data_);
+ }
+
+ template <class Alloc = allocator_type>
+ typename std::enable_if<!std::is_pod<typename std::allocator_traits<Alloc>::pointer>::value, void>::type
+ swap(variant& other) JSONCONS_NOEXCEPT
+ {
+ if (this ==&other)
+ {
+ return;
+ }
+ switch (type_id())
+ {
+ case json_type_tag::null_t:
+ {
+ switch (other.type_id())
+ {
+ case json_type_tag::string_t:
+ {
+ string_data temp(std::move(*other.string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))null_data();
+ new(reinterpret_cast<void*>(&data_))string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::byte_string_t:
+ {
+ byte_string_data temp(std::move(*other.byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))null_data();
+ new(reinterpret_cast<void*>(&data_))byte_string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::array_t:
+ {
+ array_data temp(std::move(*other.array_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))null_data();
+ new(reinterpret_cast<void*>(&data_))array_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::object_t:
+ {
+ object_data temp(std::move(*other.object_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))null_data();
+ new(reinterpret_cast<void*>(&data_))object_data(std::move(temp));
+ }
+ break;
+ default:
+ std::swap(data_,other.data_);
+ break;
+ }
+ }
+ break;
+ case json_type_tag::empty_object_t:
+ {
+ switch (other.type_id())
+ {
+ case json_type_tag::string_t:
+ {
+ string_data temp(std::move(*other.string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))empty_object_data();
+ new(reinterpret_cast<void*>(&data_))string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::byte_string_t:
+ {
+ byte_string_data temp(std::move(*other.byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))empty_object_data();
+ new(reinterpret_cast<void*>(&data_))byte_string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::array_t:
+ {
+ array_data temp(std::move(*other.array_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))empty_object_data();
+ new(reinterpret_cast<void*>(&data_))array_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::object_t:
+ {
+ object_data temp(std::move(*other.object_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))empty_object_data();
+ new(reinterpret_cast<void*>(&data_))object_data(std::move(temp));
+ }
+ break;
+ default:
+ std::swap(data_,other.data_);
+ break;
+ }
+ }
+ break;
+ case json_type_tag::bool_t:
+ {
+ switch (other.type_id())
+ {
+ case json_type_tag::string_t:
+ {
+ string_data temp(std::move(*other.string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))bool_data(*bool_data_cast());
+ new(reinterpret_cast<void*>(&data_))string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::byte_string_t:
+ {
+ byte_string_data temp(std::move(*other.byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))bool_data(*bool_data_cast());
+ new(reinterpret_cast<void*>(&data_))byte_string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::array_t:
+ {
+ array_data temp(std::move(*other.array_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))bool_data(*bool_data_cast());
+ new(reinterpret_cast<void*>(&data_))array_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::object_t:
+ {
+ object_data temp(std::move(*other.object_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))bool_data(*bool_data_cast());
+ new(reinterpret_cast<void*>(&data_))object_data(std::move(temp));
+ }
+ break;
+ default:
+ std::swap(data_,other.data_);
+ break;
+ }
+ }
+ break;
+ case json_type_tag::integer_t:
+ {
+ switch (other.type_id())
+ {
+ case json_type_tag::string_t:
+ {
+ string_data temp(std::move(*other.string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))integer_data(*integer_data_cast());
+ new(reinterpret_cast<void*>(&data_))string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::byte_string_t:
+ {
+ byte_string_data temp(std::move(*other.byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))integer_data(*integer_data_cast());
+ new(reinterpret_cast<void*>(&data_))byte_string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::array_t:
+ {
+ array_data temp(std::move(*other.array_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))integer_data(*integer_data_cast());
+ new(reinterpret_cast<void*>(&data_))array_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::object_t:
+ {
+ object_data temp(std::move(*other.object_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))integer_data(*integer_data_cast());
+ new(reinterpret_cast<void*>(&data_))object_data(std::move(temp));
+ }
+ break;
+ default:
+ std::swap(data_,other.data_);
+ break;
+ }
+ }
+ break;
+ case json_type_tag::uinteger_t:
+ {
+ switch (other.type_id())
+ {
+ case json_type_tag::string_t:
+ {
+ string_data temp(std::move(*other.string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))uinteger_data(*uinteger_data_cast());
+ new(reinterpret_cast<void*>(&data_))string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::byte_string_t:
+ {
+ byte_string_data temp(std::move(*other.byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))uinteger_data(*uinteger_data_cast());
+ new(reinterpret_cast<void*>(&data_))byte_string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::array_t:
+ {
+ array_data temp(std::move(*other.array_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))uinteger_data(*uinteger_data_cast());
+ new(reinterpret_cast<void*>(&data_))array_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::object_t:
+ {
+ object_data temp(std::move(*other.object_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))uinteger_data(*uinteger_data_cast());
+ new(reinterpret_cast<void*>(&data_))object_data(std::move(temp));
+ }
+ break;
+ default:
+ std::swap(data_,other.data_);
+ break;
+ }
+ }
+ break;
+ case json_type_tag::double_t:
+ {
+ switch (other.type_id())
+ {
+ case json_type_tag::string_t:
+ {
+ string_data temp(std::move(*other.string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))double_data(*double_data_cast());
+ new(reinterpret_cast<void*>(&data_))string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::byte_string_t:
+ {
+ byte_string_data temp(std::move(*other.byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))double_data(*double_data_cast());
+ new(reinterpret_cast<void*>(&data_))byte_string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::array_t:
+ {
+ array_data temp(std::move(*other.array_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))double_data(*double_data_cast());
+ new(reinterpret_cast<void*>(&data_))array_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::object_t:
+ {
+ object_data temp(std::move(*other.object_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))double_data(*double_data_cast());
+ new(reinterpret_cast<void*>(&data_))object_data(std::move(temp));
+ }
+ break;
+ default:
+ std::swap(data_,other.data_);
+ break;
+ }
+ }
+ break;
+ case json_type_tag::small_string_t:
+ {
+ switch (other.type_id())
+ {
+ case json_type_tag::string_t:
+ {
+ string_data temp(std::move(*other.string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))small_string_data(*small_string_data_cast());
+ new(reinterpret_cast<void*>(&data_))string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::byte_string_t:
+ {
+ byte_string_data temp(std::move(*other.byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))small_string_data(*small_string_data_cast());
+ new(reinterpret_cast<void*>(&data_))byte_string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::array_t:
+ {
+ array_data temp(std::move(*other.array_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))small_string_data(*small_string_data_cast());
+ new(reinterpret_cast<void*>(&data_))array_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::object_t:
+ {
+ object_data temp(std::move(*other.object_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))small_string_data(*small_string_data_cast());
+ new(reinterpret_cast<void*>(&data_))object_data(std::move(temp));
+ }
+ break;
+ default:
+ std::swap(data_,other.data_);
+ break;
+ }
+ }
+ break;
+ case json_type_tag::string_t:
+ {
+ switch (other.type_id())
+ {
+ case json_type_tag::null_t:
+ {
+ string_data temp(std::move(*string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))null_data();
+ new(reinterpret_cast<void*>(&other.data_))string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::empty_object_t:
+ {
+ string_data temp(std::move(*string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))empty_object_data();
+ new(reinterpret_cast<void*>(&other.data_))string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::bool_t:
+ {
+ string_data temp(std::move(*string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))bool_data(*(other.bool_data_cast()));
+ new(reinterpret_cast<void*>(&other.data_))string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::integer_t:
+ {
+ string_data temp(std::move(*string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))integer_data(*(other.integer_data_cast()));
+ new(reinterpret_cast<void*>(&other.data_))string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::uinteger_t:
+ {
+ string_data temp(std::move(*string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))uinteger_data(*(other.uinteger_data_cast()));
+ new(reinterpret_cast<void*>(&other.data_))string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::double_t:
+ {
+ string_data temp(std::move(*string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))double_data(*(other.double_data_cast()));
+ new(reinterpret_cast<void*>(&other.data_))string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::small_string_t:
+ {
+ string_data temp(std::move(*string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))small_string_data(*(other.small_string_data_cast()));
+ new(reinterpret_cast<void*>(&other.data_))string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::string_t:
+ {
+ string_data_cast()->swap(*other.string_data_cast());
+ }
+ break;
+ case json_type_tag::byte_string_t:
+ {
+ string_data temp(std::move(*string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))byte_string_data(std::move(*other.byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&other.data_))string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::array_t:
+ {
+ string_data temp(std::move(*string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))array_data(std::move(*other.array_data_cast()));
+ new(reinterpret_cast<void*>(&other.data_))string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::object_t:
+ {
+ string_data temp(std::move(*string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))object_data(std::move(*other.object_data_cast()));
+ new(reinterpret_cast<void*>(&other.data_))string_data(std::move(temp));
+ }
+ break;
+ default:
+ JSONCONS_UNREACHABLE();
+ break;
+ }
+ }
+ break;
+ case json_type_tag::byte_string_t:
+ {
+ switch (other.type_id())
+ {
+ case json_type_tag::null_t:
+ {
+ byte_string_data temp(std::move(*byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))null_data();
+ new(reinterpret_cast<void*>(&other.data_))byte_string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::empty_object_t:
+ {
+ byte_string_data temp(std::move(*byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))empty_object_data();
+ new(reinterpret_cast<void*>(&other.data_))byte_string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::bool_t:
+ {
+ byte_string_data temp(std::move(*byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))bool_data(*(other.bool_data_cast()));
+ new(reinterpret_cast<void*>(&other.data_))byte_string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::integer_t:
+ {
+ byte_string_data temp(std::move(*byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))integer_data(*(other.integer_data_cast()));
+ new(reinterpret_cast<void*>(&other.data_))byte_string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::uinteger_t:
+ {
+ byte_string_data temp(std::move(*byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))uinteger_data(*(other.uinteger_data_cast()));
+ new(reinterpret_cast<void*>(&other.data_))byte_string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::double_t:
+ {
+ byte_string_data temp(std::move(*byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))double_data(*(other.double_data_cast()));
+ new(reinterpret_cast<void*>(&other.data_))byte_string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::small_string_t:
+ {
+ byte_string_data temp(std::move(*byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))small_string_data(*(other.small_string_data_cast()));
+ new(reinterpret_cast<void*>(&other.data_))byte_string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::string_t:
+ {
+ byte_string_data temp(std::move(*byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))string_data(*(other.string_data_cast()));
+ new(reinterpret_cast<void*>(&other.data_))byte_string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::byte_string_t:
+ {
+ byte_string_data_cast()->swap(*other.byte_string_data_cast());
+ }
+ break;
+ case json_type_tag::array_t:
+ {
+ byte_string_data temp(std::move(*byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))array_data(std::move(*other.array_data_cast()));
+ new(reinterpret_cast<void*>(&other.data_))byte_string_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::object_t:
+ {
+ byte_string_data temp(std::move(*byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&data_))object_data(std::move(*other.object_data_cast()));
+ new(reinterpret_cast<void*>(&other.data_))byte_string_data(std::move(temp));
+ }
+ break;
+ default:
+ JSONCONS_UNREACHABLE();
+ break;
+ }
+ }
+ break;
+ case json_type_tag::array_t:
+ {
+ switch (other.type_id())
+ {
+ case json_type_tag::null_t:
+ {
+ array_data temp(std::move(*array_data_cast()));
+ new(reinterpret_cast<void*>(&data_))null_data();
+ new(reinterpret_cast<void*>(&(other.data_)))array_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::empty_object_t:
+ {
+ array_data temp(std::move(*array_data_cast()));
+ new(reinterpret_cast<void*>(&data_))empty_object_data();
+ new(reinterpret_cast<void*>(&(other.data_)))array_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::bool_t:
+ {
+ array_data temp(std::move(*array_data_cast()));
+ new(reinterpret_cast<void*>(&data_))bool_data(*(other.bool_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))array_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::integer_t:
+ {
+ array_data temp(std::move(*array_data_cast()));
+ new(reinterpret_cast<void*>(&data_))integer_data(*(other.integer_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))array_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::uinteger_t:
+ {
+ array_data temp(std::move(*array_data_cast()));
+ new(reinterpret_cast<void*>(&data_))uinteger_data(*(other.uinteger_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))array_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::double_t:
+ {
+ array_data temp(std::move(*array_data_cast()));
+ new(reinterpret_cast<void*>(&data_))double_data(*(other.double_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))array_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::small_string_t:
+ {
+ array_data temp(std::move(*array_data_cast()));
+ new(reinterpret_cast<void*>(&data_))small_string_data(*(other.small_string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))array_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::string_t:
+ {
+ array_data temp(std::move(*array_data_cast()));
+ new(reinterpret_cast<void*>(&data_))string_data(std::move(*other.string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))array_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::byte_string_t:
+ {
+ array_data temp(std::move(*array_data_cast()));
+ new(reinterpret_cast<void*>(&data_))byte_string_data(std::move(*other.byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))array_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::array_t:
+ {
+ array_data_cast()->swap(*other.array_data_cast());
+ }
+ break;
+ case json_type_tag::object_t:
+ {
+ array_data temp(std::move(*array_data_cast()));
+ new(reinterpret_cast<void*>(&data_))object_data(std::move(*other.object_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))array_data(std::move(temp));
+ }
+ break;
+ default:
+ JSONCONS_UNREACHABLE();
+ break;
+ }
+ }
+ break;
+ case json_type_tag::object_t:
+ {
+ switch (other.type_id())
+ {
+ case json_type_tag::null_t:
+ {
+ object_data temp(std::move(*object_data_cast()));
+ new(reinterpret_cast<void*>(&data_))null_data();
+ new(reinterpret_cast<void*>(&(other.data_)))object_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::empty_object_t:
+ {
+ object_data temp(std::move(*object_data_cast()));
+ new(reinterpret_cast<void*>(&data_))empty_object_data();
+ new(reinterpret_cast<void*>(&(other.data_)))object_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::bool_t:
+ {
+ object_data temp(std::move(*object_data_cast()));
+ new(reinterpret_cast<void*>(&data_))bool_data(*(other.bool_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))object_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::integer_t:
+ {
+ object_data temp(std::move(*object_data_cast()));
+ new(reinterpret_cast<void*>(&data_))integer_data(*(other.integer_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))object_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::uinteger_t:
+ {
+ object_data temp(std::move(*object_data_cast()));
+ new(reinterpret_cast<void*>(&data_))uinteger_data(*(other.uinteger_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))object_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::double_t:
+ {
+ object_data temp(std::move(*object_data_cast()));
+ new(reinterpret_cast<void*>(&data_))double_data(*(other.double_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))object_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::small_string_t:
+ {
+ object_data temp(std::move(*object_data_cast()));
+ new(reinterpret_cast<void*>(&data_))small_string_data(*(other.small_string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))object_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::string_t:
+ {
+ object_data temp(std::move(*object_data_cast()));
+ new(reinterpret_cast<void*>(&data_))string_data(std::move(*other.string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))object_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::byte_string_t:
+ {
+ object_data temp(std::move(*object_data_cast()));
+ new(reinterpret_cast<void*>(&data_))byte_string_data(std::move(*other.byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))object_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::array_t:
+ {
+ object_data temp(std::move(*object_data_cast()));
+ new(reinterpret_cast<void*>(&data_))array_data(std::move(*other.array_data_cast()));
+ new(reinterpret_cast<void*>(&(other.data_)))object_data(std::move(temp));
+ }
+ break;
+ case json_type_tag::object_t:
+ {
+ object_data_cast()->swap(*other.object_data_cast());
+ }
+ break;
+ default:
+ JSONCONS_UNREACHABLE();
+ break;
+ }
+ }
+ break;
+ default:
+ JSONCONS_UNREACHABLE();
+ break;
+ }
+ }
+ private:
+
+ void Init_(const variant& val)
+ {
+ switch (val.type_id())
+ {
+ case json_type_tag::null_t:
+ new(reinterpret_cast<void*>(&data_))null_data();
+ break;
+ case json_type_tag::empty_object_t:
+ new(reinterpret_cast<void*>(&data_))empty_object_data();
+ break;
+ case json_type_tag::bool_t:
+ new(reinterpret_cast<void*>(&data_))bool_data(*(val.bool_data_cast()));
+ break;
+ case json_type_tag::integer_t:
+ new(reinterpret_cast<void*>(&data_))integer_data(*(val.integer_data_cast()));
+ break;
+ case json_type_tag::uinteger_t:
+ new(reinterpret_cast<void*>(&data_))uinteger_data(*(val.uinteger_data_cast()));
+ break;
+ case json_type_tag::double_t:
+ new(reinterpret_cast<void*>(&data_))double_data(*(val.double_data_cast()));
+ break;
+ case json_type_tag::small_string_t:
+ new(reinterpret_cast<void*>(&data_))small_string_data(*(val.small_string_data_cast()));
+ break;
+ case json_type_tag::string_t:
+ new(reinterpret_cast<void*>(&data_))string_data(*(val.string_data_cast()));
+ break;
+ case json_type_tag::byte_string_t:
+ new(reinterpret_cast<void*>(&data_))byte_string_data(*(val.byte_string_data_cast()));
+ break;
+ case json_type_tag::object_t:
+ new(reinterpret_cast<void*>(&data_))object_data(*(val.object_data_cast()));
+ break;
+ case json_type_tag::array_t:
+ new(reinterpret_cast<void*>(&data_))array_data(*(val.array_data_cast()));
+ break;
+ default:
+ break;
+ }
+ }
+
+ void Init_(const variant& val, const Allocator& a)
+ {
+ switch (val.type_id())
+ {
+ case json_type_tag::null_t:
+ case json_type_tag::empty_object_t:
+ case json_type_tag::bool_t:
+ case json_type_tag::integer_t:
+ case json_type_tag::uinteger_t:
+ case json_type_tag::double_t:
+ case json_type_tag::small_string_t:
+ Init_(val);
+ break;
+ case json_type_tag::string_t:
+ new(reinterpret_cast<void*>(&data_))string_data(*(val.string_data_cast()),a);
+ break;
+ case json_type_tag::byte_string_t:
+ new(reinterpret_cast<void*>(&data_))byte_string_data(*(val.byte_string_data_cast()),a);
+ break;
+ case json_type_tag::array_t:
+ new(reinterpret_cast<void*>(&data_))array_data(*(val.array_data_cast()),a);
+ break;
+ case json_type_tag::object_t:
+ new(reinterpret_cast<void*>(&data_))object_data(*(val.object_data_cast()),a);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void Init_rv_(variant&& val) JSONCONS_NOEXCEPT
+ {
+ switch (val.type_id())
+ {
+ case json_type_tag::null_t:
+ case json_type_tag::empty_object_t:
+ case json_type_tag::double_t:
+ case json_type_tag::integer_t:
+ case json_type_tag::uinteger_t:
+ case json_type_tag::bool_t:
+ case json_type_tag::small_string_t:
+ Init_(val);
+ break;
+ case json_type_tag::string_t:
+ {
+ new(reinterpret_cast<void*>(&data_))string_data(std::move(*val.string_data_cast()));
+ new(reinterpret_cast<void*>(&val.data_))null_data();
+ }
+ break;
+ case json_type_tag::byte_string_t:
+ {
+ new(reinterpret_cast<void*>(&data_))byte_string_data(std::move(*val.byte_string_data_cast()));
+ new(reinterpret_cast<void*>(&val.data_))null_data();
+ }
+ break;
+ case json_type_tag::array_t:
+ {
+ new(reinterpret_cast<void*>(&data_))array_data(std::move(*val.array_data_cast()));
+ new(reinterpret_cast<void*>(&val.data_))null_data();
+ }
+ break;
+ case json_type_tag::object_t:
+ {
+ new(reinterpret_cast<void*>(&data_))object_data(std::move(*val.object_data_cast()));
+ new(reinterpret_cast<void*>(&val.data_))null_data();
+ }
+ break;
+ default:
+ JSONCONS_UNREACHABLE();
+ break;
+ }
+ }
+
+ void Init_rv_(variant&& val, const Allocator& a, std::true_type) JSONCONS_NOEXCEPT
+ {
+ Init_rv_(std::forward<variant>(val));
+ }
+
+ void Init_rv_(variant&& val, const Allocator& a, std::false_type) JSONCONS_NOEXCEPT
+ {
+ switch (val.type_id())
+ {
+ case json_type_tag::null_t:
+ case json_type_tag::empty_object_t:
+ case json_type_tag::double_t:
+ case json_type_tag::integer_t:
+ case json_type_tag::uinteger_t:
+ case json_type_tag::bool_t:
+ case json_type_tag::small_string_t:
+ Init_(std::forward<variant>(val));
+ break;
+ case json_type_tag::string_t:
+ {
+ if (a == val.string_data_cast()->get_allocator())
+ {
+ Init_rv_(std::forward<variant>(val), a, std::true_type());
+ }
+ else
+ {
+ Init_(val,a);
+ }
+ }
+ break;
+ case json_type_tag::byte_string_t:
+ {
+ if (a == val.byte_string_data_cast()->get_allocator())
+ {
+ Init_rv_(std::forward<variant>(val), a, std::true_type());
+ }
+ else
+ {
+ Init_(val,a);
+ }
+ }
+ break;
+ case json_type_tag::object_t:
+ {
+ if (a == val.object_data_cast()->get_allocator())
+ {
+ Init_rv_(std::forward<variant>(val), a, std::true_type());
+ }
+ else
+ {
+ Init_(val,a);
+ }
+ }
+ break;
+ case json_type_tag::array_t:
+ {
+ if (a == val.array_data_cast()->get_allocator())
+ {
+ Init_rv_(std::forward<variant>(val), a, std::true_type());
+ }
+ else
+ {
+ Init_(val,a);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ };
+
+ template <class ParentT>
+ class json_proxy
+ {
+ private:
+ typedef json_proxy<ParentT> proxy_type;
+
+ ParentT& parent_;
+ key_storage_type key_;
+
+ json_proxy() = delete;
+ json_proxy& operator = (const json_proxy& other) = delete;
+
+ json_proxy(ParentT& parent, key_storage_type&& name)
+ : parent_(parent), key_(std::forward<key_storage_type>(name))
+ {
+ }
+
+ basic_json& evaluate()
+ {
+ return parent_.evaluate(string_view_type(key_.data(),key_.size()));
+ }
+
+ const basic_json& evaluate() const
+ {
+ return parent_.evaluate(string_view_type(key_.data(),key_.size()));
+ }
+
+ basic_json& evaluate_with_default()
+ {
+ basic_json& val = parent_.evaluate_with_default();
+ auto it = val.find(string_view_type(key_.data(),key_.size()));
+ if (it == val.object_range().end())
+ {
+ it = val.set_(val.object_range().begin(),std::move(key_),object(val.object_value().get_allocator()));
+ }
+ return it->value();
+ }
+
+ basic_json& evaluate(size_t index)
+ {
+ return evaluate().at(index);
+ }
+
+ const basic_json& evaluate(size_t index) const
+ {
+ return evaluate().at(index);
+ }
+
+ basic_json& evaluate(const string_view_type& index)
+ {
+ return evaluate().at(index);
+ }
+
+ const basic_json& evaluate(const string_view_type& index) const
+ {
+ return evaluate().at(index);
+ }
+ public:
+
+ friend class basic_json<CharT,ImplementationPolicy,Allocator>;
+
+ range<object_iterator> object_range()
+ {
+ return evaluate().object_range();
+ }
+
+ range<const_object_iterator> object_range() const
+ {
+ return evaluate().object_range();
+ }
+
+ range<array_iterator> array_range()
+ {
+ return evaluate().array_range();
+ }
+
+ range<const_array_iterator> array_range() const
+ {
+ return evaluate().array_range();
+ }
+
+ size_t size() const JSONCONS_NOEXCEPT
+ {
+ return evaluate().size();
+ }
+
+ json_type_tag type_id() const
+ {
+ return evaluate().type_id();
+ }
+
+ size_t count(const string_view_type& name) const
+ {
+ return evaluate().count(name);
+ }
+
+ bool has_key(const string_view_type& name) const
+ {
+ return evaluate().has_key(name);
+ }
+
+ bool is_null() const JSONCONS_NOEXCEPT
+ {
+ return evaluate().is_null();
+ }
+
+ bool empty() const
+ {
+ return evaluate().empty();
+ }
+
+ size_t capacity() const
+ {
+ return evaluate().capacity();
+ }
+
+ void reserve(size_t n)
+ {
+ evaluate().reserve(n);
+ }
+
+ void resize(size_t n)
+ {
+ evaluate().resize(n);
+ }
+
+ template <class T>
+ void resize(size_t n, T val)
+ {
+ evaluate().resize(n,val);
+ }
+
+ template<class T, class... Args>
+ bool is(Args&&... args) const
+ {
+ return evaluate().template is<T>(std::forward<Args>(args)...);
+ }
+
+ bool is_string() const JSONCONS_NOEXCEPT
+ {
+ return evaluate().is_string();
+ }
+
+ bool is_byte_string() const JSONCONS_NOEXCEPT
+ {
+ return evaluate().is_byte_string();
+ }
+
+ bool is_number() const JSONCONS_NOEXCEPT
+ {
+ return evaluate().is_number();
+ }
+ bool is_bool() const JSONCONS_NOEXCEPT
+ {
+ return evaluate().is_bool();
+ }
+
+ bool is_object() const JSONCONS_NOEXCEPT
+ {
+ return evaluate().is_object();
+ }
+
+ bool is_array() const JSONCONS_NOEXCEPT
+ {
+ return evaluate().is_array();
+ }
+ bool is_integer() const JSONCONS_NOEXCEPT
+ {
+ return evaluate().is_integer();
+ }
+
+ bool is_uinteger() const JSONCONS_NOEXCEPT
+ {
+ return evaluate().is_uinteger();
+ }
+
+ bool is_double() const JSONCONS_NOEXCEPT
+ {
+ return evaluate().is_double();
+ }
+
+ string_view_type as_string_view() const
+ {
+ return evaluate().as_string_view();
+ }
+
+ byte_string_view as_byte_string_view() const
+ {
+ return evaluate().as_byte_string_view();
+ }
+
+ string_type as_string() const
+ {
+ return evaluate().as_string();
+ }
+
+ template <class SAllocator>
+ string_type as_string(const SAllocator& allocator) const
+ {
+ return evaluate().as_string(allocator);
+ }
+
+ string_type as_string(const basic_serialization_options<char_type>& options) const
+ {
+ return evaluate().as_string(options);
+ }
+
+ template <class SAllocator>
+ string_type as_string(const basic_serialization_options<char_type>& options,
+ const SAllocator& allocator) const
+ {
+ return evaluate().as_string(options,allocator);
+ }
+
+ template<class T, class... Args>
+ T as(Args&&... args) const
+ {
+ return evaluate().template as<T>(std::forward<Args>(args)...);
+ }
+
+ template<class T>
+ typename std::enable_if<std::is_same<string_type,T>::value,T>::type
+ as(const char_allocator_type& allocator) const
+ {
+ return evaluate().template as<T>(allocator);
+ }
+ bool as_bool() const
+ {
+ return evaluate().as_bool();
+ }
+
+ double as_double() const
+ {
+ return evaluate().as_double();
+ }
+
+ int64_t as_integer() const
+ {
+ return evaluate().as_integer();
+ }
+
+ unsigned long long as_ulonglong() const
+ {
+ return evaluate().as_ulonglong();
+ }
+
+ uint64_t as_uinteger() const
+ {
+ return evaluate().as_uinteger();
+ }
+
+ template <class T>
+ json_proxy& operator=(T&& val)
+ {
+ parent_.evaluate_with_default().set_(std::move(key_), std::forward<T>(val));
+ return *this;
+ }
+
+ bool operator==(const basic_json& val) const
+ {
+ return evaluate() == val;
+ }
+
+ bool operator!=(const basic_json& val) const
+ {
+ return evaluate() != val;
+ }
+
+ basic_json& operator[](size_t i)
+ {
+ return evaluate_with_default().at(i);
+ }
+
+ const basic_json& operator[](size_t i) const
+ {
+ return evaluate().at(i);
+ }
+
+ json_proxy<proxy_type> operator[](const string_view_type& name)
+ {
+ return json_proxy<proxy_type>(*this,key_storage_type(name.begin(),name.end(),key_.get_allocator()));
+ }
+
+ const basic_json& operator[](const string_view_type& name) const
+ {
+ return at(name);
+ }
+
+ basic_json& at(const string_view_type& name)
+ {
+ return evaluate().at(name);
+ }
+
+ const basic_json& at(const string_view_type& name) const
+ {
+ return evaluate().at(name);
+ }
+
+ const basic_json& at(size_t index)
+ {
+ return evaluate().at(index);
+ }
+
+ const basic_json& at(size_t index) const
+ {
+ return evaluate().at(index);
+ }
+
+ object_iterator find(const string_view_type& name)
+ {
+ return evaluate().find(name);
+ }
+
+ const_object_iterator find(const string_view_type& name) const
+ {
+ return evaluate().find(name);
+ }
+
+ template <class T>
+ basic_json get(const string_view_type& name, T&& default_val) const
+ {
+ return evaluate().get(name,std::forward<T>(default_val));
+ }
+
+ template <class T>
+ T get_with_default(const string_view_type& name, const T& default_val) const
+ {
+ return evaluate().get_with_default(name,default_val);
+ }
+
+ const CharT* get_with_default(const string_view_type& name, const CharT* default_val) const
+ {
+ return evaluate().get_with_default(name,default_val);
+ }
+
+ void shrink_to_fit()
+ {
+ evaluate_with_default().shrink_to_fit();
+ }
+
+ void clear()
+ {
+ evaluate().clear();
+ }
+ // Remove all elements from an array or object
+
+ void erase(const_object_iterator pos)
+ {
+ evaluate().erase(pos);
+ }
+ // Remove a range of elements from an object
+
+ void erase(const_object_iterator first, const_object_iterator last)
+ {
+ evaluate().erase(first, last);
+ }
+ // Remove a range of elements from an object
+
+ void erase(const string_view_type& name)
+ {
+ evaluate().erase(name);
+ }
+
+ void erase(const_array_iterator pos)
+ {
+ evaluate().erase(pos);
+ }
+ // Removes the element at pos
+
+ void erase(const_array_iterator first, const_array_iterator last)
+ {
+ evaluate().erase(first, last);
+ }
+ // Remove a range of elements from an array
+
+ // merge
+
+ void merge(const basic_json& source)
+ {
+ return evaluate().merge(source);
+ }
+
+ void merge(basic_json&& source)
+ {
+ return evaluate().merge(std::forward<basic_json>(source));
+ }
+
+ void merge(object_iterator hint, const basic_json& source)
+ {
+ return evaluate().merge(hint, source);
+ }
+
+ void merge(object_iterator hint, basic_json&& source)
+ {
+ return evaluate().merge(hint, std::forward<basic_json>(source));
+ }
+
+ // merge_or_update
+
+ void merge_or_update(const basic_json& source)
+ {
+ return evaluate().merge_or_update(source);
+ }
+
+ void merge_or_update(basic_json&& source)
+ {
+ return evaluate().merge_or_update(std::forward<basic_json>(source));
+ }
+
+ void merge_or_update(object_iterator hint, const basic_json& source)
+ {
+ return evaluate().merge_or_update(hint, source);
+ }
+
+ void merge_or_update(object_iterator hint, basic_json&& source)
+ {
+ return evaluate().merge_or_update(hint, std::forward<basic_json>(source));
+ }
+
+ // set
+
+ template <class T>
+ std::pair<object_iterator,bool> set(const string_view_type& name, T&& val)
+ {
+ return evaluate().set(name,std::forward<T>(val));
+ }
+
+ template <class T>
+ std::pair<object_iterator,bool> insert_or_assign(const string_view_type& name, T&& val)
+ {
+ return evaluate().insert_or_assign(name,std::forward<T>(val));
+ }
+
+ template <class T>
+ void set_(key_storage_type&& name, T&& val)
+ {
+ evaluate().set_(std::forward<key_storage_type>(name),std::forward<T>(val));
+ }
+
+ // emplace
+
+ template <class ... Args>
+ std::pair<object_iterator,bool> try_emplace(const string_view_type& name, Args&&... args)
+ {
+ return evaluate().try_emplace(name,std::forward<Args>(args)...);
+ }
+
+ template <class T>
+ object_iterator set(object_iterator hint, const string_view_type& name, T&& val)
+ {
+ return evaluate().set(hint, name, std::forward<T>(val));
+ }
+
+ template <class T>
+ object_iterator insert_or_assign(object_iterator hint, const string_view_type& name, T&& val)
+ {
+ return evaluate().insert_or_assign(hint, name, std::forward<T>(val));
+ }
+
+ template <class ... Args>
+ object_iterator try_emplace(object_iterator hint, const string_view_type& name, Args&&... args)
+ {
+ return evaluate().try_emplace(hint, name, std::forward<Args>(args)...);
+ }
+
+ template <class T>
+ object_iterator set_(object_iterator hint, key_storage_type&& name, T&& val)
+ {
+ return evaluate().set_(hint, std::forward<key_storage_type>(name), std::forward<T>(val));
+ }
+
+ template <class... Args>
+ array_iterator emplace(const_array_iterator pos, Args&&... args)
+ {
+ evaluate_with_default().emplace(pos, std::forward<Args>(args)...);
+ }
+
+ template <class... Args>
+ basic_json& emplace_back(Args&&... args)
+ {
+ return evaluate_with_default().emplace_back(std::forward<Args>(args)...);
+ }
+
+ template <class T>
+ void add(T&& val)
+ {
+ evaluate_with_default().add(std::forward<T>(val));
+ }
+
+ template <class T>
+ void push_back(T&& val)
+ {
+ evaluate_with_default().push_back(std::forward<T>(val));
+ }
+
+ template <class T>
+ array_iterator add(const_array_iterator pos, T&& val)
+ {
+ return evaluate_with_default().add(pos, std::forward<T>(val));
+ }
+
+ template <class T>
+ array_iterator insert(const_array_iterator pos, T&& val)
+ {
+ return evaluate_with_default().insert(pos, std::forward<T>(val));
+ }
+
+ template <class InputIt>
+ array_iterator insert(const_array_iterator pos, InputIt first, InputIt last)
+ {
+ return evaluate_with_default().insert(pos, first, last);
+ }
+
+ template <class SAllocator>
+ void dump(std::basic_string<char_type,char_traits_type,SAllocator>& s) const
+ {
+ evaluate().dump(s);
+ }
+
+ template <class SAllocator>
+ void dump(std::basic_string<char_type,char_traits_type,SAllocator>& s,
+ const basic_serialization_options<char_type>& options) const
+ {
+ evaluate().dump(s,options);
+ }
+ void dump(basic_json_output_handler<char_type>& handler) const
+ {
+ evaluate().dump(handler);
+ }
+
+ void dump(std::basic_ostream<char_type>& os) const
+ {
+ evaluate().dump(os);
+ }
+
+ void dump(std::basic_ostream<char_type>& os, bool pprint) const
+ {
+ evaluate().dump(os, pprint);
+ }
+
+ void dump(std::basic_ostream<char_type>& os, const basic_serialization_options<char_type>& options) const
+ {
+ evaluate().dump(os,options);
+ }
+
+ void dump(std::basic_ostream<char_type>& os, const basic_serialization_options<char_type>& options, bool pprint) const
+ {
+ evaluate().dump(os,options,pprint);
+ }
+#if !defined(JSONCONS_NO_DEPRECATED)
+
+ string_type to_string(const char_allocator_type& allocator = char_allocator_type()) const JSONCONS_NOEXCEPT
+ {
+ return evaluate().to_string(allocator);
+ }
+ void write(basic_json_output_handler<char_type>& handler) const
+ {
+ evaluate().write(handler);
+ }
+
+ void write(std::basic_ostream<char_type>& os) const
+ {
+ evaluate().write(os);
+ }
+
+ void write(std::basic_ostream<char_type>& os, const basic_serialization_options<char_type>& options) const
+ {
+ evaluate().write(os,options);
+ }
+
+ void write(std::basic_ostream<char_type>& os, const basic_serialization_options<char_type>& options, bool pprint) const
+ {
+ evaluate().write(os,options,pprint);
+ }
+
+ string_type to_string(const basic_serialization_options<char_type>& options, char_allocator_type& allocator = char_allocator_type()) const
+ {
+ return evaluate().to_string(options,allocator);
+ }
+
+ range<object_iterator> members()
+ {
+ return evaluate().members();
+ }
+
+ range<const_object_iterator> members() const
+ {
+ return evaluate().members();
+ }
+
+ range<array_iterator> elements()
+ {
+ return evaluate().elements();
+ }
+
+ range<const_array_iterator> elements() const
+ {
+ return evaluate().elements();
+ }
+ void to_stream(basic_json_output_handler<char_type>& handler) const
+ {
+ evaluate().to_stream(handler);
+ }
+
+ void to_stream(std::basic_ostream<char_type>& os) const
+ {
+ evaluate().to_stream(os);
+ }
+
+ void to_stream(std::basic_ostream<char_type>& os, const basic_serialization_options<char_type>& options) const
+ {
+ evaluate().to_stream(os,options);
+ }
+
+ void to_stream(std::basic_ostream<char_type>& os, const basic_serialization_options<char_type>& options, bool pprint) const
+ {
+ evaluate().to_stream(os,options,pprint);
+ }
+#endif
+ void swap(basic_json& val)
+ {
+ evaluate_with_default().swap(val);
+ }
+
+ friend std::basic_ostream<char_type>& operator<<(std::basic_ostream<char_type>& os, const json_proxy& o)
+ {
+ o.dump(os);
+ return os;
+ }
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+
+ void resize_array(size_t n)
+ {
+ evaluate().resize_array(n);
+ }
+
+ template <class T>
+ void resize_array(size_t n, T val)
+ {
+ evaluate().resize_array(n,val);
+ }
+
+ object_iterator begin_members()
+ {
+ return evaluate().begin_members();
+ }
+
+ const_object_iterator begin_members() const
+ {
+ return evaluate().begin_members();
+ }
+
+ object_iterator end_members()
+ {
+ return evaluate().end_members();
+ }
+
+ const_object_iterator end_members() const
+ {
+ return evaluate().end_members();
+ }
+
+ array_iterator begin_elements()
+ {
+ return evaluate().begin_elements();
+ }
+
+ const_array_iterator begin_elements() const
+ {
+ return evaluate().begin_elements();
+ }
+
+ array_iterator end_elements()
+ {
+ return evaluate().end_elements();
+ }
+
+ const_array_iterator end_elements() const
+ {
+ return evaluate().end_elements();
+ }
+
+ const basic_json& get(const string_view_type& name) const
+ {
+ return evaluate().get(name);
+ }
+
+ bool is_ulonglong() const JSONCONS_NOEXCEPT
+ {
+ return evaluate().is_ulonglong();
+ }
+
+ bool is_longlong() const JSONCONS_NOEXCEPT
+ {
+ return evaluate().is_longlong();
+ }
+
+ int as_int() const
+ {
+ return evaluate().as_int();
+ }
+
+ unsigned int as_uint() const
+ {
+ return evaluate().as_uint();
+ }
+
+ long as_long() const
+ {
+ return evaluate().as_long();
+ }
+
+ unsigned long as_ulong() const
+ {
+ return evaluate().as_ulong();
+ }
+
+ long long as_longlong() const
+ {
+ return evaluate().as_longlong();
+ }
+
+ void add(size_t index, const basic_json& value)
+ {
+ evaluate_with_default().add(index, value);
+ }
+
+ void add(size_t index, basic_json&& value)
+ {
+ evaluate_with_default().add(index, std::forward<basic_json>(value));
+ }
+
+ bool has_member(const key_storage_type& name) const
+ {
+ return evaluate().has_member(name);
+ }
+
+ // Remove a range of elements from an array
+ void remove_range(size_t from_index, size_t to_index)
+ {
+ evaluate().remove_range(from_index, to_index);
+ }
+ // Remove a range of elements from an array
+ void remove(const string_view_type& name)
+ {
+ evaluate().remove(name);
+ }
+ void remove_member(const string_view_type& name)
+ {
+ evaluate().remove(name);
+ }
+ bool is_empty() const JSONCONS_NOEXCEPT
+ {
+ return empty();
+ }
+ bool is_numeric() const JSONCONS_NOEXCEPT
+ {
+ return is_number();
+ }
+#endif
+ };
+
+ static basic_json parse(std::basic_istream<char_type>& is);
+ static basic_json parse(std::basic_istream<char_type>& is, parse_error_handler& err_handler);
+
+ static basic_json parse(const string_view_type& s)
+ {
+ parse_error_handler_type err_handler;
+ return parse(s,err_handler);
+ }
+
+ static basic_json parse(const char_type* s, size_t length)
+ {
+ parse_error_handler_type err_handler;
+ return parse(s,length,err_handler);
+ }
+
+ static basic_json parse(const char_type* s, size_t length, parse_error_handler& err_handler)
+ {
+ return parse(string_view_type(s,length),err_handler);
+ }
+
+ static basic_json parse(const string_view_type& s, parse_error_handler& err_handler)
+ {
+ json_decoder<basic_json> decoder;
+ basic_json_parser<char_type> parser(decoder,err_handler);
+
+ auto result = unicons::skip_bom(s.begin(), s.end());
+ if (result.ec != unicons::encoding_errc())
+ {
+ throw parse_error(result.ec,1,1);
+ }
+ size_t offset = result.it - s.begin();
+ parser.set_source(s.data()+offset,s.size()-offset);
+ parser.parse_some();
+ parser.end_parse();
+ parser.check_done();
+ if (!decoder.is_valid())
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Failed to parse json string"));
+ }
+ return decoder.get_result();
+ }
+
+ static basic_json make_array()
+ {
+ return basic_json(variant(array()));
+ }
+
+ static basic_json make_array(const array& a)
+ {
+ return basic_json(variant(a));
+ }
+
+ static basic_json make_array(const array& a, allocator_type allocator)
+ {
+ return basic_json(variant(a,allocator));
+ }
+
+ static basic_json make_array(std::initializer_list<basic_json> init, const Allocator& allocator = Allocator())
+ {
+ return array(std::move(init),allocator);
+ }
+
+ static basic_json make_array(size_t n, const Allocator& allocator = Allocator())
+ {
+ return array(n,allocator);
+ }
+
+ template <class T>
+ static basic_json make_array(size_t n, const T& val, const Allocator& allocator = Allocator())
+ {
+ return basic_json::array(n, val,allocator);
+ }
+
+ template <size_t dim>
+ static typename std::enable_if<dim==1,basic_json>::type make_array(size_t n)
+ {
+ return array(n);
+ }
+
+ template <size_t dim, class T>
+ static typename std::enable_if<dim==1,basic_json>::type make_array(size_t n, const T& val, const Allocator& allocator = Allocator())
+ {
+ return array(n,val,allocator);
+ }
+
+ template <size_t dim, typename... Args>
+ static typename std::enable_if<(dim>1),basic_json>::type make_array(size_t n, Args... args)
+ {
+ const size_t dim1 = dim - 1;
+
+ basic_json val = make_array<dim1>(args...);
+ val.resize(n);
+ for (size_t i = 0; i < n; ++i)
+ {
+ val[i] = make_array<dim1>(args...);
+ }
+ return val;
+ }
+
+ static const basic_json& null()
+ {
+ static basic_json a_null = basic_json(variant(null_type()));
+ return a_null;
+ }
+
+ variant var_;
+
+ basic_json()
+ : var_()
+ {
+ }
+
+ explicit basic_json(const Allocator& allocator)
+ : var_(allocator)
+ {
+ }
+
+ basic_json(const basic_json& val)
+ : var_(val.var_)
+ {
+ }
+
+ basic_json(const basic_json& val, const Allocator& allocator)
+ : var_(val.var_,allocator)
+ {
+ }
+
+ basic_json(basic_json&& other) JSONCONS_NOEXCEPT
+ : var_(std::move(other.var_))
+ {
+ }
+
+ basic_json(basic_json&& other, const Allocator& allocator) JSONCONS_NOEXCEPT
+ : var_(std::move(other.var_) /*,allocator*/ )
+ {
+ }
+
+ basic_json(const variant& val)
+ : var_(val)
+ {
+ }
+
+ basic_json(variant&& other)
+ : var_(std::forward<variant>(other))
+ {
+ }
+
+ basic_json(const array& val)
+ : var_(val)
+ {
+ }
+
+ basic_json(array&& other)
+ : var_(std::forward<array>(other))
+ {
+ }
+
+ basic_json(const object& other)
+ : var_(other)
+ {
+ }
+
+ basic_json(object&& other)
+ : var_(std::forward<object>(other))
+ {
+ }
+
+ template <class ParentT>
+ basic_json(const json_proxy<ParentT>& proxy)
+ : var_(proxy.evaluate().var_)
+ {
+ }
+
+ template <class ParentT>
+ basic_json(const json_proxy<ParentT>& proxy, const Allocator& allocator)
+ : var_(proxy.evaluate().var_,allocator)
+ {
+ }
+
+ template <class T>
+ basic_json(const T& val)
+ : var_(json_type_traits<basic_json,T>::to_json(val).var_)
+ {
+ }
+
+ template <class T>
+ basic_json(const T& val, const Allocator& allocator)
+ : var_(json_type_traits<basic_json,T>::to_json(val,allocator).var_)
+ {
+ }
+
+ basic_json(const char_type* s)
+ : var_(s)
+ {
+ }
+
+ basic_json(const char_type* s, const Allocator& allocator)
+ : var_(s,allocator)
+ {
+ }
+
+ basic_json(double val, uint8_t precision)
+ : var_(val, number_format(precision, 0))
+ {
+ }
+
+ basic_json(double val, const number_format& fmt)
+ : var_(val, fmt)
+ {
+ }
+
+ basic_json(const char_type *s, size_t length)
+ : var_(s, length)
+ {
+ }
+
+ basic_json(const char_type *s, size_t length, const Allocator& allocator)
+ : var_(s, length, allocator)
+ {
+ }
+
+ basic_json(const uint8_t* s, size_t length)
+ : var_(s, length)
+ {
+ }
+
+ explicit basic_json(const byte_string_view& s)
+ : var_(s.data(), s.length())
+ {
+ }
+
+ basic_json(const uint8_t* s, size_t length, const Allocator& allocator)
+ : var_(s, length, allocator)
+ {
+ }
+#if !defined(JSONCONS_NO_DEPRECATED)
+ template<class InputIterator>
+ basic_json(InputIterator first, InputIterator last, const Allocator& allocator = Allocator())
+ : var_(first,last,allocator)
+ {
+ }
+#endif
+
+ ~basic_json()
+ {
+ }
+
+ basic_json& operator=(const basic_json& rhs)
+ {
+ if (this != &rhs)
+ {
+ var_ = rhs.var_;
+ }
+ return *this;
+ }
+
+ basic_json& operator=(basic_json&& rhs) JSONCONS_NOEXCEPT
+ {
+ if (this !=&rhs)
+ {
+ var_ = std::move(rhs.var_);
+ }
+ return *this;
+ }
+
+ template <class T>
+ basic_json& operator=(const T& val)
+ {
+ var_ = json_type_traits<basic_json,T>::to_json(val).var_;
+ return *this;
+ }
+
+ basic_json& operator=(const char_type* s)
+ {
+ var_ = variant(s);
+ return *this;
+ }
+
+ bool operator!=(const basic_json& rhs) const
+ {
+ return !(*this == rhs);
+ }
+
+ bool operator==(const basic_json& rhs) const
+ {
+ return var_ == rhs.var_;
+ }
+
+ size_t size() const JSONCONS_NOEXCEPT
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ return 0;
+ case json_type_tag::object_t:
+ return object_value().size();
+ case json_type_tag::array_t:
+ return array_value().size();
+ default:
+ return 0;
+ }
+ }
+
+ basic_json& operator[](size_t i)
+ {
+ return at(i);
+ }
+
+ const basic_json& operator[](size_t i) const
+ {
+ return at(i);
+ }
+
+ json_proxy<basic_json> operator[](const string_view_type& name)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ create_object_implicitly();
+ // FALLTHRU
+ case json_type_tag::object_t:
+ return json_proxy<basic_json>(*this, key_storage_type(name.begin(),name.end(),char_allocator_type(object_value().get_allocator())));
+ break;
+ default:
+ JSONCONS_THROW(not_an_object(name.data(),name.length()));
+ break;
+ }
+ }
+
+ const basic_json& operator[](const string_view_type& name) const
+ {
+ return at(name);
+ }
+
+ template <class SAllocator>
+ void dump(std::basic_string<char_type,char_traits_type,SAllocator>& s) const
+ {
+ basic_json_serializer<char_type,detail::string_writer<char_type>> serializer(s);
+ dump(serializer);
+ }
+
+ template <class SAllocator>
+ void dump(std::basic_string<char_type,char_traits_type,SAllocator>& s,
+ const basic_serialization_options<char_type>& options) const
+ {
+ basic_json_serializer<char_type,detail::string_writer<char_type>> serializer(s, options);
+ dump(serializer);
+ }
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+ void dump_body(basic_json_output_handler<char_type>& handler) const
+ {
+ dump_fragment(handler);
+ }
+#endif
+ void dump_fragment(basic_json_output_handler<char_type>& handler) const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::small_string_t:
+ case json_type_tag::string_t:
+ handler.string_value(as_string_view());
+ break;
+ case json_type_tag::byte_string_t:
+ handler.byte_string_value(var_.byte_string_data_cast()->data(), var_.byte_string_data_cast()->length());
+ break;
+ case json_type_tag::double_t:
+ handler.double_value(var_.double_data_cast()->value(), number_format(var_.double_data_cast()->precision(), var_.double_data_cast()->decimal_places()));
+ break;
+ case json_type_tag::integer_t:
+ handler.integer_value(var_.integer_data_cast()->value());
+ break;
+ case json_type_tag::uinteger_t:
+ handler.uinteger_value(var_.uinteger_data_cast()->value());
+ break;
+ case json_type_tag::bool_t:
+ handler.bool_value(var_.bool_data_cast()->value());
+ break;
+ case json_type_tag::null_t:
+ handler.null_value();
+ break;
+ case json_type_tag::empty_object_t:
+ handler.begin_object(0);
+ handler.end_object();
+ break;
+ case json_type_tag::object_t:
+ {
+ handler.begin_object(size());
+ const object& o = object_value();
+ for (const_object_iterator it = o.begin(); it != o.end(); ++it)
+ {
+ handler.name(string_view_type((it->key()).data(),it->key().length()));
+ it->value().dump_fragment(handler);
+ }
+ handler.end_object();
+ }
+ break;
+ case json_type_tag::array_t:
+ {
+ handler.begin_array(size());
+ const array& o = array_value();
+ for (const_array_iterator it = o.begin(); it != o.end(); ++it)
+ {
+ it->dump_fragment(handler);
+ }
+ handler.end_array();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ void dump(basic_json_output_handler<char_type>& handler) const
+ {
+ handler.begin_json();
+ dump_fragment(handler);
+ handler.end_json();
+ }
+
+ void dump(std::basic_ostream<char_type>& os) const
+ {
+ basic_json_serializer<char_type> serializer(os);
+ dump(serializer);
+ }
+
+ void dump(std::basic_ostream<char_type>& os, bool pprint) const
+ {
+ basic_json_serializer<char_type> serializer(os, pprint);
+ dump(serializer);
+ }
+
+ void dump(std::basic_ostream<char_type>& os, const basic_serialization_options<char_type>& options) const
+ {
+ basic_json_serializer<char_type> serializer(os, options);
+ dump(serializer);
+ }
+
+ void dump(std::basic_ostream<char_type>& os, const basic_serialization_options<char_type>& options, bool pprint) const
+ {
+ basic_json_serializer<char_type> serializer(os, options, pprint);
+ dump(serializer);
+ }
+
+ string_type to_string(const char_allocator_type& allocator=char_allocator_type()) const JSONCONS_NOEXCEPT
+ {
+ string_type s(allocator);
+ basic_json_serializer<char_type,detail::string_writer<char_type>> serializer(s);
+ dump_fragment(serializer);
+ return s;
+ }
+
+ string_type to_string(const basic_serialization_options<char_type>& options,
+ const char_allocator_type& allocator=char_allocator_type()) const
+ {
+ string_type s(allocator);
+ basic_json_serializer<char_type,detail::string_writer<char_type>> serializer(s,options);
+ dump_fragment(serializer);
+ return s;
+ }
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+
+ void write_body(basic_json_output_handler<char_type>& handler) const
+ {
+ dump(handler);
+ }
+ void write(basic_json_output_handler<char_type>& handler) const
+ {
+ dump(handler);
+ }
+
+ void write(std::basic_ostream<char_type>& os) const
+ {
+ dump(os);
+ }
+
+ void write(std::basic_ostream<char_type>& os, const basic_serialization_options<char_type>& options) const
+ {
+ dump(os,options);
+ }
+
+ void write(std::basic_ostream<char_type>& os, const basic_serialization_options<char_type>& options, bool pprint) const
+ {
+ dump(os,options,pprint);
+ }
+
+ void to_stream(basic_json_output_handler<char_type>& handler) const
+ {
+ handler.begin_json();
+ dump_fragment(handler);
+ handler.end_json();
+ }
+
+ void to_stream(std::basic_ostream<char_type>& os) const
+ {
+ basic_json_serializer<char_type> serializer(os);
+ to_stream(serializer);
+ }
+
+ void to_stream(std::basic_ostream<char_type>& os, const basic_serialization_options<char_type>& options) const
+ {
+ basic_json_serializer<char_type> serializer(os, options);
+ to_stream(serializer);
+ }
+
+ void to_stream(std::basic_ostream<char_type>& os, const basic_serialization_options<char_type>& options, bool pprint) const
+ {
+ basic_json_serializer<char_type> serializer(os, options, pprint);
+ to_stream(serializer);
+ }
+#endif
+ bool is_null() const JSONCONS_NOEXCEPT
+ {
+ return var_.type_id() == json_type_tag::null_t;
+ }
+
+ bool has_key(const string_view_type& name) const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::object_t:
+ {
+ const_object_iterator it = object_value().find(name);
+ return it != object_range().end();
+ }
+ break;
+ default:
+ return false;
+ }
+ }
+
+ size_t count(const string_view_type& name) const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::object_t:
+ {
+ auto it = object_value().find(name);
+ if (it == object_range().end())
+ {
+ return 0;
+ }
+ size_t count = 0;
+ while (it != object_range().end()&& it->key() == name)
+ {
+ ++count;
+ ++it;
+ }
+ return count;
+ }
+ break;
+ default:
+ return 0;
+ }
+ }
+
+ template<class T, class... Args>
+ bool is(Args&&... args) const
+ {
+ return json_type_traits<basic_json,T>::is(*this,std::forward<Args>(args)...);
+ }
+
+ bool is_string() const JSONCONS_NOEXCEPT
+ {
+ return (var_.type_id() == json_type_tag::string_t) || (var_.type_id() == json_type_tag::small_string_t);
+ }
+
+ bool is_byte_string() const JSONCONS_NOEXCEPT
+ {
+ return (var_.type_id() == json_type_tag::byte_string_t);
+ }
+
+ bool is_bool() const JSONCONS_NOEXCEPT
+ {
+ return var_.type_id() == json_type_tag::bool_t;
+ }
+
+ bool is_object() const JSONCONS_NOEXCEPT
+ {
+ return var_.type_id() == json_type_tag::object_t || var_.type_id() == json_type_tag::empty_object_t;
+ }
+
+ bool is_array() const JSONCONS_NOEXCEPT
+ {
+ return var_.type_id() == json_type_tag::array_t;
+ }
+
+ bool is_integer() const JSONCONS_NOEXCEPT
+ {
+ return var_.type_id() == json_type_tag::integer_t || (var_.type_id() == json_type_tag::uinteger_t&& (as_uinteger() <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)())));
+ }
+
+ bool is_uinteger() const JSONCONS_NOEXCEPT
+ {
+ return var_.type_id() == json_type_tag::uinteger_t || (var_.type_id() == json_type_tag::integer_t&& as_integer() >= 0);
+ }
+
+ bool is_double() const JSONCONS_NOEXCEPT
+ {
+ return var_.type_id() == json_type_tag::double_t;
+ }
+
+ bool is_number() const JSONCONS_NOEXCEPT
+ {
+ return var_.type_id() == json_type_tag::integer_t || var_.type_id() == json_type_tag::uinteger_t || var_.type_id() == json_type_tag::double_t;
+ }
+
+ bool empty() const JSONCONS_NOEXCEPT
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::small_string_t:
+ return var_.small_string_data_cast()->length() == 0;
+ case json_type_tag::string_t:
+ return var_.string_data_cast()->length() == 0;
+ case json_type_tag::array_t:
+ return array_value().size() == 0;
+ case json_type_tag::empty_object_t:
+ return true;
+ case json_type_tag::object_t:
+ return object_value().size() == 0;
+ default:
+ return false;
+ }
+ }
+
+ size_t capacity() const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ return array_value().capacity();
+ case json_type_tag::object_t:
+ return object_value().capacity();
+ default:
+ return 0;
+ }
+ }
+
+ template<class U=Allocator>
+ typename std::enable_if<is_stateless<U>::value,void>::type
+ create_object_implicitly()
+ {
+ var_ = variant(Allocator());
+ }
+
+ template<class U=Allocator>
+ typename std::enable_if<!is_stateless<U>::value,void>::type
+ create_object_implicitly() const
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Cannot create object implicitly - allocator is not default constructible."));
+ }
+
+ void reserve(size_t n)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ array_value().reserve(n);
+ break;
+ case json_type_tag::empty_object_t:
+ {
+ create_object_implicitly();
+ object_value().reserve(n);
+ }
+ break;
+ case json_type_tag::object_t:
+ {
+ object_value().reserve(n);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ void resize(size_t n)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ array_value().resize(n);
+ break;
+ default:
+ break;
+ }
+ }
+
+ template <class T>
+ void resize(size_t n, T val)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ array_value().resize(n, val);
+ break;
+ default:
+ break;
+ }
+ }
+
+ template<class T, class... Args>
+ T as(Args&&... args) const
+ {
+ return json_type_traits<basic_json,T>::as(*this,std::forward<Args>(args)...);
+ }
+
+ template<class T>
+ typename std::enable_if<std::is_same<string_type,T>::value,T>::type
+ as(const char_allocator_type& allocator) const
+ {
+ return json_type_traits<basic_json,T>::as(*this,allocator);
+ }
+
+ bool as_bool() const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::small_string_t:
+ case json_type_tag::string_t:
+ try
+ {
+ basic_json j = basic_json::parse(as_string_view().data(),as_string_view().length());
+ return j.as_bool();
+ }
+ catch (...)
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not a bool"));
+ }
+ break;
+ case json_type_tag::bool_t:
+ return var_.bool_data_cast()->value();
+ case json_type_tag::double_t:
+ return var_.double_data_cast()->value() != 0.0;
+ case json_type_tag::integer_t:
+ return var_.integer_data_cast()->value() != 0;
+ case json_type_tag::uinteger_t:
+ return var_.uinteger_data_cast()->value() != 0;
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not a bool"));
+ }
+ }
+
+ int64_t as_integer() const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::small_string_t:
+ case json_type_tag::string_t:
+ try
+ {
+ basic_json j = basic_json::parse(as_string_view().data(),as_string_view().length());
+ return j.as<int64_t>();
+ }
+ catch (...)
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not an integer"));
+ }
+ break;
+ case json_type_tag::double_t:
+ return static_cast<int64_t>(var_.double_data_cast()->value());
+ case json_type_tag::integer_t:
+ return static_cast<int64_t>(var_.integer_data_cast()->value());
+ case json_type_tag::uinteger_t:
+ return static_cast<int64_t>(var_.uinteger_data_cast()->value());
+ case json_type_tag::bool_t:
+ return var_.bool_data_cast()->value() ? 1 : 0;
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not an integer"));
+ }
+ }
+
+ uint64_t as_uinteger() const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::small_string_t:
+ case json_type_tag::string_t:
+ try
+ {
+ basic_json j = basic_json::parse(as_string_view().data(),as_string_view().length());
+ return j.as<uint64_t>();
+ }
+ catch (...)
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not an unsigned integer"));
+ }
+ break;
+ case json_type_tag::double_t:
+ return static_cast<uint64_t>(var_.double_data_cast()->value());
+ case json_type_tag::integer_t:
+ return static_cast<uint64_t>(var_.integer_data_cast()->value());
+ case json_type_tag::uinteger_t:
+ return static_cast<uint64_t>(var_.uinteger_data_cast()->value());
+ case json_type_tag::bool_t:
+ return var_.bool_data_cast()->value() ? 1 : 0;
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not an unsigned integer"));
+ }
+ }
+
+ size_t precision() const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::double_t:
+ return var_.double_data_cast()->precision();
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not a double"));
+ }
+ }
+
+ size_t decimal_places() const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::double_t:
+ return var_.double_data_cast()->decimal_places();
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not a double"));
+ }
+ }
+
+ double as_double() const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::small_string_t:
+ case json_type_tag::string_t:
+ try
+ {
+ basic_json j = basic_json::parse(as_string_view().data(),as_string_view().length());
+ return j.as<double>();
+ }
+ catch (...)
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not a double"));
+ }
+ break;
+ case json_type_tag::double_t:
+ return var_.double_data_cast()->value();
+ case json_type_tag::integer_t:
+ return static_cast<double>(var_.integer_data_cast()->value());
+ case json_type_tag::uinteger_t:
+ return static_cast<double>(var_.uinteger_data_cast()->value());
+ //case json_type_tag::null_t:
+ // return std::numeric_limits<double>::quiet_NaN();
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not a double"));
+ }
+ }
+
+ string_view_type as_string_view() const
+ {
+ return var_.as_string_view();
+ }
+
+ byte_string_view as_byte_string_view() const
+ {
+ return var_.as_byte_string_view();
+ }
+
+ string_type as_string() const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::small_string_t:
+ case json_type_tag::string_t:
+ return string_type(as_string_view().data(),as_string_view().length());
+ default:
+ return to_string();
+ }
+ }
+
+ template <class SAllocator>
+ string_type as_string(const SAllocator& allocator) const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::small_string_t:
+ case json_type_tag::string_t:
+ return string_type(as_string_view().data(),as_string_view().length(),allocator);
+ default:
+ return to_string(allocator);
+ }
+ }
+
+ string_type as_string(const basic_serialization_options<char_type>& options) const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::small_string_t:
+ case json_type_tag::string_t:
+ return string_type(as_string_view().data(),as_string_view().length());
+ default:
+ return to_string(options);
+ }
+ }
+
+ template <class SAllocator>
+ string_type as_string(const basic_serialization_options<char_type>& options,
+ const SAllocator& allocator) const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::small_string_t:
+ case json_type_tag::string_t:
+ return string_type(as_string_view().data(),as_string_view().length(),allocator);
+ default:
+ return to_string(options,allocator);
+ }
+ }
+
+ const char_type* as_cstring() const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::small_string_t:
+ return var_.small_string_data_cast()->c_str();
+ case json_type_tag::string_t:
+ return var_.string_data_cast()->c_str();
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not a cstring"));
+ }
+ }
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+
+ size_t double_precision() const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::double_t:
+ return var_.double_data_cast()->precision();
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not a double"));
+ }
+ }
+#endif
+
+ basic_json& at(const string_view_type& name)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ JSONCONS_THROW(key_not_found(name.data(),name.length()));
+ case json_type_tag::object_t:
+ {
+ auto it = object_value().find(name);
+ if (it == object_range().end())
+ {
+ JSONCONS_THROW(key_not_found(name.data(),name.length()));
+ }
+ return it->value();
+ }
+ break;
+ default:
+ {
+ JSONCONS_THROW(not_an_object(name.data(),name.length()));
+ }
+ }
+ }
+
+ basic_json& evaluate()
+ {
+ return *this;
+ }
+
+ basic_json& evaluate_with_default()
+ {
+ return *this;
+ }
+
+ const basic_json& evaluate() const
+ {
+ return *this;
+ }
+ basic_json& evaluate(const string_view_type& name)
+ {
+ return at(name);
+ }
+
+ const basic_json& evaluate(const string_view_type& name) const
+ {
+ return at(name);
+ }
+
+ const basic_json& at(const string_view_type& name) const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ JSONCONS_THROW(key_not_found(name.data(),name.length()));
+ case json_type_tag::object_t:
+ {
+ auto it = object_value().find(name);
+ if (it == object_range().end())
+ {
+ JSONCONS_THROW(key_not_found(name.data(),name.length()));
+ }
+ return it->value();
+ }
+ break;
+ default:
+ {
+ JSONCONS_THROW(not_an_object(name.data(),name.length()));
+ }
+ }
+ }
+
+ basic_json& at(size_t i)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ if (i >= array_value().size())
+ {
+ JSONCONS_THROW(json_exception_impl<std::out_of_range>("Invalid array subscript"));
+ }
+ return array_value().operator[](i);
+ case json_type_tag::object_t:
+ return object_value().at(i);
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Index on non-array value not supported"));
+ }
+ }
+
+ const basic_json& at(size_t i) const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ if (i >= array_value().size())
+ {
+ JSONCONS_THROW(json_exception_impl<std::out_of_range>("Invalid array subscript"));
+ }
+ return array_value().operator[](i);
+ case json_type_tag::object_t:
+ return object_value().at(i);
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Index on non-array value not supported"));
+ }
+ }
+
+ object_iterator find(const string_view_type& name)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ return object_range().end();
+ case json_type_tag::object_t:
+ return object_value().find(name);
+ default:
+ {
+ JSONCONS_THROW(not_an_object(name.data(),name.length()));
+ }
+ }
+ }
+
+ const_object_iterator find(const string_view_type& name) const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ return object_range().end();
+ case json_type_tag::object_t:
+ return object_value().find(name);
+ default:
+ {
+ JSONCONS_THROW(not_an_object(name.data(),name.length()));
+ }
+ }
+ }
+
+ template<class T>
+ basic_json get(const string_view_type& name, T&& default_val) const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ {
+ return basic_json(std::forward<T>(default_val));
+ }
+ case json_type_tag::object_t:
+ {
+ const_object_iterator it = object_value().find(name);
+ if (it != object_range().end())
+ {
+ return it->value();
+ }
+ else
+ {
+ return basic_json(std::forward<T>(default_val));
+ }
+ }
+ default:
+ {
+ JSONCONS_THROW(not_an_object(name.data(),name.length()));
+ }
+ }
+ }
+
+ template<class T>
+ T get_with_default(const string_view_type& name, const T& default_val) const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ {
+ return default_val;
+ }
+ case json_type_tag::object_t:
+ {
+ const_object_iterator it = object_value().find(name);
+ if (it != object_range().end())
+ {
+ return it->value().template as<T>();
+ }
+ else
+ {
+ return default_val;
+ }
+ }
+ default:
+ {
+ JSONCONS_THROW(not_an_object(name.data(),name.length()));
+ }
+ }
+ }
+
+ const CharT* get_with_default(const string_view_type& name, const CharT* default_val) const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ {
+ return default_val;
+ }
+ case json_type_tag::object_t:
+ {
+ const_object_iterator it = object_value().find(name);
+ if (it != object_range().end())
+ {
+ return it->value().as_cstring();
+ }
+ else
+ {
+ return default_val;
+ }
+ }
+ default:
+ {
+ JSONCONS_THROW(not_an_object(name.data(),name.length()));
+ }
+ }
+ }
+
+ // Modifiers
+
+ void shrink_to_fit()
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ array_value().shrink_to_fit();
+ break;
+ case json_type_tag::object_t:
+ object_value().shrink_to_fit();
+ break;
+ default:
+ break;
+ }
+ }
+
+ void clear()
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ array_value().clear();
+ break;
+ case json_type_tag::object_t:
+ object_value().clear();
+ break;
+ default:
+ break;
+ }
+ }
+
+ void erase(const_object_iterator pos)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ break;
+ case json_type_tag::object_t:
+ object_value().erase(pos);
+ break;
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not an object"));
+ break;
+ }
+ }
+
+ void erase(const_object_iterator first, const_object_iterator last)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ break;
+ case json_type_tag::object_t:
+ object_value().erase(first, last);
+ break;
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not an object"));
+ break;
+ }
+ }
+
+ void erase(const_array_iterator pos)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ array_value().erase(pos);
+ break;
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not an array"));
+ break;
+ }
+ }
+
+ void erase(const_array_iterator first, const_array_iterator last)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ array_value().erase(first, last);
+ break;
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not an array"));
+ break;
+ }
+ }
+
+ // Removes all elements from an array value whose index is between from_index, inclusive, and to_index, exclusive.
+
+ void erase(const string_view_type& name)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ break;
+ case json_type_tag::object_t:
+ object_value().erase(name);
+ break;
+ default:
+ JSONCONS_THROW(not_an_object(name.data(),name.length()));
+ break;
+ }
+ }
+
+ template <class T>
+ std::pair<object_iterator,bool> set(const string_view_type& name, T&& val)
+ {
+ return insert_or_assign(name, std::forward<T>(val));
+ }
+
+ template <class T>
+ std::pair<object_iterator,bool> insert_or_assign(const string_view_type& name, T&& val)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ create_object_implicitly();
+ // FALLTHRU
+ case json_type_tag::object_t:
+ return object_value().insert_or_assign(name, std::forward<T>(val));
+ default:
+ {
+ JSONCONS_THROW(not_an_object(name.data(),name.length()));
+ }
+ }
+ }
+
+ template <class ... Args>
+ std::pair<object_iterator,bool> try_emplace(const string_view_type& name, Args&&... args)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ create_object_implicitly();
+ // FALLTHRU
+ case json_type_tag::object_t:
+ return object_value().try_emplace(name, std::forward<Args>(args)...);
+ default:
+ {
+ JSONCONS_THROW(not_an_object(name.data(),name.length()));
+ }
+ }
+ }
+
+ template <class T>
+ void set_(key_storage_type&& name, T&& val)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ create_object_implicitly();
+ // FALLTHRU
+ case json_type_tag::object_t:
+ object_value().set_(std::forward<key_storage_type>(name), std::forward<T>(val));
+ break;
+ default:
+ {
+ JSONCONS_THROW(not_an_object(name.data(),name.length()));
+ }
+ }
+ }
+
+ // merge
+
+ void merge(const basic_json& source)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ create_object_implicitly();
+ // FALLTHRU
+ case json_type_tag::object_t:
+ return object_value().merge(source.object_value());
+ default:
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Attempting to merge a value that is not an object"));
+ }
+ }
+ }
+
+ void merge(basic_json&& source)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ create_object_implicitly();
+ // FALLTHRU
+ case json_type_tag::object_t:
+ return object_value().merge(std::move(source.object_value()));
+ default:
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Attempting to merge a value that is not an object"));
+ }
+ }
+ }
+
+ void merge(object_iterator hint, const basic_json& source)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ create_object_implicitly();
+ // FALLTHRU
+ case json_type_tag::object_t:
+ return object_value().merge(hint, source.object_value());
+ default:
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Attempting to merge a value that is not an object"));
+ }
+ }
+ }
+
+ void merge(object_iterator hint, basic_json&& source)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ create_object_implicitly();
+ // FALLTHRU
+ case json_type_tag::object_t:
+ return object_value().merge(hint, std::move(source.object_value()));
+ default:
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Attempting to merge a value that is not an object"));
+ }
+ }
+ }
+
+ // merge_or_update
+
+ void merge_or_update(const basic_json& source)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ create_object_implicitly();
+ // FALLTHRU
+ case json_type_tag::object_t:
+ return object_value().merge_or_update(source.object_value());
+ default:
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Attempting to merge or update a value that is not an object"));
+ }
+ }
+ }
+
+ void merge_or_update(basic_json&& source)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ create_object_implicitly();
+ // FALLTHRU
+ case json_type_tag::object_t:
+ return object_value().merge_or_update(std::move(source.object_value()));
+ default:
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Attempting to merge or update a value that is not an object"));
+ }
+ }
+ }
+
+ void merge_or_update(object_iterator hint, const basic_json& source)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ create_object_implicitly();
+ // FALLTHRU
+ case json_type_tag::object_t:
+ return object_value().merge_or_update(hint, source.object_value());
+ default:
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Attempting to merge or update a value that is not an object"));
+ }
+ }
+ }
+
+ void merge_or_update(object_iterator hint, basic_json&& source)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ create_object_implicitly();
+ // FALLTHRU
+ case json_type_tag::object_t:
+ return object_value().merge_or_update(hint, std::move(source.object_value()));
+ default:
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Attempting to merge or update a value that is not an object"));
+ }
+ }
+ }
+
+ // set
+
+ template <class T>
+ object_iterator set(object_iterator hint, const string_view_type& name, T&& val)
+ {
+ return insert_or_assign(hint, name, std::forward<T>(val));
+ }
+
+ template <class T>
+ object_iterator insert_or_assign(object_iterator hint, const string_view_type& name, T&& val)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ create_object_implicitly();
+ // FALLTHRU
+ case json_type_tag::object_t:
+ return object_value().insert_or_assign(hint, name, std::forward<T>(val));
+ default:
+ {
+ JSONCONS_THROW(not_an_object(name.data(),name.length()));
+ }
+ }
+ }
+
+ template <class ... Args>
+ object_iterator try_emplace(object_iterator hint, const string_view_type& name, Args&&... args)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ create_object_implicitly();
+ // FALLTHRU
+ case json_type_tag::object_t:
+ return object_value().try_emplace(hint, name, std::forward<Args>(args)...);
+ default:
+ {
+ JSONCONS_THROW(not_an_object(name.data(),name.length()));
+ }
+ }
+ }
+
+ template <class T>
+ object_iterator set_(object_iterator hint, key_storage_type&& name, T&& val)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ create_object_implicitly();
+ // FALLTHRU
+ case json_type_tag::object_t:
+ return object_value().set_(hint, std::forward<key_storage_type>(name), std::forward<T>(val));
+ break;
+ default:
+ {
+ JSONCONS_THROW(not_an_object(name.data(),name.length()));
+ }
+ }
+ }
+
+ template <class T>
+ void add(T&& val)
+ {
+ push_back(std::forward<T>(val));
+ }
+
+ template <class T>
+ void push_back(T&& val)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ array_value().push_back(std::forward<T>(val));
+ break;
+ default:
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Attempting to insert into a value that is not an array"));
+ }
+ }
+ }
+
+ template <class T>
+ array_iterator add(const_array_iterator pos, T&& val)
+ {
+ return insert(pos, std::forward<T>(val));
+ }
+
+ template <class T>
+ array_iterator insert(const_array_iterator pos, T&& val)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ return array_value().insert(pos, std::forward<T>(val));
+ break;
+ default:
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Attempting to insert into a value that is not an array"));
+ }
+ }
+ }
+
+ template <class InputIt>
+ array_iterator insert(const_array_iterator pos, InputIt first, InputIt last)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ return array_value().insert(pos, first, last);
+ break;
+ default:
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Attempting to insert into a value that is not an array"));
+ }
+ }
+ }
+
+ template <class... Args>
+ array_iterator emplace(const_array_iterator pos, Args&&... args)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ return array_value().emplace(pos, std::forward<Args>(args)...);
+ break;
+ default:
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Attempting to insert into a value that is not an array"));
+ }
+ }
+ }
+
+ template <class... Args>
+ basic_json& emplace_back(Args&&... args)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ return array_value().emplace_back(std::forward<Args>(args)...);
+ default:
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Attempting to insert into a value that is not an array"));
+ }
+ }
+ }
+
+ json_type_tag type_id() const
+ {
+ return var_.type_id();
+ }
+
+ void swap(basic_json& b)
+ {
+ var_.swap(b.var_);
+ }
+
+ friend void swap(basic_json& a, basic_json& b)
+ {
+ a.swap(b);
+ }
+
+ static basic_json make_string(const string_view_type& s)
+ {
+ return basic_json(variant(s.data(),s.length()));
+ }
+
+ static basic_json make_string(const char_type* rhs, size_t length)
+ {
+ return basic_json(variant(rhs,length));
+ }
+
+ static basic_json make_string(const string_view_type& s, allocator_type allocator)
+ {
+ return basic_json(variant(s.data(),s.length(),allocator));
+ }
+
+ static basic_json from_integer(int64_t val)
+ {
+ return basic_json(variant(val));
+ }
+
+ static basic_json from_integer(int64_t val, allocator_type)
+ {
+ return basic_json(variant(val));
+ }
+
+ static basic_json from_uinteger(uint64_t val)
+ {
+ return basic_json(variant(val));
+ }
+
+ static basic_json from_uinteger(uint64_t val, allocator_type)
+ {
+ return basic_json(variant(val));
+ }
+
+ static basic_json from_floating_point(double val)
+ {
+ return basic_json(variant(val));
+ }
+
+ static basic_json from_floating_point(double val, allocator_type)
+ {
+ return basic_json(variant(val));
+ }
+
+ static basic_json from_bool(bool val)
+ {
+ return basic_json(variant(val));
+ }
+
+ static basic_json make_object(const object& o)
+ {
+ return basic_json(variant(o));
+ }
+
+ static basic_json make_object(const object& o, allocator_type allocator)
+ {
+ return basic_json(variant(o,allocator));
+ }
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+
+ static basic_json parse_file(const std::basic_string<char_type,char_traits_type>& filename)
+ {
+ parse_error_handler_type err_handler;
+ return parse_file(filename,err_handler);
+ }
+
+ static basic_json parse_file(const std::basic_string<char_type,char_traits_type>& filename,
+ parse_error_handler& err_handler)
+ {
+ std::basic_ifstream<CharT> is(filename);
+ return parse(is,err_handler);
+ }
+
+ static basic_json parse_stream(std::basic_istream<char_type>& is)
+ {
+ return parse(is);
+ }
+ static basic_json parse_stream(std::basic_istream<char_type>& is, parse_error_handler& err_handler)
+ {
+ return parse(is,err_handler);
+ }
+
+ static basic_json parse_string(const string_type& s)
+ {
+ return parse(s);
+ }
+
+ static basic_json parse_string(const string_type& s, parse_error_handler& err_handler)
+ {
+ return parse(s,err_handler);
+ }
+
+ void resize_array(size_t n)
+ {
+ resize(n);
+ }
+
+ template <class T>
+ void resize_array(size_t n, T val)
+ {
+ resize(n,val);
+ }
+
+ object_iterator begin_members()
+ {
+ return object_range().begin();
+ }
+
+ const_object_iterator begin_members() const
+ {
+ return object_range().begin();
+ }
+
+ object_iterator end_members()
+ {
+ return object_range().end();
+ }
+
+ const_object_iterator end_members() const
+ {
+ return object_range().end();
+ }
+
+ array_iterator begin_elements()
+ {
+ return array_range().begin();
+ }
+
+ const_array_iterator begin_elements() const
+ {
+ return array_range().begin();
+ }
+
+ array_iterator end_elements()
+ {
+ return array_range().end();
+ }
+
+ const_array_iterator end_elements() const
+ {
+ return array_range().end();
+ }
+
+ const basic_json& get(const string_view_type& name) const
+ {
+ static const basic_json a_null = null_type();
+
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ return a_null;
+ case json_type_tag::object_t:
+ {
+ const_object_iterator it = object_value().find(name);
+ return it != object_range().end() ? it->value() : a_null;
+ }
+ default:
+ {
+ JSONCONS_THROW(not_an_object(name.data(),name.length()));
+ }
+ }
+ }
+
+ bool is_longlong() const JSONCONS_NOEXCEPT
+ {
+ return var_.type_id() == json_type_tag::integer_t;
+ }
+
+ bool is_ulonglong() const JSONCONS_NOEXCEPT
+ {
+ return var_.type_id() == json_type_tag::uinteger_t;
+ }
+
+ long long as_longlong() const
+ {
+ return as_integer();
+ }
+
+ unsigned long long as_ulonglong() const
+ {
+ return as_uinteger();
+ }
+
+ int as_int() const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::double_t:
+ return static_cast<int>(var_.double_data_cast()->value());
+ case json_type_tag::integer_t:
+ return static_cast<int>(var_.integer_data_cast()->value());
+ case json_type_tag::uinteger_t:
+ return static_cast<int>(var_.uinteger_data_cast()->value());
+ case json_type_tag::bool_t:
+ return var_.bool_data_cast()->value() ? 1 : 0;
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not an int"));
+ }
+ }
+
+ unsigned int as_uint() const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::double_t:
+ return static_cast<unsigned int>(var_.double_data_cast()->value());
+ case json_type_tag::integer_t:
+ return static_cast<unsigned int>(var_.integer_data_cast()->value());
+ case json_type_tag::uinteger_t:
+ return static_cast<unsigned int>(var_.uinteger_data_cast()->value());
+ case json_type_tag::bool_t:
+ return var_.bool_data_cast()->value() ? 1 : 0;
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not an unsigned int"));
+ }
+ }
+
+ long as_long() const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::double_t:
+ return static_cast<long>(var_.double_data_cast()->value());
+ case json_type_tag::integer_t:
+ return static_cast<long>(var_.integer_data_cast()->value());
+ case json_type_tag::uinteger_t:
+ return static_cast<long>(var_.uinteger_data_cast()->value());
+ case json_type_tag::bool_t:
+ return var_.bool_data_cast()->value() ? 1 : 0;
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not a long"));
+ }
+ }
+
+ unsigned long as_ulong() const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::double_t:
+ return static_cast<unsigned long>(var_.double_data_cast()->value());
+ case json_type_tag::integer_t:
+ return static_cast<unsigned long>(var_.integer_data_cast()->value());
+ case json_type_tag::uinteger_t:
+ return static_cast<unsigned long>(var_.uinteger_data_cast()->value());
+ case json_type_tag::bool_t:
+ return var_.bool_data_cast()->value() ? 1 : 0;
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not an unsigned long"));
+ }
+ }
+
+ bool has_member(const key_storage_type& name) const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::object_t:
+ {
+ const_object_iterator it = object_value().find(name);
+ return it != object_range().end();
+ }
+ break;
+ default:
+ return false;
+ }
+ }
+
+ void remove_range(size_t from_index, size_t to_index)
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ array_value().remove_range(from_index, to_index);
+ break;
+ default:
+ break;
+ }
+ }
+ // Removes all elements from an array value whose index is between from_index, inclusive, and to_index, exclusive.
+
+ void remove(const string_view_type& name)
+ {
+ erase(name);
+ }
+ void remove_member(const string_view_type& name)
+ {
+ erase(name);
+ }
+ // Removes a member from an object value
+
+ bool is_empty() const JSONCONS_NOEXCEPT
+ {
+ return empty();
+ }
+ bool is_numeric() const JSONCONS_NOEXCEPT
+ {
+ return is_number();
+ }
+
+ template<int size>
+ static typename std::enable_if<size==1,basic_json>::type make_multi_array()
+ {
+ return make_array();
+ }
+ template<size_t size>
+ static typename std::enable_if<size==1,basic_json>::type make_multi_array(size_t n)
+ {
+ return make_array(n);
+ }
+ template<size_t size,typename T>
+ static typename std::enable_if<size==1,basic_json>::type make_multi_array(size_t n, T val)
+ {
+ return make_array(n,val);
+ }
+ template<size_t size>
+ static typename std::enable_if<size==2,basic_json>::type make_multi_array(size_t m, size_t n)
+ {
+ return make_array<2>(m, n);
+ }
+ template<size_t size,typename T>
+ static typename std::enable_if<size==2,basic_json>::type make_multi_array(size_t m, size_t n, T val)
+ {
+ return make_array<2>(m, n, val);
+ }
+ template<size_t size>
+ static typename std::enable_if<size==3,basic_json>::type make_multi_array(size_t m, size_t n, size_t k)
+ {
+ return make_array<3>(m, n, k);
+ }
+ template<size_t size,typename T>
+ static typename std::enable_if<size==3,basic_json>::type make_multi_array(size_t m, size_t n, size_t k, T val)
+ {
+ return make_array<3>(m, n, k, val);
+ }
+ range<object_iterator> members()
+ {
+ return object_range();
+ }
+
+ range<const_object_iterator> members() const
+ {
+ return object_range();
+ }
+
+ range<array_iterator> elements()
+ {
+ return array_range();
+ }
+
+ range<const_array_iterator> elements() const
+ {
+ return array_range();
+ }
+#endif
+
+ range<object_iterator> object_range()
+ {
+ static basic_json empty_object = object();
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ return range<object_iterator>(empty_object.object_range().begin(), empty_object.object_range().end());
+ case json_type_tag::object_t:
+ return range<object_iterator>(object_value().begin(),object_value().end());
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not an object"));
+ }
+ }
+
+ range<const_object_iterator> object_range() const
+ {
+ static const basic_json empty_object = object();
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ return range<const_object_iterator>(empty_object.object_range().begin(), empty_object.object_range().end());
+ case json_type_tag::object_t:
+ return range<const_object_iterator>(object_value().begin(),object_value().end());
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not an object"));
+ }
+ }
+
+ range<array_iterator> array_range()
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ return range<array_iterator>(array_value().begin(),array_value().end());
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not an array"));
+ }
+ }
+
+ range<const_array_iterator> array_range() const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ return range<const_array_iterator>(array_value().begin(),array_value().end());
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not an array"));
+ }
+ }
+
+ array& array_value()
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ return var_.array_data_cast()->value();
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Bad array cast"));
+ break;
+ }
+ }
+
+ const array& array_value() const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::array_t:
+ return var_.array_data_cast()->value();
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Bad array cast"));
+ break;
+ }
+ }
+
+ object& object_value()
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ create_object_implicitly();
+ // FALLTHRU
+ case json_type_tag::object_t:
+ return var_.object_data_cast()->value();
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Bad object cast"));
+ break;
+ }
+ }
+
+ const object& object_value() const
+ {
+ switch (var_.type_id())
+ {
+ case json_type_tag::empty_object_t:
+ const_cast<basic_json*>(this)->create_object_implicitly(); // HERE
+ // FALLTHRU
+ case json_type_tag::object_t:
+ return var_.object_data_cast()->value();
+ default:
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Bad object cast"));
+ break;
+ }
+ }
+
+private:
+
+ friend std::basic_ostream<char_type>& operator<<(std::basic_ostream<char_type>& os, const basic_json& o)
+ {
+ o.dump(os);
+ return os;
+ }
+
+ friend std::basic_istream<char_type>& operator<<(std::basic_istream<char_type>& is, basic_json& o)
+ {
+ json_decoder<basic_json> handler;
+ basic_json_reader<char_type> reader(is, handler);
+ reader.read_next();
+ reader.check_done();
+ if (!handler.is_valid())
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Failed to parse json stream"));
+ }
+ o = handler.get_result();
+ return is;
+ }
+};
+
+template <class Json>
+void swap(typename Json::key_value_pair_type& a, typename Json::key_value_pair_type& b)
+{
+ a.swap(b);
+}
+
+template<class CharT,class ImplementationPolicy,class Allocator>
+basic_json<CharT,ImplementationPolicy,Allocator> basic_json<CharT,ImplementationPolicy,Allocator>::parse(std::basic_istream<char_type>& is)
+{
+ parse_error_handler_type err_handler;
+ return parse(is,err_handler);
+}
+
+template<class CharT,class ImplementationPolicy,class Allocator>
+basic_json<CharT,ImplementationPolicy,Allocator> basic_json<CharT,ImplementationPolicy,Allocator>::parse(std::basic_istream<char_type>& is,
+ parse_error_handler& err_handler)
+{
+ json_decoder<basic_json<CharT,ImplementationPolicy,Allocator>> handler;
+ basic_json_reader<char_type> reader(is, handler, err_handler);
+ reader.read_next();
+ reader.check_done();
+ if (!handler.is_valid())
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Failed to parse json stream"));
+ }
+ return handler.get_result();
+}
+
+template <class Json>
+std::basic_istream<typename Json::char_type>& operator>>(std::basic_istream<typename Json::char_type>& is, Json& o)
+{
+ json_decoder<Json> handler;
+ basic_json_reader<typename Json::char_type> reader(is, handler);
+ reader.read_next();
+ reader.check_done();
+ if (!handler.is_valid())
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Failed to parse json stream"));
+ }
+ o = handler.get_result();
+ return is;
+}
+
+template<class Json>
+class json_printable
+{
+public:
+ typedef typename Json::char_type char_type;
+
+ json_printable(const Json& o,
+ bool is_pretty_print)
+ : o_(&o), is_pretty_print_(is_pretty_print)
+ {
+ }
+
+ json_printable(const Json& o,
+ bool is_pretty_print,
+ const basic_serialization_options<char_type>& options)
+ : o_(&o), is_pretty_print_(is_pretty_print), options_(options)
+ {
+ ;
+ }
+
+ void dump(std::basic_ostream<char_type>& os) const
+ {
+ o_->dump(os, options_, is_pretty_print_);
+ }
+
+ friend std::basic_ostream<char_type>& operator<<(std::basic_ostream<char_type>& os, const json_printable<Json>& o)
+ {
+ o.dump(os);
+ return os;
+ }
+
+ const Json *o_;
+ bool is_pretty_print_;
+ basic_serialization_options<char_type> options_;
+private:
+ json_printable();
+};
+
+template<class Json>
+json_printable<Json> print(const Json& val)
+{
+ return json_printable<Json>(val,false);
+}
+
+template<class Json>
+json_printable<Json> print(const Json& val,
+ const basic_serialization_options<typename Json::char_type>& options)
+{
+ return json_printable<Json>(val, false, options);
+}
+
+template<class Json>
+json_printable<Json> pretty_print(const Json& val)
+{
+ return json_printable<Json>(val,true);
+}
+
+template<class Json>
+json_printable<Json> pretty_print(const Json& val,
+ const basic_serialization_options<typename Json::char_type>& options)
+{
+ return json_printable<Json>(val, true, options);
+}
+
+typedef basic_json<char,sorted_policy,std::allocator<char>> json;
+typedef basic_json<wchar_t,sorted_policy,std::allocator<wchar_t>> wjson;
+typedef basic_json<char, preserve_order_policy, std::allocator<char>> ojson;
+typedef basic_json<wchar_t, preserve_order_policy, std::allocator<wchar_t>> wojson;
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+typedef basic_json<wchar_t, preserve_order_policy, std::allocator<wchar_t>> owjson;
+typedef json_decoder<json> json_deserializer;
+typedef json_decoder<wjson> wjson_deserializer;
+typedef json_decoder<ojson> ojson_deserializer;
+typedef json_decoder<wojson> wojson_deserializer;
+#endif
+
+#if defined(JSONCONS_HAS_USER_DEFINED_LITERALS)
+namespace literals {
+
+inline
+jsoncons::json operator "" _json(const char* s, std::size_t n)
+{
+ return jsoncons::json::parse(s, n);
+}
+
+inline
+jsoncons::wjson operator "" _json(const wchar_t* s, std::size_t n)
+{
+ return jsoncons::wjson::parse(s, n);
+}
+
+inline
+jsoncons::ojson operator "" _ojson(const char* s, std::size_t n)
+{
+ return jsoncons::ojson::parse(s, n);
+}
+
+inline
+jsoncons::wojson operator "" _ojson(const wchar_t* s, std::size_t n)
+{
+ return jsoncons::wojson::parse(s, n);
+}
+
+}
+#endif
+
+}
+
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/json_decoder.hpp b/vendor/jsoncons-0.104.0/jsoncons/json_decoder.hpp
new file mode 100644
index 00000000..9ca5bd4c
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/json_decoder.hpp
@@ -0,0 +1,310 @@
+// Copyright 2013-2016 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSON_DECODER_HPP
+#define JSONCONS_JSON_DECODER_HPP
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <cstdlib>
+#include <memory>
+#include <jsoncons/json_exception.hpp>
+#include <jsoncons/json_input_handler.hpp>
+
+namespace jsoncons {
+
+template <class Json,class Allocator=std::allocator<typename Json::char_type>>
+class json_decoder final : public basic_json_input_handler<typename Json::char_type>
+{
+public:
+ typedef typename Json::char_type char_type;
+ using typename basic_json_input_handler<char_type>::string_view_type;
+
+ typedef typename Json::key_value_pair_type key_value_pair_type;
+ typedef typename Json::key_storage_type key_storage_type;
+ typedef typename Json::string_type string_type;
+ typedef typename Json::array array;
+ typedef typename Json::object object;
+ typedef typename Json::allocator_type json_allocator_type;
+ typedef typename string_type::allocator_type json_string_allocator;
+ typedef typename array::allocator_type json_array_allocator;
+ typedef typename object::allocator_type json_object_allocator;
+
+ json_string_allocator string_allocator_;
+ json_object_allocator object_allocator_;
+ json_array_allocator array_allocator_;
+
+ Json result_;
+
+ struct stack_item
+ {
+ stack_item(key_storage_type&& name)
+ : name_(std::forward<key_storage_type>(name))
+ {
+ }
+ stack_item(Json&& value)
+ : value_(std::forward<Json>(value))
+ {
+ }
+
+ stack_item() = default;
+ stack_item(const stack_item&) = default;
+ stack_item(stack_item&&) = default;
+ stack_item& operator=(const stack_item&) = default;
+ stack_item& operator=(stack_item&&) = default;
+
+ key_storage_type name_;
+ Json value_;
+ };
+
+ struct structure_offset
+ {
+ size_t offset_;
+ bool is_object_;
+ };
+
+ typedef Allocator allocator_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<stack_item> stack_item_allocator_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<structure_offset> size_t_allocator_type;
+
+
+ std::vector<stack_item,stack_item_allocator_type> stack_;
+ std::vector<structure_offset,size_t_allocator_type> stack_offsets_;
+ bool is_valid_;
+
+public:
+ json_decoder(const json_allocator_type& jallocator = json_allocator_type())
+ : string_allocator_(jallocator),
+ object_allocator_(jallocator),
+ array_allocator_(jallocator),
+ is_valid_(false)
+
+ {
+ stack_offsets_.reserve(100);
+ stack_.reserve(1000);
+ }
+
+ bool is_valid() const
+ {
+ return is_valid_;
+ }
+
+ Json get_result()
+ {
+ is_valid_ = false;
+ return std::move(result_);
+ }
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+ Json& root()
+ {
+ return result_;
+ }
+#endif
+
+private:
+
+ void push_object()
+ {
+ if (stack_offsets_.back().is_object_)
+ {
+ stack_.back().value_ = Json(object(object_allocator_));
+ }
+ else
+ {
+ stack_.push_back(Json(object(object_allocator_)));
+ }
+ stack_offsets_.push_back({stack_.size()-1,true});
+ }
+
+ void pop_object()
+ {
+ stack_.erase(stack_.begin()+stack_offsets_.back().offset_+1, stack_.end());
+ stack_offsets_.pop_back();
+ }
+
+ void push_array()
+ {
+ if (stack_offsets_.back().is_object_)
+ {
+ stack_.back().value_ = Json(array(array_allocator_));
+ }
+ else
+ {
+ stack_.push_back(Json(array(array_allocator_)));
+ }
+ stack_offsets_.push_back({stack_.size()-1,false});
+ }
+
+ void pop_array()
+ {
+ stack_.erase(stack_.begin()+stack_offsets_.back().offset_+1, stack_.end());
+ stack_offsets_.pop_back();
+ }
+
+ void do_begin_json() override
+ {
+ stack_offsets_.clear();
+ stack_.clear();
+ stack_offsets_.push_back({0,false});
+ is_valid_ = false;
+ }
+
+ void do_end_json() override
+ {
+ if (stack_.size() == 1)
+ {
+ result_.swap(stack_.front().value_);
+ stack_.pop_back();
+ is_valid_ = true;
+ }
+ }
+
+ void do_begin_object(const parsing_context&) override
+ {
+ push_object();
+ }
+
+ void do_end_object(const parsing_context&) override
+ {
+ end_structure();
+ pop_object();
+ }
+
+ void do_begin_array(const parsing_context&) override
+ {
+ push_array();
+ }
+
+ void do_end_array(const parsing_context&) override
+ {
+ end_structure();
+ pop_array();
+ }
+
+ void end_structure()
+ {
+ JSONCONS_ASSERT(stack_offsets_.size() > 0);
+ const size_t structure_index = stack_offsets_.back().offset_;
+ JSONCONS_ASSERT(stack_.size() > structure_index);
+ const size_t count = stack_.size() - (structure_index + 1);
+
+ auto first = stack_.begin() + (structure_index+1);
+ auto last = first + count;
+ if (stack_offsets_.back().is_object_)
+ {
+ stack_[structure_index].value_.object_value().insert(
+ std::make_move_iterator(first),
+ std::make_move_iterator(last),
+ [](stack_item&& val){return key_value_pair_type(std::move(val.name_),std::move(val.value_));});
+ }
+ else
+ {
+ auto& j = stack_[structure_index].value_;
+ j.reserve(count);
+ while (first != last)
+ {
+ j.push_back(std::move(first->value_));
+ ++first;
+ }
+ }
+ }
+
+ void do_name(const string_view_type& name, const parsing_context&) override
+ {
+ stack_.push_back(key_storage_type(name.begin(),name.end(),string_allocator_));
+ }
+
+ void do_string_value(const string_view_type& val, const parsing_context&) override
+ {
+ if (stack_offsets_.back().is_object_)
+ {
+ stack_.back().value_ = Json(val.data(),val.length(),string_allocator_);
+ }
+ else
+ {
+ stack_.push_back(Json(val.data(),val.length(),string_allocator_));
+ }
+ }
+
+ void do_byte_string_value(const uint8_t* data, size_t length, const parsing_context&) override
+ {
+ if (stack_offsets_.back().is_object_)
+ {
+ stack_.back().value_ = Json(data,length,string_allocator_);
+ }
+ else
+ {
+ stack_.push_back(Json(data,length,string_allocator_));
+ }
+ }
+
+ void do_integer_value(int64_t value, const parsing_context&) override
+ {
+ if (stack_offsets_.back().is_object_)
+ {
+ stack_.back().value_ = value;
+ }
+ else
+ {
+ stack_.push_back(Json(value));
+ }
+ }
+
+ void do_uinteger_value(uint64_t value, const parsing_context&) override
+ {
+ if (stack_offsets_.back().is_object_)
+ {
+ stack_.back().value_ = value;
+ }
+ else
+ {
+ stack_.push_back(Json(value));
+ }
+ }
+
+ void do_double_value(double value, const number_format& fmt, const parsing_context&) override
+ {
+ if (stack_offsets_.back().is_object_)
+ {
+ stack_.back().value_ = Json(value,fmt);
+ }
+ else
+ {
+ stack_.push_back(Json(value,fmt));
+ }
+ }
+
+ void do_bool_value(bool value, const parsing_context&) override
+ {
+ if (stack_offsets_.back().is_object_)
+ {
+ stack_.back().value_ = value;
+ }
+ else
+ {
+ stack_.push_back(Json(value));
+ }
+ }
+
+ void do_null_value(const parsing_context&) override
+ {
+ if (stack_offsets_.back().is_object_)
+ {
+ stack_.back().value_ = Json::null();
+ }
+ else
+ {
+ stack_.push_back(Json(Json::null()));
+ }
+ }
+};
+
+}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/json_deserializer.hpp b/vendor/jsoncons-0.104.0/jsoncons/json_deserializer.hpp
new file mode 100644
index 00000000..05b44a40
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/json_deserializer.hpp
@@ -0,0 +1,12 @@
+// Copyright 2013-2016 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSON_DESERIALIZER_HPP
+#define JSONCONS_JSON_DESERIALIZER_HPP
+
+#include <jsoncons/json_decoder.hpp>
+
+#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons/json_error_category.hpp b/vendor/jsoncons-0.104.0/jsoncons/json_error_category.hpp
index 90d12d56..c09b847a 100644
--- a/vendor/jsoncons-0.99.2/jsoncons/json_error_category.hpp
+++ b/vendor/jsoncons-0.104.0/jsoncons/json_error_category.hpp
@@ -4,39 +4,47 @@
// See https://github.com/danielaparker/jsoncons for latest version
-#ifndef JSONCONS_JSON_TEXT_ERROR_CATEGORY_HPP
-#define JSONCONS_JSON_TEXT_ERROR_CATEGORY_HPP
+#ifndef JSONCONS_JSON_ERROR_CATEGORY_HPP
+#define JSONCONS_JSON_ERROR_CATEGORY_HPP
-#include "jsoncons/jsoncons.hpp"
#include <system_error>
+#include <jsoncons/jsoncons_config.hpp>
namespace jsoncons {
-namespace json_parser_errc
-{
- const int unexpected_eof = 1;
- const int invalid_json_text = 2;
- const int extra_character = 3;
- const int max_depth_exceeded = 4;
- const int single_quote = 5;
- const int illegal_character_in_string = 6;
- const int extra_comma = 7;
- const int expected_name = 8;
- const int expected_value = 9;
- const int invalid_value = 10;
- const int expected_colon = 11;
- const int illegal_control_character = 12;
- const int illegal_escaped_character = 13;
- const int expected_codepoint_surrogate_pair = 14;
- const int invalid_hex_escape_sequence = 15;
- const int invalid_unicode_escape_sequence = 16;
- const int leading_zero = 17;
- const int invalid_number = 18;
- const int expected_comma_or_right_brace = 19;
- const int expected_comma_or_right_bracket = 20;
- const int unexpected_right_bracket = 21;
- const int unexpected_right_brace = 22;
-}
+ enum class json_parser_errc
+ {
+ ok = 0,
+ unexpected_eof = 1,
+ source_error,
+ invalid_json_text,
+ extra_character,
+ max_depth_exceeded,
+ single_quote,
+ illegal_character_in_string,
+ extra_comma,
+ expected_name,
+ expected_value,
+ invalid_value,
+ expected_colon,
+ illegal_control_character,
+ illegal_escaped_character,
+ expected_codepoint_surrogate_pair,
+ invalid_hex_escape_sequence,
+ invalid_unicode_escape_sequence,
+ leading_zero,
+ invalid_number,
+ expected_comma_or_right_brace,
+ expected_comma_or_right_bracket,
+ unexpected_right_bracket,
+ unexpected_right_brace,
+ illegal_comment,
+ expected_continuation_byte,
+ over_long_utf8_sequence,
+ illegal_codepoint,
+ illegal_surrogate_value,
+ unpaired_high_surrogate
+ };
class json_error_category_impl
: public std::error_category
@@ -44,14 +52,16 @@ class json_error_category_impl
public:
virtual const char* name() const JSONCONS_NOEXCEPT
{
- return "json";
+ return "jsoncons";
}
virtual std::string message(int ev) const
{
- switch (ev)
+ switch (static_cast<json_parser_errc>(ev))
{
case json_parser_errc::unexpected_eof:
return "Unexpected end of file";
+ case json_parser_errc::source_error:
+ return "Source error";
case json_parser_errc::invalid_json_text:
return "Invalid JSON text";
case json_parser_errc::extra_character:
@@ -94,7 +104,19 @@ public:
return "Unexpected right brace '}'";
case json_parser_errc::unexpected_right_bracket:
return "Unexpected right bracket ']'";
- default:
+ case json_parser_errc::illegal_comment:
+ return "Illegal comment";
+ case json_parser_errc::expected_continuation_byte:
+ return "Expected continuation byte";
+ case json_parser_errc::over_long_utf8_sequence:
+ return "Over long UTF-8 sequence";
+ case json_parser_errc::illegal_codepoint:
+ return "Illegal codepoint (>= 0xd800 && <= 0xdfff)";
+ case json_parser_errc::illegal_surrogate_value:
+ return "UTF-16 surrogate values are illegal in UTF-32";
+ case json_parser_errc::unpaired_high_surrogate:
+ return "Expected low surrogate following the high surrogate";
+ default:
return "Unknown JSON parser error";
}
}
@@ -107,5 +129,20 @@ const std::error_category& json_error_category()
return instance;
}
+inline
+std::error_code make_error_code(json_parser_errc result)
+{
+ return std::error_code(static_cast<int>(result),json_error_category());
}
+
+
+}
+
+namespace std {
+ template<>
+ struct is_error_code_enum<jsoncons::json_parser_errc> : public true_type
+ {
+ };
+}
+
#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/json_exception.hpp b/vendor/jsoncons-0.104.0/jsoncons/json_exception.hpp
new file mode 100644
index 00000000..668fa3c5
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/json_exception.hpp
@@ -0,0 +1,107 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSON_EXCEPTION_HPP
+#define JSON_EXCEPTION_HPP
+
+#include <locale>
+#include <string>
+#include <vector>
+#include <cstdlib>
+#include <cwchar>
+#include <cstdint>
+#include <iostream>
+#include <vector>
+#include <iterator>
+#include <jsoncons/detail/unicode_traits.hpp>
+#include <jsoncons/jsoncons_config.hpp>
+
+namespace jsoncons {
+
+// json_exception
+
+class json_exception
+{
+public:
+ virtual const char* what() const JSONCONS_NOEXCEPT = 0;
+};
+
+template <class Base>
+class json_exception_impl : public Base, public virtual json_exception
+{
+public:
+ json_exception_impl(const std::string& s) JSONCONS_NOEXCEPT
+ : Base(""), message_(s)
+ {
+ }
+ ~json_exception_impl() JSONCONS_NOEXCEPT
+ {
+ }
+ const char* what() const JSONCONS_NOEXCEPT override
+ {
+ return message_.c_str();
+ }
+private:
+ std::string message_;
+};
+
+class key_not_found : public std::out_of_range, public virtual json_exception
+{
+public:
+ template <class CharT>
+ explicit key_not_found(const CharT* key, size_t length) JSONCONS_NOEXCEPT
+ : std::out_of_range("")
+ {
+ buffer_.append("Key '");
+ unicons::convert(key, key+length, std::back_inserter(buffer_),
+ unicons::conv_flags::strict);
+ buffer_.append("' not found");
+ }
+ ~key_not_found() JSONCONS_NOEXCEPT
+ {
+ }
+ const char* what() const JSONCONS_NOEXCEPT override
+ {
+ return buffer_.c_str();
+ }
+private:
+ std::string buffer_;
+};
+
+class not_an_object : public std::runtime_error, public virtual json_exception
+{
+public:
+ template <class CharT>
+ explicit not_an_object(const CharT* key, size_t length) JSONCONS_NOEXCEPT
+ : std::runtime_error("")
+ {
+ buffer_.append("Attempting to access or modify '");
+ unicons::convert(key, key+length, std::back_inserter(buffer_),
+ unicons::conv_flags::strict);
+ buffer_.append("' on a value that is not an object");
+ }
+ ~not_an_object() JSONCONS_NOEXCEPT
+ {
+ }
+ const char* what() const JSONCONS_NOEXCEPT override
+ {
+ return buffer_.c_str();
+ }
+private:
+ std::string buffer_;
+};
+
+#define JSONCONS_STR2(x) #x
+#define JSONCONS_STR(x) JSONCONS_STR2(x)
+
+#define JSONCONS_ASSERT(x) if (!(x)) { \
+ throw jsoncons::json_exception_impl<std::runtime_error>("assertion '" #x "' failed at " __FILE__ ":" \
+ JSONCONS_STR(__LINE__)); }
+
+#define JSONCONS_THROW(x) throw (x)
+
+}
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/json_filter.hpp b/vendor/jsoncons-0.104.0/jsoncons/json_filter.hpp
new file mode 100644
index 00000000..30b69e18
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/json_filter.hpp
@@ -0,0 +1,465 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSON_FILTER_HPP
+#define JSONCONS_JSON_FILTER_HPP
+
+#include <string>
+
+#include <jsoncons/json_input_handler.hpp>
+#include <jsoncons/json_output_handler.hpp>
+#include <jsoncons/parse_error_handler.hpp>
+
+namespace jsoncons {
+
+template <class CharT>
+class basic_json_output_input_adapter : public basic_json_input_handler<CharT>
+{
+public:
+ using typename basic_json_input_handler<CharT>::string_view_type;
+private:
+
+ basic_null_json_output_handler<CharT> null_output_handler_;
+ basic_json_output_handler<CharT>& output_handler_;
+
+ // noncopyable and nonmoveable
+ basic_json_output_input_adapter<CharT>(const basic_json_output_input_adapter<CharT>&) = delete;
+ basic_json_output_input_adapter<CharT>& operator=(const basic_json_output_input_adapter<CharT>&) = delete;
+
+public:
+ basic_json_output_input_adapter()
+ : output_handler_(null_output_handler_)
+ {
+ }
+
+ basic_json_output_input_adapter(basic_json_output_handler<CharT>& handler)
+ : output_handler_(handler)
+ {
+ }
+
+private:
+
+ void do_begin_json() override
+ {
+ output_handler_.begin_json();
+ }
+
+ void do_end_json() override
+ {
+ output_handler_.end_json();
+ }
+
+ void do_begin_object(const parsing_context&) override
+ {
+ output_handler_.begin_object();
+ }
+
+ void do_begin_object(size_t length, const parsing_context&) override
+ {
+ output_handler_.begin_object(length);
+ }
+
+ void do_end_object(const parsing_context&) override
+ {
+ output_handler_.end_object();
+ }
+
+ void do_begin_array(const parsing_context&) override
+ {
+ output_handler_.begin_array();
+ }
+
+ void do_begin_array(size_t length, const parsing_context&) override
+ {
+ output_handler_.begin_array(length);
+ }
+
+ void do_end_array(const parsing_context&) override
+ {
+ output_handler_.end_array();
+ }
+
+ void do_name(const string_view_type& name,
+ const parsing_context&) override
+ {
+ output_handler_.name(name);
+ }
+
+ void do_string_value(const string_view_type& value,
+ const parsing_context&) override
+ {
+ output_handler_.string_value(value);
+ }
+
+ void do_byte_string_value(const uint8_t* data, size_t length,
+ const parsing_context&) override
+ {
+ output_handler_.byte_string_value(data, length);
+ }
+
+ void do_integer_value(int64_t value, const parsing_context&) override
+ {
+ output_handler_.integer_value(value);
+ }
+
+ void do_uinteger_value(uint64_t value,
+ const parsing_context&) override
+ {
+ output_handler_.uinteger_value(value);
+ }
+
+ void do_double_value(double value, const number_format& fmt, const parsing_context&) override
+ {
+ output_handler_.double_value(value, fmt);
+ }
+
+ void do_bool_value(bool value, const parsing_context&) override
+ {
+ output_handler_.bool_value(value);
+ }
+
+ void do_null_value(const parsing_context&) override
+ {
+ output_handler_.null_value();
+ }
+};
+
+template <class CharT>
+class basic_json_input_output_adapter : public basic_json_output_handler<CharT>
+{
+public:
+ using typename basic_json_output_handler<CharT>::string_view_type ;
+private:
+ class null_parsing_context : public parsing_context
+ {
+ size_t do_line_number() const override { return 0; }
+
+ size_t do_column_number() const override { return 0; }
+ };
+ const null_parsing_context default_context_ = null_parsing_context();
+
+ basic_null_json_input_handler<CharT> null_input_handler_;
+ basic_json_output_input_adapter<CharT> default_input_output_adapter_;
+ basic_json_input_handler<CharT>& input_handler_;
+ const basic_json_output_input_adapter<CharT>& input_output_adapter_;
+
+ // noncopyable and nonmoveable
+ basic_json_input_output_adapter<CharT>(const basic_json_input_output_adapter<CharT>&) = delete;
+ basic_json_input_output_adapter<CharT>& operator=(const basic_json_input_output_adapter<CharT>&) = delete;
+
+public:
+ basic_json_input_output_adapter()
+ : input_handler_(null_input_handler_),
+ input_output_adapter_(default_input_output_adapter_)
+ {
+ }
+ basic_json_input_output_adapter(basic_json_input_handler<CharT>& input_handler)
+ : input_handler_(input_handler),
+ input_output_adapter_(default_input_output_adapter_)
+ {
+ }
+ basic_json_input_output_adapter(basic_json_input_handler<CharT>& input_handler,
+ const basic_json_output_input_adapter<CharT>& input_output_adapter)
+ : input_handler_(input_handler),
+ input_output_adapter_(input_output_adapter)
+ {
+ }
+
+private:
+
+ void do_begin_json() override
+ {
+ input_handler_.begin_json();
+ }
+
+ void do_end_json() override
+ {
+ input_handler_.end_json();
+ }
+
+ void do_begin_object() override
+ {
+ input_handler_.begin_object(default_context_);
+ }
+
+ void do_begin_object(size_t length) override
+ {
+ input_handler_.begin_object(length, default_context_);
+ }
+
+ void do_end_object() override
+ {
+ input_handler_.end_object(default_context_);
+ }
+
+ void do_begin_array() override
+ {
+ input_handler_.begin_array(default_context_);
+ }
+
+ void do_begin_array(size_t length) override
+ {
+ input_handler_.begin_array(length, default_context_);
+ }
+
+ void do_end_array() override
+ {
+ input_handler_.end_array(default_context_);
+ }
+
+ void do_name(const string_view_type& name) override
+ {
+ input_handler_.name(name, default_context_);
+ }
+
+ void do_string_value(const string_view_type& value) override
+ {
+ input_handler_.string_value(value, default_context_);
+ }
+
+ void do_byte_string_value(const uint8_t* data, size_t length) override
+ {
+ input_handler_.byte_string_value(data, length, default_context_);
+ }
+
+ void do_integer_value(int64_t value) override
+ {
+ input_handler_.integer_value(value, default_context_);
+ }
+
+ void do_uinteger_value(uint64_t value) override
+ {
+ input_handler_.uinteger_value(value, default_context_);
+ }
+
+ void do_double_value(double value, const number_format& fmt) override
+ {
+ input_handler_.double_value(value, fmt, default_context_);
+ }
+
+ void do_bool_value(bool value) override
+ {
+ input_handler_.bool_value(value, default_context_);
+ }
+
+ void do_null_value() override
+ {
+ input_handler_.null_value(default_context_);
+ }
+};
+
+template <class CharT>
+class basic_json_filter : public basic_json_input_handler<CharT>
+{
+public:
+ using typename basic_json_input_handler<CharT>::string_view_type ;
+private:
+ basic_json_output_input_adapter<CharT> input_output_adapter_;
+ basic_json_input_output_adapter<CharT> output_input_adapter_;
+ basic_json_output_handler<CharT>& output_handler_;
+ basic_json_input_handler<CharT>& downstream_handler_;
+
+ // noncopyable and nonmoveable
+ basic_json_filter<CharT>(const basic_json_filter<CharT>&) = delete;
+ basic_json_filter<CharT>& operator=(const basic_json_filter<CharT>&) = delete;
+public:
+ basic_json_filter(basic_json_output_handler<CharT>& handler)
+ : input_output_adapter_(handler),
+ output_input_adapter_(*this),
+ output_handler_(output_input_adapter_),
+ downstream_handler_(input_output_adapter_)
+ {
+ }
+
+ basic_json_filter(basic_json_input_handler<CharT>& handler)
+ : output_input_adapter_(*this),
+ output_handler_(output_input_adapter_),
+ downstream_handler_(handler)
+ {
+ }
+
+ operator basic_json_output_handler<CharT>&()
+ {
+ return output_handler_;
+ }
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+ basic_json_input_handler<CharT>& input_handler()
+ {
+ return downstream_handler_;
+ }
+#endif
+
+ basic_json_input_handler<CharT>& downstream_handler()
+ {
+ return downstream_handler_;
+ }
+
+private:
+ void do_begin_json() override
+ {
+ downstream_handler_.begin_json();
+ }
+
+ void do_end_json() override
+ {
+ downstream_handler_.end_json();
+ }
+
+ void do_begin_object(const parsing_context& context) override
+ {
+ downstream_handler_.begin_object(context);
+ }
+
+ void do_begin_object(size_t length, const parsing_context& context) override
+ {
+ downstream_handler_.begin_object(length, context);
+ }
+
+ void do_end_object(const parsing_context& context) override
+ {
+ downstream_handler_.end_object(context);
+ }
+
+ void do_begin_array(const parsing_context& context) override
+ {
+ downstream_handler_.begin_array(context);
+ }
+
+ void do_begin_array(size_t length, const parsing_context& context) override
+ {
+ downstream_handler_.begin_array(length, context);
+ }
+
+ void do_end_array(const parsing_context& context) override
+ {
+ downstream_handler_.end_array(context);
+ }
+
+ void do_name(const string_view_type& name,
+ const parsing_context& context) override
+ {
+ downstream_handler_.name(name,context);
+ }
+
+ void do_string_value(const string_view_type& value,
+ const parsing_context& context) override
+ {
+ downstream_handler_.string_value(value,context);
+ }
+
+ void do_byte_string_value(const uint8_t* data, size_t length,
+ const parsing_context& context) override
+ {
+ downstream_handler_.byte_string_value(data, length, context);
+ }
+
+ void do_double_value(double value, const number_format& fmt,
+ const parsing_context& context) override
+ {
+ downstream_handler_.double_value(value, fmt, context);
+ }
+
+ void do_integer_value(int64_t value,
+ const parsing_context& context) override
+ {
+ downstream_handler_.integer_value(value,context);
+ }
+
+ void do_uinteger_value(uint64_t value,
+ const parsing_context& context) override
+ {
+ downstream_handler_.uinteger_value(value,context);
+ }
+
+ void do_bool_value(bool value,
+ const parsing_context& context) override
+ {
+ downstream_handler_.bool_value(value,context);
+ }
+
+ void do_null_value(const parsing_context& context) override
+ {
+ downstream_handler_.null_value(context);
+ }
+
+};
+
+// Filters out begin_json and end_json events
+template <class CharT>
+class basic_json_fragment_filter : public basic_json_filter<CharT>
+{
+public:
+ using typename basic_json_filter<CharT>::string_view_type;
+
+ basic_json_fragment_filter(basic_json_input_handler<CharT>& handler)
+ : basic_json_filter<CharT>(handler)
+ {
+ }
+private:
+ void do_begin_json() override
+ {
+ }
+
+ void do_end_json() override
+ {
+ }
+};
+
+template <class CharT>
+class basic_rename_object_member_filter : public basic_json_filter<CharT>
+{
+public:
+ using typename basic_json_filter<CharT>::string_view_type;
+
+private:
+ std::basic_string<CharT> name_;
+ std::basic_string<CharT> new_name_;
+public:
+ basic_rename_object_member_filter(const std::basic_string<CharT>& name,
+ const std::basic_string<CharT>& new_name,
+ basic_json_output_handler<CharT>& handler)
+ : basic_json_filter<CharT>(handler),
+ name_(name), new_name_(new_name)
+ {
+ }
+
+ basic_rename_object_member_filter(const std::basic_string<CharT>& name,
+ const std::basic_string<CharT>& new_name,
+ basic_json_input_handler<CharT>& handler)
+ : basic_json_filter<CharT>(handler),
+ name_(name), new_name_(new_name)
+ {
+ }
+
+private:
+ void do_name(const string_view_type& name,
+ const parsing_context& context) override
+ {
+ if (name == name_)
+ {
+ this->downstream_handler().name(new_name_,context);
+ }
+ else
+ {
+ this->downstream_handler().name(name,context);
+ }
+ }
+};
+
+typedef basic_json_filter<char> json_filter;
+typedef basic_json_filter<wchar_t> wjson_filter;
+typedef basic_rename_object_member_filter<char> rename_object_member_filter;
+typedef basic_rename_object_member_filter<wchar_t> wrename_object_member_filter;
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+typedef basic_rename_object_member_filter<char> rename_name_filter;
+typedef basic_rename_object_member_filter<wchar_t> wrename_name_filter;
+#endif
+
+}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/json_input_handler.hpp b/vendor/jsoncons-0.104.0/jsoncons/json_input_handler.hpp
new file mode 100644
index 00000000..ed014287
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/json_input_handler.hpp
@@ -0,0 +1,308 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSON_INPUT_HANDLER_HPP
+#define JSONCONS_JSON_INPUT_HANDLER_HPP
+
+#include <string>
+#include <jsoncons/json_exception.hpp>
+#include <jsoncons/jsoncons_utilities.hpp>
+#if !defined(JSONCONS_NO_DEPRECATED)
+#include <jsoncons/json_type_traits.hpp> // for null_type
+#endif
+
+namespace jsoncons {
+
+class parsing_context;
+
+template <class CharT>
+class basic_json_input_handler
+{
+public:
+ typedef CharT char_type;
+ typedef std::char_traits<char_type> char_traits_type;
+
+ typedef basic_string_view_ext<char_type,char_traits_type> string_view_type;
+
+ virtual ~basic_json_input_handler() {}
+
+ void begin_json()
+ {
+ do_begin_json();
+ }
+
+ void end_json()
+ {
+ do_end_json();
+ }
+
+ void begin_object(const parsing_context& context)
+ {
+ do_begin_object(context);
+ }
+
+ void begin_object(size_t length, const parsing_context& context)
+ {
+ do_begin_object(length, context);
+ }
+
+ void end_object(const parsing_context& context)
+ {
+ do_end_object(context);
+ }
+
+ void begin_array(const parsing_context& context)
+ {
+ do_begin_array(context);
+ }
+
+ void begin_array(size_t length, const parsing_context& context)
+ {
+ do_begin_array(length, context);
+ }
+
+ void end_array(const parsing_context& context)
+ {
+ do_end_array(context);
+ }
+
+ void name(const string_view_type& name, const parsing_context& context)
+ {
+ do_name(name, context);
+ }
+
+// new
+
+ void string_value(const string_view_type& value, const parsing_context& context)
+ {
+ do_string_value(value, context);
+ }
+
+ void byte_string_value(const uint8_t* data, size_t length, const parsing_context& context)
+ {
+ do_byte_string_value(data, length, context);
+ }
+
+ void integer_value(int64_t value, const parsing_context& context)
+ {
+ do_integer_value(value,context);
+ }
+
+ void uinteger_value(uint64_t value, const parsing_context& context)
+ {
+ do_uinteger_value(value,context);
+ }
+
+ void double_value(double value, const parsing_context& context)
+ {
+ do_double_value(value, number_format(), context);
+ }
+
+ void double_value(double value, uint8_t precision, const parsing_context& context)
+ {
+ do_double_value(value, number_format(precision, 0), context);
+ }
+
+ void double_value(double value, const number_format& fmt, const parsing_context& context)
+ {
+ do_double_value(value, fmt, context);
+ }
+
+ void bool_value(bool value, const parsing_context& context)
+ {
+ do_bool_value(value,context);
+ }
+
+ void null_value(const parsing_context& context)
+ {
+ do_null_value(context);
+ }
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+
+ void name(const CharT* p, size_t length, const parsing_context& context)
+ {
+ do_name(string_view_type(p, length), context);
+ }
+
+ void value(const std::basic_string<CharT>& value, const parsing_context& context)
+ {
+ do_string_value(value, context);
+ }
+
+ void value(const CharT* p, size_t length, const parsing_context& context)
+ {
+ do_string_value(string_view_type(p, length), context);
+ }
+
+ void value(const CharT* p, const parsing_context& context)
+ {
+ do_string_value(string_view_type(p), context);
+ }
+
+ void value(int value, const parsing_context& context)
+ {
+ do_integer_value(value,context);
+ }
+
+ void value(long value, const parsing_context& context)
+ {
+ do_integer_value(value,context);
+ }
+
+ void value(long long value, const parsing_context& context)
+ {
+ do_integer_value(value,context);
+ }
+
+ void value(unsigned int value, const parsing_context& context)
+ {
+ do_uinteger_value(value,context);
+ }
+
+ void value(unsigned long value, const parsing_context& context)
+ {
+ do_uinteger_value(value,context);
+ }
+
+ void value(unsigned long long value, const parsing_context& context)
+ {
+ do_uinteger_value(value,context);
+ }
+
+ void value(float value, uint8_t precision, const parsing_context& context)
+ {
+ do_double_value(value, number_format(precision, 0), context);
+ }
+
+ void value(double value, uint8_t precision, const parsing_context& context)
+ {
+ do_double_value(value, number_format(precision, 0), context);
+ }
+
+ void value(bool value, const parsing_context& context)
+ {
+ do_bool_value(value,context);
+ }
+
+ void value(null_type, const parsing_context& context)
+ {
+ do_null_value(context);
+ }
+#endif
+
+private:
+ virtual void do_begin_json() = 0;
+
+ virtual void do_end_json() = 0;
+
+ virtual void do_begin_object(const parsing_context& context) = 0;
+
+ virtual void do_begin_object(size_t length, const parsing_context& context)
+ {
+ do_begin_object(context);
+ }
+
+ virtual void do_end_object(const parsing_context& context) = 0;
+
+ virtual void do_begin_array(const parsing_context& context) = 0;
+
+ virtual void do_begin_array(size_t length, const parsing_context& context)
+ {
+ do_begin_array(context);
+ }
+
+ virtual void do_end_array(const parsing_context& context) = 0;
+
+ virtual void do_name(const string_view_type& name, const parsing_context& context) = 0;
+
+ virtual void do_null_value(const parsing_context& context) = 0;
+
+ virtual void do_string_value(const string_view_type& value, const parsing_context& context) = 0;
+
+ virtual void do_byte_string_value(const uint8_t* data, size_t length, const parsing_context& context) = 0;
+
+ virtual void do_double_value(double value, const number_format& fmt, const parsing_context& context) = 0;
+
+ virtual void do_integer_value(int64_t value, const parsing_context& context) = 0;
+
+ virtual void do_uinteger_value(uint64_t value, const parsing_context& context) = 0;
+
+ virtual void do_bool_value(bool value, const parsing_context& context) = 0;
+};
+
+template <class CharT>
+class basic_null_json_input_handler final : public basic_json_input_handler<CharT>
+{
+public:
+ using typename basic_json_input_handler<CharT>::string_view_type ;
+private:
+ void do_begin_json() override
+ {
+ }
+
+ void do_end_json() override
+ {
+ }
+
+ void do_begin_object(const parsing_context&) override
+ {
+ }
+
+ void do_end_object(const parsing_context&) override
+ {
+ }
+
+ void do_begin_array(const parsing_context&) override
+ {
+ }
+
+ void do_end_array(const parsing_context&) override
+ {
+ }
+
+ void do_name(const string_view_type&, const parsing_context&) override
+ {
+ }
+
+ void do_null_value(const parsing_context&) override
+ {
+ }
+
+ void do_string_value(const string_view_type&, const parsing_context&) override
+ {
+ }
+
+ void do_byte_string_value(const uint8_t* data, size_t length, const parsing_context&) override
+ {
+ }
+
+ void do_double_value(double, const number_format& fmt, const parsing_context&) override
+ {
+ }
+
+ void do_integer_value(int64_t, const parsing_context&) override
+ {
+ }
+
+ void do_uinteger_value(uint64_t, const parsing_context&) override
+ {
+ }
+
+ void do_bool_value(bool, const parsing_context&) override
+ {
+ }
+};
+
+typedef basic_json_input_handler<char> json_input_handler;
+typedef basic_json_input_handler<wchar_t> wjson_input_handler;
+
+typedef basic_null_json_input_handler<char> null_json_input_handler;
+typedef basic_null_json_input_handler<wchar_t> wnull_json_input_handler;
+
+}
+
+#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons/json_output_handler.hpp b/vendor/jsoncons-0.104.0/jsoncons/json_output_handler.hpp
index d0f3de8f..b16f098e 100644
--- a/vendor/jsoncons-0.99.2/jsoncons/json_output_handler.hpp
+++ b/vendor/jsoncons-0.104.0/jsoncons/json_output_handler.hpp
@@ -8,50 +8,23 @@
#define JSONCONS_JSON_OUTPUT_HANDLER_HPP
#include <string>
-#include "jsoncons/jsoncons.hpp"
+#include <jsoncons/json_exception.hpp>
+#include <jsoncons/jsoncons_utilities.hpp>
+#if !defined(JSONCONS_NO_DEPRECATED)
+#include <jsoncons/json_type_traits.hpp> // for null_type
+#endif
namespace jsoncons {
-template<typename CharT>
-void print_integer(int64_t value, buffered_ostream<CharT>& os)
-{
- CharT buf[255];
- uint64_t u = (value < 0) ? static_cast<uint64_t>(-value) : static_cast<uint64_t>(value);
- CharT* p = buf;
- do
- {
- *p++ = static_cast<CharT>(48 + u%10);
- }
- while (u /= 10);
- if (value < 0)
- {
- os.put('-');
- }
- while (--p >= buf)
- {
- os.put(*p);
- }
-}
-
-template<typename CharT>
-void print_uinteger(uint64_t value, buffered_ostream<CharT>& os)
-{
- CharT buf[255];
- CharT* p = buf;
- do
- {
- *p++ = static_cast<CharT>(48 + value % 10);
- } while (value /= 10);
- while (--p >= buf)
- {
- os.put(*p);
- }
-}
-
-template <typename CharT>
+template <class CharT>
class basic_json_output_handler
{
public:
+ typedef CharT char_type;
+ typedef std::char_traits<char_type> char_traits_type;
+
+ typedef basic_string_view_ext<char_type,char_traits_type> string_view_type;
+
virtual ~basic_json_output_handler() {}
// Overloaded methods
@@ -71,6 +44,11 @@ public:
do_begin_object();
}
+ void begin_object(size_t length)
+ {
+ do_begin_object(length);
+ }
+
void end_object()
{
do_end_object();
@@ -81,34 +59,86 @@ public:
do_begin_array();
}
+ void begin_array(size_t length)
+ {
+ do_begin_array(length);
+ }
+
void end_array()
{
do_end_array();
}
- void name(const std::basic_string<CharT>& name)
+ void name(const string_view_type& name)
+ {
+ do_name(name);
+ }
+
+ void string_value(const string_view_type& value)
+ {
+ do_string_value(value);
+ }
+
+ void byte_string_value(const uint8_t* data, size_t length)
{
- do_name(name.data(), name.length());
+ do_byte_string_value(data, length);
}
+ void integer_value(int64_t value)
+ {
+ do_integer_value(value);
+ }
+
+ void uinteger_value(uint64_t value)
+ {
+ do_uinteger_value(value);
+ }
+
+ void double_value(double value)
+ {
+ do_double_value(value, number_format());
+ }
+
+ void double_value(double value, uint8_t precision)
+ {
+ do_double_value(value, number_format(precision, 0));
+ }
+
+ void double_value(double value, const number_format& fmt)
+ {
+ do_double_value(value, fmt);
+ }
+
+ void bool_value(bool value)
+ {
+ do_bool_value(value);
+ }
+
+ void null_value()
+ {
+ do_null_value();
+ }
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+
void name(const CharT* p, size_t length)
{
- do_name(p, length);
+ do_name(string_view_type(p, length));
}
- void value(const std::basic_string<CharT>& value)
+ void value(const string_view_type& value)
{
- do_string_value(value.data(), value.length());
+ do_string_value(value);
}
void value(const CharT* p, size_t length)
{
- do_string_value(p, length);
+ do_string_value(string_view_type(p, length));
}
void value(const CharT* p)
{
- do_string_value(p, std::char_traits<CharT>::length(p));
+ do_string_value(string_view_type(p));
}
void value(int value)
@@ -141,9 +171,9 @@ public:
do_uinteger_value(value);
}
- void value(double value, uint8_t precision = 0)
+ void value(double value, uint8_t precision = 0, uint8_t decimal_places = 0)
{
- do_double_value(value, precision);
+ do_double_value(value, precision, decimal_places);
}
void value(bool value)
@@ -155,6 +185,7 @@ public:
{
do_null_value();
}
+#endif
private:
@@ -162,21 +193,33 @@ private:
virtual void do_end_json() = 0;
- virtual void do_name(const CharT* name, size_t length) = 0;
+ virtual void do_name(const string_view_type& name) = 0;
virtual void do_begin_object() = 0;
+ virtual void do_begin_object(size_t length)
+ {
+ do_begin_object();
+ }
+
virtual void do_end_object() = 0;
virtual void do_begin_array() = 0;
+ virtual void do_begin_array(size_t length)
+ {
+ do_begin_array();
+ }
+
virtual void do_end_array() = 0;
virtual void do_null_value() = 0;
- virtual void do_string_value(const CharT* value, size_t length) = 0;
+ virtual void do_string_value(const string_view_type& value) = 0;
+
+ virtual void do_byte_string_value(const uint8_t* data, size_t length) = 0;
- virtual void do_double_value(double value, uint8_t precision) = 0;
+ virtual void do_double_value(double value, const number_format& fmt) = 0;
virtual void do_integer_value(int64_t value) = 0;
@@ -185,9 +228,11 @@ private:
virtual void do_bool_value(bool value) = 0;
};
-template <typename CharT>
-class null_json_output_handler_impl : public basic_json_output_handler<CharT>
+template <class CharT>
+class basic_null_json_output_handler : public basic_json_output_handler<CharT>
{
+public:
+ using typename basic_json_output_handler<CharT>::string_view_type ;
private:
void do_begin_json() override
@@ -198,10 +243,8 @@ private:
{
}
- void do_name(const CharT* name, size_t length) override
+ void do_name(const string_view_type&) override
{
- (void)name;
- (void)length;
}
void do_begin_object() override
@@ -224,13 +267,15 @@ private:
{
}
- void do_string_value(const CharT* p, size_t length) override
+ void do_string_value(const string_view_type&) override
{
- (void)p;
- (void)length;
}
- void do_double_value(double, uint8_t) override
+ void do_byte_string_value(const uint8_t* data, size_t length) override
+ {
+ }
+
+ void do_double_value(double, const number_format&) override
{
}
@@ -248,13 +293,6 @@ private:
};
-template<typename CharT>
-basic_json_output_handler<CharT>& null_json_output_handler()
-{
- static null_json_output_handler_impl<CharT> instance;
- return instance;
-}
-
typedef basic_json_output_handler<char> json_output_handler;
typedef basic_json_output_handler<wchar_t> wjson_output_handler;
diff --git a/vendor/jsoncons-0.104.0/jsoncons/json_parser.hpp b/vendor/jsoncons-0.104.0/jsoncons/json_parser.hpp
new file mode 100644
index 00000000..13bd9500
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/json_parser.hpp
@@ -0,0 +1,2830 @@
+// Copyright 2015 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSON_PARSER_HPP
+#define JSONCONS_JSON_PARSER_HPP
+
+#include <memory>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <cstdlib>
+#include <stdexcept>
+#include <system_error>
+#include <jsoncons/json_exception.hpp>
+#include <jsoncons/json_input_handler.hpp>
+#include <jsoncons/parse_error_handler.hpp>
+#include <jsoncons/json_error_category.hpp>
+#include <jsoncons/detail/number_parsers.hpp>
+
+#define JSONCONS_ILLEGAL_CONTROL_CHARACTER \
+ case 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06:case 0x07:case 0x08:case 0x0b: \
+ case 0x0c:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12:case 0x13:case 0x14:case 0x15:case 0x16: \
+ case 0x17:case 0x18:case 0x19:case 0x1a:case 0x1b:case 0x1c:case 0x1d:case 0x1e:case 0x1f
+
+namespace jsoncons {
+
+enum class parse_state : uint8_t
+{
+ root,
+ start,
+ slash,
+ slash_slash,
+ slash_star,
+ slash_star_star,
+ expect_comma_or_end,
+ object,
+ expect_member_name_or_end,
+ expect_member_name,
+ expect_colon,
+ expect_value_or_end,
+ expect_value,
+ array,
+ string_u1,
+ member_name,
+ escape,
+ escape_u1,
+ escape_u2,
+ escape_u3,
+ escape_u4,
+ escape_expect_surrogate_pair1,
+ escape_expect_surrogate_pair2,
+ escape_u6,
+ escape_u7,
+ escape_u8,
+ escape_u9,
+ minus,
+ zero,
+ integer,
+ fraction1,
+ fraction2,
+ exp1,
+ exp2,
+ exp3,
+ n,
+ nu,
+ nul,
+ t,
+ tr,
+ tru,
+ f,
+ fa,
+ fal,
+ fals,
+ cr,
+ lf,
+ done
+};
+
+template <class CharT, class Allocator = std::allocator<char>>
+class basic_json_parser : private parsing_context
+{
+ static const size_t initial_string_buffer_capacity_ = 1024;
+ static const size_t initial_number_buffer_capacity_ = 64;
+ static const int default_initial_stack_capacity_ = 100;
+ typedef typename basic_json_input_handler<CharT>::string_view_type string_view_type;
+
+ basic_null_json_input_handler<CharT> default_input_handler_;
+ default_parse_error_handler default_err_handler_;
+
+ basic_json_input_handler<CharT>& handler_;
+ parse_error_handler& err_handler_;
+ uint32_t cp_;
+ uint32_t cp2_;
+
+ typedef Allocator allocator_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<CharT> char_allocator_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<char> numeral_allocator_type;
+
+ std::basic_string<CharT,std::char_traits<CharT>,char_allocator_type> string_buffer_;
+ std::basic_string<char,std::char_traits<char>,numeral_allocator_type> number_buffer_;
+
+ bool is_negative_;
+ uint8_t precision_;
+ uint8_t decimal_places_;
+
+ size_t line_;
+ size_t column_;
+ int nesting_depth_;
+ int initial_stack_capacity_;
+
+ int max_depth_;
+ detail::string_to_double to_double_;
+ const CharT* begin_input_;
+ const CharT* input_end_;
+ const CharT* input_ptr_;
+
+ parse_state state_;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<parse_state> parse_state_allocator_type;
+ std::vector<parse_state,parse_state_allocator_type> state_stack_;
+
+ // Noncopyable and nonmoveable
+ basic_json_parser(const basic_json_parser&) = delete;
+ basic_json_parser& operator=(const basic_json_parser&) = delete;
+
+public:
+
+ basic_json_parser()
+ : handler_(default_input_handler_),
+ err_handler_(default_err_handler_),
+ cp_(0),
+ cp2_(0),
+ is_negative_(false),
+ precision_(0),
+ decimal_places_(0),
+ line_(1),
+ column_(1),
+ nesting_depth_(0),
+ initial_stack_capacity_(default_initial_stack_capacity_),
+ begin_input_(nullptr),
+ input_end_(nullptr),
+ input_ptr_(nullptr),
+ state_(parse_state::start)
+ {
+ string_buffer_.reserve(initial_string_buffer_capacity_);
+ number_buffer_.reserve(initial_number_buffer_capacity_);
+ max_depth_ = (std::numeric_limits<int>::max)();
+
+ state_stack_.reserve(initial_stack_capacity_);
+ push_state(parse_state::root);
+ }
+
+ basic_json_parser(parse_error_handler& err_handler)
+ : handler_(default_input_handler_),
+ err_handler_(err_handler),
+ cp_(0),
+ cp2_(0),
+ is_negative_(false),
+ precision_(0),
+ decimal_places_(0),
+ line_(1),
+ column_(1),
+ nesting_depth_(0),
+ initial_stack_capacity_(default_initial_stack_capacity_),
+ begin_input_(nullptr),
+ input_end_(nullptr),
+ input_ptr_(nullptr),
+ state_(parse_state::start)
+ {
+ string_buffer_.reserve(initial_string_buffer_capacity_);
+ number_buffer_.reserve(initial_number_buffer_capacity_);
+ max_depth_ = (std::numeric_limits<int>::max)();
+
+ state_stack_.reserve(initial_stack_capacity_);
+ push_state(parse_state::root);
+ }
+
+ basic_json_parser(basic_json_input_handler<CharT>& handler)
+ : handler_(handler),
+ err_handler_(default_err_handler_),
+ cp_(0),
+ cp2_(0),
+ is_negative_(false),
+ precision_(0),
+ decimal_places_(0),
+ line_(1),
+ column_(1),
+ nesting_depth_(0),
+ initial_stack_capacity_(default_initial_stack_capacity_),
+ begin_input_(nullptr),
+ input_end_(nullptr),
+ input_ptr_(nullptr),
+ state_(parse_state::start)
+ {
+ string_buffer_.reserve(initial_string_buffer_capacity_);
+ number_buffer_.reserve(initial_number_buffer_capacity_);
+ max_depth_ = (std::numeric_limits<int>::max)();
+
+ state_stack_.reserve(initial_stack_capacity_);
+ push_state(parse_state::root);
+ }
+
+ basic_json_parser(basic_json_input_handler<CharT>& handler,
+ parse_error_handler& err_handler)
+ : handler_(handler),
+ err_handler_(err_handler),
+ cp_(0),
+ cp2_(0),
+ is_negative_(false),
+ precision_(0),
+ decimal_places_(0),
+ line_(1),
+ column_(1),
+ nesting_depth_(0),
+ initial_stack_capacity_(default_initial_stack_capacity_),
+ begin_input_(nullptr),
+ input_end_(nullptr),
+ input_ptr_(nullptr),
+ state_(parse_state::start)
+ {
+ string_buffer_.reserve(initial_string_buffer_capacity_);
+ number_buffer_.reserve(initial_number_buffer_capacity_);
+ max_depth_ = (std::numeric_limits<int>::max)();
+
+ state_stack_.reserve(initial_stack_capacity_);
+ push_state(parse_state::root);
+ }
+
+ size_t line_number() const
+ {
+ return line_;
+ }
+
+ size_t column_number() const
+ {
+ return column_;
+ }
+
+ void set_column_number(size_t column)
+ {
+ column_ = column;
+ }
+
+ bool source_exhausted() const
+ {
+ return input_ptr_ == input_end_;
+ }
+
+ const parsing_context& parsing_context() const
+ {
+ return *this;
+ }
+
+ ~basic_json_parser()
+ {
+ }
+
+ size_t max_nesting_depth() const
+ {
+ return static_cast<size_t>(max_depth_);
+ }
+
+ void max_nesting_depth(size_t max_nesting_depth)
+ {
+ max_depth_ = static_cast<int>((std::min)(max_nesting_depth,static_cast<size_t>((std::numeric_limits<int>::max)())));
+ }
+
+ parse_state parent() const
+ {
+ JSONCONS_ASSERT(state_stack_.size() >= 1);
+ return state_stack_.back();
+ }
+
+ bool done() const
+ {
+ return state_ == parse_state::done;
+ }
+
+ void skip_whitespace()
+ {
+ const CharT* local_input_end = input_end_;
+ for (;;)
+ {
+ if (JSONCONS_UNLIKELY(input_ptr_ == local_input_end))
+ {
+ return;
+ }
+ else if (*input_ptr_ == ' ' || *input_ptr_ == '\t')
+ {
+ ++input_ptr_;
+ ++column_;
+ }
+ else
+ {
+ return;
+ }
+ }
+ }
+
+ void do_begin_object(std::error_code& ec)
+ {
+ if (++nesting_depth_ >= max_depth_)
+ {
+ if (err_handler_.error(json_parser_errc::max_depth_exceeded, *this))
+ {
+ ec = json_parser_errc::max_depth_exceeded;
+ return;
+ }
+ }
+ push_state(parse_state::object);
+ state_ = parse_state::expect_member_name_or_end;
+ handler_.begin_object(*this);
+ }
+
+ void do_end_object(std::error_code& ec)
+ {
+ --nesting_depth_;
+ state_ = pop_state();
+ if (state_ == parse_state::object)
+ {
+ handler_.end_object(*this);
+ }
+ else if (state_ == parse_state::array)
+ {
+ err_handler_.fatal_error(json_parser_errc::expected_comma_or_right_bracket, *this);
+ ec = json_parser_errc::expected_comma_or_right_bracket;
+ return;
+ }
+ else
+ {
+ err_handler_.fatal_error(json_parser_errc::unexpected_right_brace, *this);
+ ec = json_parser_errc::unexpected_right_brace;
+ return;
+ }
+
+ if (parent() == parse_state::root)
+ {
+ state_ = parse_state::done;
+ handler_.end_json();
+ }
+ else
+ {
+ state_ = parse_state::expect_comma_or_end;
+ }
+ }
+
+ void do_begin_array(std::error_code& ec)
+ {
+ if (++nesting_depth_ >= max_depth_)
+ {
+ if (err_handler_.error(json_parser_errc::max_depth_exceeded, *this))
+ {
+ ec = json_parser_errc::max_depth_exceeded;
+ return;
+ }
+
+ }
+ push_state(parse_state::array);
+ state_ = parse_state::expect_value_or_end;
+ handler_.begin_array(*this);
+ }
+
+ void do_end_array(std::error_code& ec)
+ {
+ --nesting_depth_;
+ state_ = pop_state();
+ if (state_ == parse_state::array)
+ {
+ handler_.end_array(*this);
+ }
+ else if (state_ == parse_state::object)
+ {
+ err_handler_.fatal_error(json_parser_errc::expected_comma_or_right_brace, *this);
+ ec = json_parser_errc::expected_comma_or_right_brace;
+ return;
+ }
+ else
+ {
+ err_handler_.fatal_error(json_parser_errc::unexpected_right_bracket, *this);
+ ec = json_parser_errc::unexpected_right_bracket;
+ return;
+ }
+ if (parent() == parse_state::root)
+ {
+ state_ = parse_state::done;
+ handler_.end_json();
+ }
+ else
+ {
+ state_ = parse_state::expect_comma_or_end;
+ }
+ }
+
+ void reset()
+ {
+ state_stack_.clear();
+ state_stack_.reserve(initial_stack_capacity_);
+ push_state(parse_state::root);
+ state_ = parse_state::start;
+ line_ = 1;
+ column_ = 1;
+ nesting_depth_ = 0;
+ }
+
+ void check_done()
+ {
+ std::error_code ec;
+ check_done(ec);
+ if (ec)
+ {
+ throw parse_error(ec,line_,column_);
+ }
+ }
+
+ void check_done(std::error_code& ec)
+ {
+ if (state_ != parse_state::done)
+ {
+ if (err_handler_.error(json_parser_errc::unexpected_eof, *this))
+ {
+ ec = json_parser_errc::unexpected_eof;
+ return;
+ }
+ }
+ for (; input_ptr_ != input_end_; ++input_ptr_)
+ {
+ CharT curr_char_ = *input_ptr_;
+ switch (curr_char_)
+ {
+ case '\n':
+ case '\r':
+ case '\t':
+ case ' ':
+ break;
+ default:
+ if (err_handler_.error(json_parser_errc::extra_character, *this))
+ {
+ ec = json_parser_errc::extra_character;
+ return;
+ }
+ break;
+ }
+ }
+ }
+
+ void parse_some(std::error_code& ec)
+ {
+ const CharT* local_input_end = input_end_;
+
+ while ((input_ptr_ < local_input_end) && (state_ != parse_state::done))
+ {
+ switch (state_)
+ {
+ case parse_state::cr:
+ ++line_;
+ column_ = 1;
+ switch (*input_ptr_)
+ {
+ case '\n':
+ state_ = pop_state();
+ ++input_ptr_;
+ break;
+ default:
+ state_ = pop_state();
+ break;
+ }
+ break;
+ case parse_state::lf:
+ ++line_;
+ column_ = 1;
+ state_ = pop_state();
+ break;
+ case parse_state::start:
+ {
+ handler_.begin_json();
+ switch (*input_ptr_)
+ {
+ JSONCONS_ILLEGAL_CONTROL_CHARACTER:
+ if (err_handler_.error(json_parser_errc::illegal_control_character, *this))
+ {
+ ec = json_parser_errc::illegal_control_character;
+ return;
+ }
+ break;
+ case '\r':
+ push_state(state_);
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::cr;
+ break;
+ case '\n':
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::lf;
+ break;
+ case ' ':case '\t':
+ skip_whitespace();
+ break;
+ case '/':
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::slash;
+ break;
+ case '{':
+ do_begin_object(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ break;
+ case '[':
+ do_begin_array(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ break;
+ case '\"':
+ state_ = parse_state::string_u1;
+ ++input_ptr_;
+ ++column_;
+ break;
+ case '-':
+ number_buffer_.clear();
+ is_negative_ = true;
+ precision_ = 0;
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::minus;
+ parse_number(ec);
+ if (ec) {return;}
+ break;
+ case '0':
+ number_buffer_.clear();
+ is_negative_ = false;
+ precision_ = 1;
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ state_ = parse_state::zero;
+ ++input_ptr_;
+ ++column_;
+ parse_number(ec);
+ if (ec) {return;}
+ break;
+ case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
+ number_buffer_.clear();
+ is_negative_ = false;
+ precision_ = 1;
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::integer;
+ parse_number(ec);
+ if (ec) {return;}
+ break;
+ case 'n':
+ parse_null(ec);
+ if (ec) {return;}
+ break;
+ case 't':
+ parse_true(ec);
+ if (ec) {return;}
+ break;
+ case 'f':
+ parse_false(ec);
+ if (ec) {return;}
+ break;
+ case '}':
+ err_handler_.fatal_error(json_parser_errc::unexpected_right_brace, *this);
+ ec = json_parser_errc::unexpected_right_brace;
+ return;
+ case ']':
+ err_handler_.fatal_error(json_parser_errc::unexpected_right_bracket, *this);
+ ec = json_parser_errc::unexpected_right_bracket;
+ return;
+ default:
+ err_handler_.fatal_error(json_parser_errc::invalid_json_text, *this);
+ ec = json_parser_errc::invalid_json_text;
+ return;
+ }
+ }
+ break;
+
+ case parse_state::expect_comma_or_end:
+ {
+ switch (*input_ptr_)
+ {
+ JSONCONS_ILLEGAL_CONTROL_CHARACTER:
+ if (err_handler_.error(json_parser_errc::illegal_control_character, *this))
+ {
+ ec = json_parser_errc::illegal_control_character;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ case '\r':
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::cr;
+ break;
+ case '\n':
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::lf;
+ break;
+ case ' ':case '\t':
+ skip_whitespace();
+ break;
+ case '/':
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::slash;
+ break;
+ case '}':
+ do_end_object(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ break;
+ case ']':
+ do_end_array(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ break;
+ case ',':
+ begin_member_or_element(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ break;
+ default:
+ if (parent() == parse_state::array)
+ {
+ if (err_handler_.error(json_parser_errc::expected_comma_or_right_bracket, *this))
+ {
+ ec = json_parser_errc::expected_comma_or_right_bracket;
+ return;
+ }
+ }
+ else if (parent() == parse_state::object)
+ {
+ if (err_handler_.error(json_parser_errc::expected_comma_or_right_brace, *this))
+ {
+ ec = json_parser_errc::expected_comma_or_right_brace;
+ return;
+ }
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ }
+ }
+ break;
+ case parse_state::expect_member_name_or_end:
+ {
+ switch (*input_ptr_)
+ {
+ JSONCONS_ILLEGAL_CONTROL_CHARACTER:
+ if (err_handler_.error(json_parser_errc::illegal_control_character, *this))
+ {
+ ec = json_parser_errc::illegal_control_character;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ case '\r':
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::cr;
+ break;
+ case '\n':
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::lf;
+ break;
+ case ' ':case '\t':
+ skip_whitespace();
+ break;
+ case '/':
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::slash;
+ break;
+ case '}':
+ do_end_object(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ break;
+ case '\"':
+ ++input_ptr_;
+ ++column_;
+ push_state(parse_state::member_name);
+ state_ = parse_state::string_u1;
+ break;
+ case '\'':
+ if (err_handler_.error(json_parser_errc::single_quote, *this))
+ {
+ ec = json_parser_errc::single_quote;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ default:
+ if (err_handler_.error(json_parser_errc::expected_name, *this))
+ {
+ ec = json_parser_errc::expected_name;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ }
+ }
+ break;
+ case parse_state::expect_member_name:
+ {
+ switch (*input_ptr_)
+ {
+ JSONCONS_ILLEGAL_CONTROL_CHARACTER:
+ if (err_handler_.error(json_parser_errc::illegal_control_character, *this))
+ {
+ ec = json_parser_errc::illegal_control_character;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ case '\r':
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::cr;
+ break;
+ case '\n':
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::lf;
+ break;
+ case ' ':case '\t':
+ skip_whitespace();
+ break;
+ case '/':
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::slash;
+ break;
+ case '\"':
+ ++input_ptr_;
+ ++column_;
+ push_state(parse_state::member_name);
+ state_ = parse_state::string_u1;
+ break;
+ case '}':
+ if (err_handler_.error(json_parser_errc::extra_comma, *this))
+ {
+ ec = json_parser_errc::extra_comma;
+ return;
+ }
+ do_end_object(ec); // Recover
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ break;
+ case '\'':
+ if (err_handler_.error(json_parser_errc::single_quote, *this))
+ {
+ ec = json_parser_errc::single_quote;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ default:
+ if (err_handler_.error(json_parser_errc::expected_name, *this))
+ {
+ ec = json_parser_errc::expected_name;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ }
+ }
+ break;
+ case parse_state::expect_colon:
+ {
+ switch (*input_ptr_)
+ {
+ JSONCONS_ILLEGAL_CONTROL_CHARACTER:
+ if (err_handler_.error(json_parser_errc::illegal_control_character, *this))
+ {
+ ec = json_parser_errc::illegal_control_character;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ case '\r':
+ push_state(state_);
+ state_ = parse_state::cr;
+ ++input_ptr_;
+ ++column_;
+ break;
+ case '\n':
+ push_state(state_);
+ state_ = parse_state::lf;
+ ++input_ptr_;
+ ++column_;
+ break;
+ case ' ':case '\t':
+ skip_whitespace();
+ break;
+ case '/':
+ push_state(state_);
+ state_ = parse_state::slash;
+ ++input_ptr_;
+ ++column_;
+ break;
+ case ':':
+ state_ = parse_state::expect_value;
+ ++input_ptr_;
+ ++column_;
+ break;
+ default:
+ if (err_handler_.error(json_parser_errc::expected_colon, *this))
+ {
+ ec = json_parser_errc::expected_colon;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ }
+ }
+ break;
+
+ case parse_state::expect_value:
+ {
+ switch (*input_ptr_)
+ {
+ JSONCONS_ILLEGAL_CONTROL_CHARACTER:
+ if (err_handler_.error(json_parser_errc::illegal_control_character, *this))
+ {
+ ec = json_parser_errc::illegal_control_character;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ case '\r':
+ push_state(state_);
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::cr;
+ break;
+ case '\n':
+ push_state(state_);
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::lf;
+ break;
+ case ' ':case '\t':
+ skip_whitespace();
+ break;
+ case '/':
+ push_state(state_);
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::slash;
+ break;
+ case '{':
+ do_begin_object(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ break;
+ case '[':
+ do_begin_array(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ break;
+ case '\"':
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::string_u1;
+ break;
+ case '-':
+ number_buffer_.clear();
+ is_negative_ = true;
+ precision_ = 0;
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::minus;
+ parse_number(ec);
+ if (ec) {return;}
+ break;
+ case '0':
+ number_buffer_.clear();
+ is_negative_ = false;
+ precision_ = 1;
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::zero;
+ parse_number(ec);
+ if (ec) {return;}
+ break;
+ case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
+ number_buffer_.clear();
+ is_negative_ = false;
+ precision_ = 1;
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::integer;
+ parse_number(ec);
+ if (ec) {return;}
+ break;
+ case 'n':
+ parse_null(ec);
+ if (ec) {return;}
+ break;
+ case 't':
+ parse_true(ec);
+ if (ec) {return;}
+ break;
+ case 'f':
+ parse_false(ec);
+ if (ec) {return;}
+ break;
+ case ']':
+ if (parent() == parse_state::array)
+ {
+ if (err_handler_.error(json_parser_errc::extra_comma, *this))
+ {
+ ec = json_parser_errc::extra_comma;
+ return;
+ }
+ do_end_array(ec); // Recover
+ if (ec) return;
+ }
+ else
+ {
+ if (err_handler_.error(json_parser_errc::expected_value, *this))
+ {
+ ec = json_parser_errc::expected_value;
+ return;
+ }
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ case '\'':
+ if (err_handler_.error(json_parser_errc::single_quote, *this))
+ {
+ ec = json_parser_errc::single_quote;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ default:
+ if (err_handler_.error(json_parser_errc::expected_value, *this))
+ {
+ ec = json_parser_errc::expected_value;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ }
+ }
+ break;
+ case parse_state::expect_value_or_end:
+ {
+ switch (*input_ptr_)
+ {
+ JSONCONS_ILLEGAL_CONTROL_CHARACTER:
+ if (err_handler_.error(json_parser_errc::illegal_control_character, *this))
+ {
+ ec = json_parser_errc::illegal_control_character;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ case '\r':
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::cr;
+ break;
+ case '\n':
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::lf;
+ break;
+ case ' ':case '\t':
+ skip_whitespace();
+ break;
+ case '/':
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::slash;
+ break;
+ case '{':
+ do_begin_object(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ break;
+ case '[':
+ do_begin_array(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ break;
+ case ']':
+ do_end_array(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ break;
+ case '\"':
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::string_u1;
+ break;
+ case '-':
+ number_buffer_.clear();
+ is_negative_ = true;
+ precision_ = 0;
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::minus;
+ parse_number(ec);
+ if (ec) {return;}
+ break;
+ case '0':
+ number_buffer_.clear();
+ is_negative_ = false;
+ precision_ = 1;
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::zero;
+ parse_number(ec);
+ if (ec) {return;}
+ break;
+ case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
+ number_buffer_.clear();
+ is_negative_ = false;
+ precision_ = 1;
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::integer;
+ parse_number(ec);
+ if (ec) {return;}
+ break;
+ case 'n':
+ parse_null(ec);
+ if (ec) {return;}
+ break;
+ case 't':
+ parse_true(ec);
+ if (ec) {return;}
+ break;
+ case 'f':
+ parse_false(ec);
+ if (ec) {return;}
+ break;
+ case '\'':
+ if (err_handler_.error(json_parser_errc::single_quote, *this))
+ {
+ ec = json_parser_errc::single_quote;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ default:
+ if (err_handler_.error(json_parser_errc::expected_value, *this))
+ {
+ ec = json_parser_errc::expected_value;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ }
+ }
+ break;
+ case parse_state::string_u1:
+ case parse_state::escape:
+ case parse_state::escape_u1:
+ case parse_state::escape_u2:
+ case parse_state::escape_u3:
+ case parse_state::escape_u4:
+ case parse_state::escape_expect_surrogate_pair1:
+ case parse_state::escape_expect_surrogate_pair2:
+ case parse_state::escape_u6:
+ case parse_state::escape_u7:
+ case parse_state::escape_u8:
+ case parse_state::escape_u9:
+ parse_string(ec);
+ if (ec) return;
+ break;
+ case parse_state::minus:
+ case parse_state::zero:
+ case parse_state::integer:
+ case parse_state::fraction1:
+ case parse_state::fraction2:
+ case parse_state::exp1:
+ case parse_state::exp2:
+ case parse_state::exp3:
+ parse_number(ec);
+ if (ec) return;
+ break;
+ case parse_state::t:
+ switch (*input_ptr_)
+ {
+ case 'r':
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::tr;
+ break;
+ default:
+ err_handler_.error(json_parser_errc::invalid_value, *this);
+ ec = json_parser_errc::invalid_value;
+ return;
+ }
+ break;
+ case parse_state::tr:
+ switch (*input_ptr_)
+ {
+ case 'u':
+ state_ = parse_state::tru;
+ break;
+ default:
+ err_handler_.error(json_parser_errc::invalid_value, *this);
+ ec = json_parser_errc::invalid_value;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ case parse_state::tru:
+ switch (*input_ptr_)
+ {
+ case 'e':
+ handler_.bool_value(true,*this);
+ if (parent() == parse_state::root)
+ {
+ state_ = parse_state::done;
+ handler_.end_json();
+ }
+ else
+ {
+ state_ = parse_state::expect_comma_or_end;
+ }
+ break;
+ default:
+ err_handler_.error(json_parser_errc::invalid_value, *this);
+ ec = json_parser_errc::invalid_value;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ case parse_state::f:
+ switch (*input_ptr_)
+ {
+ case 'a':
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::fa;
+ break;
+ default:
+ err_handler_.error(json_parser_errc::invalid_value, *this);
+ ec = json_parser_errc::invalid_value;
+ return;
+ }
+ break;
+ case parse_state::fa:
+ switch (*input_ptr_)
+ {
+ case 'l':
+ state_ = parse_state::fal;
+ break;
+ default:
+ err_handler_.error(json_parser_errc::invalid_value, *this);
+ ec = json_parser_errc::invalid_value;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ case parse_state::fal:
+ switch (*input_ptr_)
+ {
+ case 's':
+ state_ = parse_state::fals;
+ break;
+ default:
+ err_handler_.error(json_parser_errc::invalid_value, *this);
+ ec = json_parser_errc::invalid_value;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ case parse_state::fals:
+ switch (*input_ptr_)
+ {
+ case 'e':
+ handler_.bool_value(false,*this);
+ if (parent() == parse_state::root)
+ {
+ state_ = parse_state::done;
+ handler_.end_json();
+ }
+ else
+ {
+ state_ = parse_state::expect_comma_or_end;
+ }
+ break;
+ default:
+ err_handler_.error(json_parser_errc::invalid_value, *this);
+ ec = json_parser_errc::invalid_value;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ case parse_state::n:
+ switch (*input_ptr_)
+ {
+ case 'u':
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::nu;
+ break;
+ default:
+ err_handler_.error(json_parser_errc::invalid_value, *this);
+ ec = json_parser_errc::invalid_value;
+ return;
+ }
+ break;
+ case parse_state::nu:
+ switch (*input_ptr_)
+ {
+ case 'l':
+ state_ = parse_state::nul;
+ break;
+ default:
+ err_handler_.error(json_parser_errc::invalid_value, *this);
+ ec = json_parser_errc::invalid_value;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ case parse_state::nul:
+ switch (*input_ptr_)
+ {
+ case 'l':
+ handler_.null_value(*this);
+ if (parent() == parse_state::root)
+ {
+ state_ = parse_state::done;
+ handler_.end_json();
+ }
+ else
+ {
+ state_ = parse_state::expect_comma_or_end;
+ }
+ break;
+ default:
+ err_handler_.error(json_parser_errc::invalid_value, *this);
+ ec = json_parser_errc::invalid_value;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ case parse_state::slash:
+ {
+ switch (*input_ptr_)
+ {
+ case '*':
+ state_ = parse_state::slash_star;
+ if (err_handler_.error(json_parser_errc::illegal_comment, *this))
+ {
+ ec = json_parser_errc::illegal_comment;
+ return;
+ }
+ break;
+ case '/':
+ state_ = parse_state::slash_slash;
+ if (err_handler_.error(json_parser_errc::illegal_comment, *this))
+ {
+ ec = json_parser_errc::illegal_comment;
+ return;
+ }
+ break;
+ default:
+ if (err_handler_.error(json_parser_errc::invalid_json_text, *this))
+ {
+ ec = json_parser_errc::invalid_json_text;
+ return;
+ }
+ break;
+ }
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ case parse_state::slash_star:
+ {
+ switch (*input_ptr_)
+ {
+ case '\r':
+ push_state(state_);
+ state_ = parse_state::cr;
+ break;
+ case '\n':
+ push_state(state_);
+ state_ = parse_state::lf;
+ break;
+ case '*':
+ state_ = parse_state::slash_star_star;
+ break;
+ }
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ case parse_state::slash_slash:
+ {
+ switch (*input_ptr_)
+ {
+ case '\r':
+ state_ = pop_state();
+ break;
+ case '\n':
+ state_ = pop_state();
+ break;
+ default:
+ ++input_ptr_;
+ ++column_;
+ }
+ }
+ break;
+ case parse_state::slash_star_star:
+ {
+ switch (*input_ptr_)
+ {
+ case '/':
+ state_ = pop_state();
+ break;
+ default:
+ state_ = parse_state::slash_star;
+ break;
+ }
+ }
+ ++input_ptr_;
+ ++column_;
+ break;
+ default:
+ JSONCONS_ASSERT(false);
+ break;
+ }
+ }
+ }
+
+ void parse_true(std::error_code& ec)
+ {
+ if (JSONCONS_LIKELY(input_end_ - input_ptr_ >= 4))
+ {
+ if (*(input_ptr_+1) == 'r' && *(input_ptr_+2) == 'u' && *(input_ptr_+3) == 'e')
+ {
+ handler_.bool_value(true,*this);
+ input_ptr_ += 4;
+ column_ += 4;
+ if (parent() == parse_state::root)
+ {
+ handler_.end_json();
+ state_ = parse_state::done;
+ }
+ else
+ {
+ state_ = parse_state::expect_comma_or_end;
+ }
+ }
+ else
+ {
+ err_handler_.error(json_parser_errc::invalid_value, *this);
+ ec = json_parser_errc::invalid_value;
+ return;
+ }
+ }
+ else
+ {
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::t;
+ }
+ }
+
+ void parse_null(std::error_code& ec)
+ {
+ if (JSONCONS_LIKELY(input_end_ - input_ptr_ >= 4))
+ {
+ if (*(input_ptr_+1) == 'u' && *(input_ptr_+2) == 'l' && *(input_ptr_+3) == 'l')
+ {
+ handler_.null_value(*this);
+ input_ptr_ += 4;
+ column_ += 4;
+ if (parent() == parse_state::root)
+ {
+ handler_.end_json();
+ state_ = parse_state::done;
+ }
+ else
+ {
+ state_ = parse_state::expect_comma_or_end;
+ }
+ }
+ else
+ {
+ err_handler_.error(json_parser_errc::invalid_value, *this);
+ ec = json_parser_errc::invalid_value;
+ return;
+ }
+ }
+ else
+ {
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::n;
+ }
+ }
+
+ void parse_false(std::error_code& ec)
+ {
+ if (JSONCONS_LIKELY(input_end_ - input_ptr_ >= 5))
+ {
+ if (*(input_ptr_+1) == 'a' && *(input_ptr_+2) == 'l' && *(input_ptr_+3) == 's' && *(input_ptr_+4) == 'e')
+ {
+ handler_.bool_value(false,*this);
+ input_ptr_ += 5;
+ column_ += 5;
+ if (parent() == parse_state::root)
+ {
+ handler_.end_json();
+ state_ = parse_state::done;
+ }
+ else
+ {
+ state_ = parse_state::expect_comma_or_end;
+ }
+ }
+ else
+ {
+ err_handler_.error(json_parser_errc::invalid_value, *this);
+ ec = json_parser_errc::invalid_value;
+ return;
+ }
+ }
+ else
+ {
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::f;
+ }
+ }
+
+ void parse_number(std::error_code& ec)
+ {
+ const CharT* local_input_end = input_end_;
+
+ switch (state_)
+ {
+ case parse_state::minus:
+ goto minus_sign;
+ case parse_state::zero:
+ goto zero;
+ case parse_state::integer:
+ goto integer;
+ case parse_state::fraction1:
+ goto fraction1;
+ case parse_state::fraction2:
+ goto fraction2;
+ case parse_state::exp1:
+ goto exp1;
+ case parse_state::exp2:
+ goto exp2;
+ case parse_state::exp3:
+ goto exp3;
+ default:
+ JSONCONS_UNREACHABLE();
+ }
+minus_sign:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::minus;
+ return;
+ }
+ switch (*input_ptr_)
+ {
+ case '0':
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ ++precision_;
+ ++input_ptr_;
+ ++column_;
+ goto zero;
+ case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ ++precision_;
+ ++input_ptr_;
+ ++column_;
+ goto integer;
+ default:
+ err_handler_.error(json_parser_errc::expected_value, *this);
+ ec = json_parser_errc::expected_value;
+ return;
+ }
+zero:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::zero;
+ return;
+ }
+ switch (*input_ptr_)
+ {
+ case '\r':
+ end_integer_value(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::cr;
+ return;
+ case '\n':
+ end_integer_value(ec);
+ if (ec) return;
+ push_state(state_);
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::lf;
+ return;
+ case ' ':case '\t':
+ end_integer_value(ec);
+ if (ec) return;
+ skip_whitespace();
+ return;
+ case '/':
+ end_integer_value(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::slash;
+ return;
+ case '}':
+ end_integer_value(ec);
+ if (ec) return;
+ do_end_object(ec);
+ ++input_ptr_;
+ ++column_;
+ if (ec) return;
+ return;
+ case ']':
+ end_integer_value(ec);
+ if (ec) return;
+ do_end_array(ec);
+ ++input_ptr_;
+ ++column_;
+ if (ec) return;
+ return;
+ case '.':
+ decimal_places_ = 0;
+ JSONCONS_ASSERT(precision_ == number_buffer_.length());
+ number_buffer_.push_back(to_double_.get_decimal_point());
+ ++input_ptr_;
+ ++column_;
+ goto fraction1;
+ case 'e':case 'E':
+ JSONCONS_ASSERT(precision_ == number_buffer_.length());
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ ++input_ptr_;
+ ++column_;
+ goto exp1;
+ case ',':
+ end_integer_value(ec);
+ if (ec) return;
+ begin_member_or_element(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ return;
+ case '0': case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
+ err_handler_.error(json_parser_errc::leading_zero, *this);
+ ec = json_parser_errc::leading_zero;
+ state_ = parse_state::zero;
+ return;
+ default:
+ err_handler_.error(json_parser_errc::invalid_number, *this);
+ ec = json_parser_errc::invalid_number;
+ state_ = parse_state::zero;
+ return;
+ }
+integer:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::integer;
+ return;
+ }
+ switch (*input_ptr_)
+ {
+ case '\r':
+ end_integer_value(ec);
+ if (ec) return;
+ push_state(state_);
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::cr;
+ return;
+ case '\n':
+ end_integer_value(ec);
+ if (ec) return;
+ push_state(state_);
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::lf;
+ return;
+ case ' ':case '\t':
+ end_integer_value(ec);
+ if (ec) return;
+ skip_whitespace();
+ return;
+ case '/':
+ end_integer_value(ec);
+ if (ec) return;
+ push_state(state_);
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::slash;
+ return;
+ case '}':
+ end_integer_value(ec);
+ if (ec) return;
+ do_end_object(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ return;
+ case ']':
+ end_integer_value(ec);
+ if (ec) return;
+ do_end_array(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ return;
+ case '0': case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ ++precision_;
+ ++input_ptr_;
+ ++column_;
+ goto integer;
+ case '.':
+ decimal_places_ = 0;
+ JSONCONS_ASSERT(precision_ == number_buffer_.length());
+ number_buffer_.push_back(to_double_.get_decimal_point());
+ ++input_ptr_;
+ ++column_;
+ goto fraction1;
+ case 'e':case 'E':
+ JSONCONS_ASSERT(precision_ == number_buffer_.length());
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ ++input_ptr_;
+ ++column_;
+ goto exp1;
+ case ',':
+ end_integer_value(ec);
+ if (ec) return;
+ begin_member_or_element(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ return;
+ default:
+ err_handler_.error(json_parser_errc::invalid_number, *this);
+ ec = json_parser_errc::invalid_number;
+ state_ = parse_state::integer;
+ return;
+ }
+fraction1:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::fraction1;
+ return;
+ }
+ switch (*input_ptr_)
+ {
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
+ ++precision_;
+ ++decimal_places_;
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ ++input_ptr_;
+ ++column_;
+ goto fraction2;
+ default:
+ err_handler_.error(json_parser_errc::invalid_number, *this);
+ ec = json_parser_errc::invalid_number;
+ state_ = parse_state::fraction1;
+ return;
+ }
+fraction2:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::fraction2;
+ return;
+ }
+ switch (*input_ptr_)
+ {
+ case '\r':
+ end_fraction_value(chars_format::fixed,ec);
+ if (ec) return;
+ push_state(state_);
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::cr;
+ return;
+ case '\n':
+ end_fraction_value(chars_format::fixed,ec);
+ if (ec) return;
+ push_state(state_);
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::lf;
+ return;
+ case ' ':case '\t':
+ end_fraction_value(chars_format::fixed,ec);
+ if (ec) return;
+ skip_whitespace();
+ return;
+ case '/':
+ end_fraction_value(chars_format::fixed,ec);
+ if (ec) return;
+ push_state(state_);
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::slash;
+ return;
+ case '}':
+ end_fraction_value(chars_format::fixed,ec);
+ if (ec) return;
+ do_end_object(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ return;
+ case ']':
+ end_fraction_value(chars_format::fixed,ec);
+ if (ec) return;
+ do_end_array(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ return;
+ case ',':
+ end_fraction_value(chars_format::fixed,ec);
+ if (ec) return;
+ begin_member_or_element(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ return;
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
+ ++precision_;
+ ++decimal_places_;
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ ++input_ptr_;
+ ++column_;
+ goto fraction2;
+ case 'e':case 'E':
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ ++input_ptr_;
+ ++column_;
+ goto exp1;
+ default:
+ err_handler_.error(json_parser_errc::invalid_number, *this);
+ ec = json_parser_errc::invalid_number;
+ state_ = parse_state::fraction2;
+ return;
+ }
+exp1:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::exp1;
+ return;
+ }
+ switch (*input_ptr_)
+ {
+ case '+':
+ ++input_ptr_;
+ ++column_;
+ goto exp2;
+ case '-':
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ ++input_ptr_;
+ ++column_;
+ goto exp2;
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ ++input_ptr_;
+ ++column_;
+ goto exp3;
+ default:
+ err_handler_.error(json_parser_errc::expected_value, *this);
+ ec = json_parser_errc::expected_value;
+ state_ = parse_state::exp1;
+ return;
+ }
+exp2:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::exp2;
+ return;
+ }
+ switch (*input_ptr_)
+ {
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ ++input_ptr_;
+ ++column_;
+ goto exp3;
+ default:
+ err_handler_.error(json_parser_errc::expected_value, *this);
+ ec = json_parser_errc::expected_value;
+ state_ = parse_state::exp2;
+ return;
+ }
+
+exp3:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::exp3;
+ return;
+ }
+ switch (*input_ptr_)
+ {
+ case '\r':
+ end_fraction_value(chars_format::scientific,ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::cr;
+ return;
+ case '\n':
+ end_fraction_value(chars_format::scientific,ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ push_state(state_);
+ state_ = parse_state::lf;
+ return;
+ case ' ':case '\t':
+ end_fraction_value(chars_format::scientific,ec);
+ if (ec) return;
+ skip_whitespace();
+ return;
+ case '/':
+ end_fraction_value(chars_format::scientific,ec);
+ if (ec) return;
+ push_state(state_);
+ ++input_ptr_;
+ ++column_;
+ state_ = parse_state::slash;
+ return;
+ case '}':
+ end_fraction_value(chars_format::scientific,ec);
+ if (ec) return;
+ do_end_object(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ return;
+ case ']':
+ end_fraction_value(chars_format::scientific,ec);
+ if (ec) return;
+ do_end_array(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ return;
+ case ',':
+ end_fraction_value(chars_format::scientific,ec);
+ if (ec) return;
+ begin_member_or_element(ec);
+ if (ec) return;
+ ++input_ptr_;
+ ++column_;
+ return;
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
+ number_buffer_.push_back(static_cast<char>(*input_ptr_));
+ ++input_ptr_;
+ ++column_;
+ goto exp3;
+ default:
+ err_handler_.error(json_parser_errc::invalid_number, *this);
+ ec = json_parser_errc::invalid_number;
+ state_ = parse_state::exp3;
+ return;
+ }
+
+ JSONCONS_UNREACHABLE();
+ }
+
+ void parse_string(std::error_code& ec)
+ {
+ const CharT* local_input_end = input_end_;
+ const CharT* sb = input_ptr_;
+
+ switch (state_)
+ {
+ case parse_state::string_u1:
+ goto string_u1;
+ case parse_state::escape:
+ goto escape;
+ case parse_state::escape_u1:
+ goto escape_u1;
+ case parse_state::escape_u2:
+ goto escape_u2;
+ case parse_state::escape_u3:
+ goto escape_u3;
+ case parse_state::escape_u4:
+ goto escape_u4;
+ case parse_state::escape_expect_surrogate_pair1:
+ goto escape_expect_surrogate_pair1;
+ case parse_state::escape_expect_surrogate_pair2:
+ goto escape_expect_surrogate_pair2;
+ case parse_state::escape_u6:
+ goto escape_u6;
+ case parse_state::escape_u7:
+ goto escape_u7;
+ case parse_state::escape_u8:
+ goto escape_u8;
+ case parse_state::escape_u9:
+ goto escape_u9;
+ default:
+ JSONCONS_UNREACHABLE();
+ }
+
+string_u1:
+ while (input_ptr_ < local_input_end)
+ {
+ switch (*input_ptr_)
+ {
+ JSONCONS_ILLEGAL_CONTROL_CHARACTER:
+ {
+ column_ += (input_ptr_ - sb + 1);
+ if (err_handler_.error(json_parser_errc::illegal_control_character, *this))
+ {
+ ec = json_parser_errc::illegal_control_character;
+ state_ = parse_state::string_u1;
+ return;
+ }
+ // recovery - skip
+ auto result = unicons::validate(sb,input_ptr_);
+ if (result.ec != unicons::conv_errc())
+ {
+ translate_conv_errc(result.ec,ec);
+ column_ += (result.it - sb);
+ return;
+ }
+ string_buffer_.append(sb,input_ptr_-sb);
+ ++input_ptr_;
+ state_ = parse_state::string_u1;
+ return;
+ }
+ case '\r':
+ {
+ column_ += (input_ptr_ - sb + 1);
+ if (err_handler_.error(json_parser_errc::illegal_character_in_string, *this))
+ {
+ ec = json_parser_errc::illegal_character_in_string;
+ state_ = parse_state::string_u1;
+ return;
+ }
+ // recovery - keep
+ auto result = unicons::validate(sb,input_ptr_);
+ if (result.ec != unicons::conv_errc())
+ {
+ translate_conv_errc(result.ec,ec);
+ column_ += (result.it - sb);
+ return;
+ }
+ string_buffer_.append(sb, input_ptr_ - sb + 1);
+ ++input_ptr_;
+ push_state(state_);
+ state_ = parse_state::cr;
+ return;
+ }
+ case '\n':
+ {
+ column_ += (input_ptr_ - sb + 1);
+ if (err_handler_.error(json_parser_errc::illegal_character_in_string, *this))
+ {
+ ec = json_parser_errc::illegal_character_in_string;
+ state_ = parse_state::string_u1;
+ return;
+ }
+ // recovery - keep
+ auto result = unicons::validate(sb,input_ptr_);
+ if (result.ec != unicons::conv_errc())
+ {
+ translate_conv_errc(result.ec,ec);
+ column_ += (result.it - sb);
+ return;
+ }
+ string_buffer_.append(sb, input_ptr_ - sb + 1);
+ ++input_ptr_;
+ push_state(state_);
+ state_ = parse_state::lf;
+ return;
+ }
+ case '\t':
+ {
+ column_ += (input_ptr_ - sb + 1);
+ if (err_handler_.error(json_parser_errc::illegal_character_in_string, *this))
+ {
+ ec = json_parser_errc::illegal_character_in_string;
+ state_ = parse_state::string_u1;
+ return;
+ }
+ // recovery - keep
+ auto result = unicons::validate(sb,input_ptr_);
+ if (result.ec != unicons::conv_errc())
+ {
+ translate_conv_errc(result.ec,ec);
+ column_ += (result.it - sb);
+ return;
+ }
+ string_buffer_.append(sb, input_ptr_ - sb + 1);
+ ++input_ptr_;
+ state_ = parse_state::string_u1;
+ return;
+ }
+ case '\\':
+ {
+ auto result = unicons::validate(sb,input_ptr_);
+ if (result.ec != unicons::conv_errc())
+ {
+ translate_conv_errc(result.ec,ec);
+ column_ += (result.it - sb);
+ return;
+ }
+ string_buffer_.append(sb,input_ptr_-sb);
+ column_ += (input_ptr_ - sb + 1);
+ ++input_ptr_;
+ goto escape;
+ }
+ case '\"':
+ {
+ auto result = unicons::validate(sb,input_ptr_);
+ if (result.ec != unicons::conv_errc())
+ {
+ translate_conv_errc(result.ec,ec);
+ column_ += (result.it - sb);
+ return;
+ }
+ if (string_buffer_.length() == 0)
+ {
+ end_string_value(sb,input_ptr_-sb, ec);
+ if (ec) {return;}
+ }
+ else
+ {
+ string_buffer_.append(sb,input_ptr_-sb);
+ end_string_value(string_buffer_.data(),string_buffer_.length(), ec);
+ string_buffer_.clear();
+ if (ec) {return;}
+ }
+ column_ += (input_ptr_ - sb + 1);
+ ++input_ptr_;
+ return;
+ }
+ default:
+ break;
+ }
+ ++input_ptr_;
+ }
+
+ // Buffer exhausted
+ {
+ auto result = unicons::validate(sb,input_ptr_);
+ if (result.ec != unicons::conv_errc())
+ {
+ translate_conv_errc(result.ec,ec);
+ column_ += (result.it - sb);
+ return;
+ }
+ string_buffer_.append(sb,input_ptr_-sb);
+ column_ += (input_ptr_ - sb + 1);
+ state_ = parse_state::string_u1;
+ return;
+ }
+
+escape:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::escape;
+ return;
+ }
+ switch (*input_ptr_)
+ {
+ case '\"':
+ string_buffer_.push_back('\"');
+ sb = ++input_ptr_;
+ ++column_;
+ goto string_u1;
+ case '\\':
+ string_buffer_.push_back('\\');
+ sb = ++input_ptr_;
+ ++column_;
+ goto string_u1;
+ case '/':
+ string_buffer_.push_back('/');
+ sb = ++input_ptr_;
+ ++column_;
+ goto string_u1;
+ case 'b':
+ string_buffer_.push_back('\b');
+ sb = ++input_ptr_;
+ ++column_;
+ goto string_u1;
+ case 'f':
+ string_buffer_.push_back('\f');
+ sb = ++input_ptr_;
+ ++column_;
+ goto string_u1;
+ case 'n':
+ string_buffer_.push_back('\n');
+ sb = ++input_ptr_;
+ ++column_;
+ goto string_u1;
+ case 'r':
+ string_buffer_.push_back('\r');
+ sb = ++input_ptr_;
+ ++column_;
+ goto string_u1;
+ case 't':
+ string_buffer_.push_back('\t');
+ sb = ++input_ptr_;
+ ++column_;
+ goto string_u1;
+ case 'u':
+ cp_ = 0;
+ ++input_ptr_;
+ ++column_;
+ goto escape_u1;
+ default:
+ err_handler_.error(json_parser_errc::illegal_escaped_character, *this);
+ ec = json_parser_errc::illegal_escaped_character;
+ state_ = parse_state::escape;
+ return;
+ }
+
+escape_u1:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::escape_u1;
+ return;
+ }
+ {
+ append_codepoint(*input_ptr_,ec);
+ if (ec)
+ {
+ state_ = parse_state::escape_u1;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ goto escape_u2;
+ }
+
+escape_u2:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::escape_u2;
+ return;
+ }
+ {
+ append_codepoint(*input_ptr_, ec);
+ if (ec)
+ {
+ state_ = parse_state::escape_u2;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ goto escape_u3;
+ }
+
+escape_u3:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::escape_u3;
+ return;
+ }
+ {
+ append_codepoint(*input_ptr_, ec);
+ if (ec)
+ {
+ state_ = parse_state::escape_u3;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ goto escape_u4;
+ }
+
+escape_u4:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::escape_u4;
+ return;
+ }
+ {
+ append_codepoint(*input_ptr_, ec);
+ if (ec)
+ {
+ state_ = parse_state::escape_u4;
+ return;
+ }
+ if (unicons::is_high_surrogate(cp_))
+ {
+ ++input_ptr_;
+ ++column_;
+ goto escape_expect_surrogate_pair1;
+ }
+ else
+ {
+ unicons::convert(&cp_, &cp_ + 1, std::back_inserter(string_buffer_));
+ sb = ++input_ptr_;
+ ++column_;
+ state_ = parse_state::string_u1;
+ return;
+ }
+ }
+
+escape_expect_surrogate_pair1:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::escape_expect_surrogate_pair1;
+ return;
+ }
+ {
+ switch (*input_ptr_)
+ {
+ case '\\':
+ cp2_ = 0;
+ ++input_ptr_;
+ ++column_;
+ goto escape_expect_surrogate_pair2;
+ default:
+ err_handler_.error(json_parser_errc::expected_codepoint_surrogate_pair, *this);
+ ec = json_parser_errc::expected_codepoint_surrogate_pair;
+ state_ = parse_state::escape_expect_surrogate_pair1;
+ return;
+ }
+ }
+
+escape_expect_surrogate_pair2:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::escape_expect_surrogate_pair2;
+ return;
+ }
+ {
+ switch (*input_ptr_)
+ {
+ case 'u':
+ ++input_ptr_;
+ ++column_;
+ goto escape_u6;
+ default:
+ err_handler_.error(json_parser_errc::expected_codepoint_surrogate_pair, *this);
+ ec = json_parser_errc::expected_codepoint_surrogate_pair;
+ state_ = parse_state::escape_expect_surrogate_pair2;
+ return;
+ }
+ }
+
+escape_u6:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::escape_u6;
+ return;
+ }
+ {
+ append_second_codepoint(*input_ptr_, ec);
+ if (ec)
+ {
+ state_ = parse_state::escape_u6;
+ return;
+ }
+ }
+ ++input_ptr_;
+ ++column_;
+ goto escape_u7;
+
+escape_u7:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::escape_u7;
+ return;
+ }
+ {
+ append_second_codepoint(*input_ptr_, ec);
+ if (ec)
+ {
+ state_ = parse_state::escape_u7;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ goto escape_u8;
+ }
+
+escape_u8:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::escape_u8;
+ return;
+ }
+ {
+ append_second_codepoint(*input_ptr_, ec);
+ if (ec)
+ {
+ state_ = parse_state::escape_u8;
+ return;
+ }
+ ++input_ptr_;
+ ++column_;
+ goto escape_u9;
+ }
+
+escape_u9:
+ if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted
+ {
+ state_ = parse_state::escape_u9;
+ return;
+ }
+ {
+ append_second_codepoint(*input_ptr_, ec);
+ if (ec)
+ {
+ state_ = parse_state::escape_u9;
+ return;
+ }
+ uint32_t cp = 0x10000 + ((cp_ & 0x3FF) << 10) + (cp2_ & 0x3FF);
+ unicons::convert(&cp, &cp + 1, std::back_inserter(string_buffer_));
+ sb = ++input_ptr_;
+ ++column_;
+ goto string_u1;
+ }
+
+ JSONCONS_UNREACHABLE();
+ }
+
+ void translate_conv_errc(unicons::conv_errc result, std::error_code& ec)
+ {
+ switch (result)
+ {
+ case unicons::conv_errc():
+ break;
+ case unicons::conv_errc::over_long_utf8_sequence:
+ if (err_handler_.error(json_parser_errc::over_long_utf8_sequence, *this))
+ {
+ ec = json_parser_errc::over_long_utf8_sequence;
+ return;
+ }
+ break;
+ case unicons::conv_errc::unpaired_high_surrogate:
+ if (err_handler_.error(json_parser_errc::unpaired_high_surrogate, *this))
+ {
+ ec = json_parser_errc::unpaired_high_surrogate;
+ return;
+ }
+ break;
+ case unicons::conv_errc::expected_continuation_byte:
+ if (err_handler_.error(json_parser_errc::expected_continuation_byte, *this))
+ {
+ ec = json_parser_errc::expected_continuation_byte;
+ return;
+ }
+ break;
+ case unicons::conv_errc::illegal_surrogate_value:
+ if (err_handler_.error(json_parser_errc::illegal_surrogate_value, *this))
+ {
+ ec = json_parser_errc::illegal_surrogate_value;
+ return;
+ }
+ break;
+ default:
+ if (err_handler_.error(json_parser_errc::illegal_codepoint, *this))
+ {
+ ec = json_parser_errc::illegal_codepoint;
+ return;
+ }
+ break;
+ }
+ }
+
+ void parse_some()
+ {
+ std::error_code ec;
+ parse_some(ec);
+ if (ec)
+ {
+ throw parse_error(ec,line_,column_);
+ }
+ }
+
+ void end_parse()
+ {
+ std::error_code ec;
+ end_parse(ec);
+ if (ec)
+ {
+ throw parse_error(ec,line_,column_);
+ }
+ }
+
+ void end_parse(std::error_code& ec)
+ {
+ if (parent() == parse_state::root)
+ {
+ switch (state_)
+ {
+ case parse_state::zero:
+ case parse_state::integer:
+ end_integer_value(ec);
+ if (ec) return;
+ break;
+ case parse_state::fraction2:
+ end_fraction_value(chars_format::fixed,ec);
+ if (ec) return;
+ break;
+ case parse_state::exp3:
+ end_fraction_value(chars_format::scientific,ec);
+ if (ec) return;
+ break;
+ default:
+ break;
+ }
+ }
+ if (state_ == parse_state::lf || state_ == parse_state::cr)
+ {
+ state_ = pop_state();
+ }
+ if (!(state_ == parse_state::done || state_ == parse_state::start))
+ {
+ if (err_handler_.error(json_parser_errc::unexpected_eof, *this))
+ {
+ ec = json_parser_errc::unexpected_eof;
+ return;
+ }
+ }
+ }
+
+ parse_state state() const
+ {
+ return state_;
+ }
+
+ void set_source(const CharT* input, size_t length)
+ {
+ begin_input_ = input;
+ input_end_ = input + length;
+ input_ptr_ = begin_input_;
+ }
+private:
+
+ void end_integer_value(std::error_code& ec)
+ {
+ if (is_negative_)
+ {
+ end_negative_value(ec);
+ }
+ else
+ {
+ end_positive_value(ec);
+ }
+ }
+
+ void end_negative_value(std::error_code& ec)
+ {
+ static const int64_t min_value = (std::numeric_limits<int64_t>::min)();
+ static const int64_t min_value_div_10 = min_value / 10;
+
+ const char* s = number_buffer_.data();
+ size_t length = number_buffer_.length();
+ int64_t n = 0;
+ bool overflow = false;
+ const char* end = s + length;
+ for (; s < end; ++s)
+ {
+ int64_t x = *s - '0';
+ if (n < min_value_div_10)
+ {
+ overflow = true;
+ break;
+ }
+ n = n * 10;
+ if (n < min_value + x)
+ {
+ overflow = true;
+ break;
+ }
+
+ n -= x;
+ }
+
+ if (!overflow)
+ {
+ handler_.integer_value(n, *this);
+
+ switch (parent())
+ {
+ case parse_state::array:
+ case parse_state::object:
+ state_ = parse_state::expect_comma_or_end;
+ break;
+ case parse_state::root:
+ state_ = parse_state::done;
+ handler_.end_json();
+ break;
+ default:
+ if (err_handler_.error(json_parser_errc::invalid_json_text, *this))
+ {
+ ec = json_parser_errc::invalid_json_text;
+ return;
+ }
+ break;
+ }
+ }
+ else
+ {
+ end_fraction_value(chars_format::general,ec);
+ }
+ }
+
+ void end_positive_value(std::error_code& ec)
+ {
+ static const uint64_t max_value = (std::numeric_limits<uint64_t>::max)();
+ static const uint64_t max_value_div_10 = max_value / 10;
+ uint64_t n = 0;
+ bool overflow = false;
+ const char* s = number_buffer_.data();
+ size_t length = number_buffer_.length();
+
+ const char* end = s + length;
+ for (; s < end; ++s)
+ {
+ uint64_t x = *s - '0';
+ if (n > max_value_div_10)
+ {
+ overflow = true;
+ break;
+ }
+ n = n * 10;
+ if (n > max_value - x)
+ {
+ overflow = true;
+ break;
+ }
+
+ n += x;
+ }
+
+ if (!overflow)
+ {
+ handler_.uinteger_value(n, *this);
+
+ switch (parent())
+ {
+ case parse_state::array:
+ case parse_state::object:
+ state_ = parse_state::expect_comma_or_end;
+ break;
+ case parse_state::root:
+ state_ = parse_state::done;
+ handler_.end_json();
+ break;
+ default:
+ if (err_handler_.error(json_parser_errc::invalid_json_text, *this))
+ {
+ ec = json_parser_errc::invalid_json_text;
+ return;
+ }
+ break;
+ }
+ }
+ else
+ {
+ end_fraction_value(chars_format::general,ec);
+ }
+ }
+
+ void end_fraction_value(chars_format format, std::error_code& ec)
+ {
+ try
+ {
+ double d = to_double_(number_buffer_.c_str(), number_buffer_.length());
+ if (is_negative_)
+ d = -d;
+
+ if (precision_ > std::numeric_limits<double>::max_digits10)
+ {
+ handler_.double_value(d, number_format(format,std::numeric_limits<double>::max_digits10, decimal_places_), *this);
+ }
+ else
+ {
+ handler_.double_value(d, number_format(format,static_cast<uint8_t>(precision_), decimal_places_), *this);
+ }
+ }
+ catch (...)
+ {
+ if (err_handler_.error(json_parser_errc::invalid_number, *this))
+ {
+ ec = json_parser_errc::invalid_number;
+ return;
+ }
+ handler_.null_value(*this); // recovery
+ }
+
+ switch (parent())
+ {
+ case parse_state::array:
+ case parse_state::object:
+ state_ = parse_state::expect_comma_or_end;
+ break;
+ case parse_state::root:
+ state_ = parse_state::done;
+ handler_.end_json();
+ break;
+ default:
+ if (err_handler_.error(json_parser_errc::invalid_json_text, *this))
+ {
+ ec = json_parser_errc::invalid_json_text;
+ return;
+ }
+ break;
+ }
+ }
+
+ void append_codepoint(int c, std::error_code& ec)
+ {
+ switch (c)
+ {
+ case '0': case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
+ case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':
+ case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
+ cp_ = append_to_codepoint(cp_, c, ec);
+ if (ec) return;
+ break;
+ default:
+ if (err_handler_.error(json_parser_errc::expected_value, *this))
+ {
+ ec = json_parser_errc::expected_value;
+ return;
+ }
+ break;
+ }
+ }
+
+ void append_second_codepoint(int c, std::error_code& ec)
+ {
+ switch (c)
+ {
+ case '0':
+ case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
+ case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':
+ case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
+ cp2_ = append_to_codepoint(cp2_, c, ec);
+ if (ec) return;
+ break;
+ default:
+ if (err_handler_.error(json_parser_errc::expected_value, *this))
+ {
+ ec = json_parser_errc::expected_value;
+ return;
+ }
+ break;
+ }
+ }
+
+ void end_string_value(const CharT* s, size_t length, std::error_code& ec)
+ {
+ switch (parent())
+ {
+ case parse_state::member_name:
+ handler_.name(string_view_type(s, length), *this);
+ state_ = pop_state();
+ state_ = parse_state::expect_colon;
+ break;
+ case parse_state::object:
+ case parse_state::array:
+ handler_.string_value(string_view_type(s, length), *this);
+ state_ = parse_state::expect_comma_or_end;
+ break;
+ case parse_state::root:
+ handler_.string_value(string_view_type(s, length), *this);
+ state_ = parse_state::done;
+ handler_.end_json();
+ break;
+ default:
+ if (err_handler_.error(json_parser_errc::invalid_json_text, *this))
+ {
+ ec = json_parser_errc::invalid_json_text;
+ return;
+ }
+ break;
+ }
+ }
+
+ void begin_member_or_element(std::error_code& ec)
+ {
+ switch (parent())
+ {
+ case parse_state::object:
+ state_ = parse_state::expect_member_name;
+ break;
+ case parse_state::array:
+ state_ = parse_state::expect_value;
+ break;
+ case parse_state::root:
+ break;
+ default:
+ if (err_handler_.error(json_parser_errc::invalid_json_text, *this))
+ {
+ ec = json_parser_errc::invalid_json_text;
+ return;
+ }
+ break;
+ }
+ }
+
+ void push_state(parse_state state)
+ {
+ state_stack_.push_back(state);
+ }
+
+ parse_state pop_state()
+ {
+ JSONCONS_ASSERT(!state_stack_.empty())
+ parse_state state = state_stack_.back();
+ state_stack_.pop_back();
+ return state;
+ }
+
+ uint32_t append_to_codepoint(uint32_t cp, int c, std::error_code& ec)
+ {
+ cp *= 16;
+ if (c >= '0' && c <= '9')
+ {
+ cp += c - '0';
+ }
+ else if (c >= 'a' && c <= 'f')
+ {
+ cp += c - 'a' + 10;
+ }
+ else if (c >= 'A' && c <= 'F')
+ {
+ cp += c - 'A' + 10;
+ }
+ else
+ {
+ if (err_handler_.error(json_parser_errc::invalid_hex_escape_sequence, *this))
+ {
+ ec = json_parser_errc::invalid_hex_escape_sequence;
+ return cp;
+ }
+ }
+ return cp;
+ }
+
+ size_t do_line_number() const override
+ {
+ return line_;
+ }
+
+ size_t do_column_number() const override
+ {
+ return column_;
+ }
+};
+
+typedef basic_json_parser<char> json_parser;
+typedef basic_json_parser<wchar_t> wjson_parser;
+
+}
+
+#endif
+
diff --git a/vendor/jsoncons-0.104.0/jsoncons/json_reader.hpp b/vendor/jsoncons-0.104.0/jsoncons/json_reader.hpp
new file mode 100644
index 00000000..d419e2d8
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/json_reader.hpp
@@ -0,0 +1,408 @@
+// Copyright 2015 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSON_READER_HPP
+#define JSONCONS_JSON_READER_HPP
+
+#include <memory>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <cstdlib>
+#include <stdexcept>
+#include <system_error>
+#include <ios>
+#include <jsoncons/json_exception.hpp>
+#include <jsoncons/json_input_handler.hpp>
+#include <jsoncons/parse_error_handler.hpp>
+#include <jsoncons/json_parser.hpp>
+
+namespace jsoncons {
+
+// utf8_other_json_input_adapter
+
+template <class CharT>
+class json_utf8_other_input_handler_adapter : public json_input_handler
+{
+public:
+ using json_input_handler::string_view_type;
+private:
+ basic_null_json_input_handler<CharT> default_input_handler_;
+ basic_json_input_handler<CharT>& other_handler_;
+ //parse_error_handler& err_handler_;
+
+ // noncopyable and nonmoveable
+ json_utf8_other_input_handler_adapter<CharT>(const json_utf8_other_input_handler_adapter<CharT>&) = delete;
+ json_utf8_other_input_handler_adapter<CharT>& operator=(const json_utf8_other_input_handler_adapter<CharT>&) = delete;
+
+public:
+ json_utf8_other_input_handler_adapter()
+ : other_handler_(default_input_handler_)
+ {
+ }
+
+ json_utf8_other_input_handler_adapter(basic_json_input_handler<CharT>& other_handler/*,
+ parse_error_handler& err_handler*/)
+ : other_handler_(other_handler)/*,
+ err_handler_(err_handler)*/
+ {
+ }
+
+private:
+
+ void do_begin_json() override
+ {
+ other_handler_.begin_json();
+ }
+
+ void do_end_json() override
+ {
+ other_handler_.end_json();
+ }
+
+ void do_begin_object(const parsing_context& context) override
+ {
+ other_handler_.begin_object(context);
+ }
+
+ void do_end_object(const parsing_context& context) override
+ {
+ other_handler_.end_object(context);
+ }
+
+ void do_begin_array(const parsing_context& context) override
+ {
+ other_handler_.begin_array(context);
+ }
+
+ void do_end_array(const parsing_context& context) override
+ {
+ other_handler_.end_array(context);
+ }
+
+ void do_name(const string_view_type& name, const parsing_context& context) override
+ {
+ std::basic_string<CharT> target;
+ auto result = unicons::convert(
+ name.begin(), name.end(), std::back_inserter(target),
+ unicons::conv_flags::strict);
+ if (result.ec != unicons::conv_errc())
+ {
+ throw parse_error(result.ec,context.line_number(),context.column_number());
+ }
+ other_handler_.name(target, context);
+ }
+
+ void do_string_value(const string_view_type& value, const parsing_context& context) override
+ {
+ std::basic_string<CharT> target;
+ auto result = unicons::convert(
+ value.begin(), value.end(), std::back_inserter(target),
+ unicons::conv_flags::strict);
+ if (result.ec != unicons::conv_errc())
+ {
+ throw parse_error(result.ec,context.line_number(),context.column_number());
+ }
+ other_handler_.string_value(target, context);
+ }
+
+ void do_integer_value(int64_t value, const parsing_context& context) override
+ {
+ other_handler_.integer_value(value, context);
+ }
+
+ void do_uinteger_value(uint64_t value, const parsing_context& context) override
+ {
+ other_handler_.uinteger_value(value, context);
+ }
+
+ void do_double_value(double value, const number_format& fmt, const parsing_context& context) override
+ {
+ other_handler_.double_value(value, fmt, context);
+ }
+
+ void do_bool_value(bool value, const parsing_context& context) override
+ {
+ other_handler_.bool_value(value, context);
+ }
+
+ void do_null_value(const parsing_context& context) override
+ {
+ other_handler_.null_value(context);
+ }
+};
+
+template<class CharT,class Allocator=std::allocator<char>>
+class basic_json_reader
+{
+ static const size_t default_max_buffer_length = 16384;
+
+ typedef CharT char_type;
+ typedef Allocator allocator_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<CharT> char_allocator_type;
+
+ basic_json_parser<CharT,Allocator> parser_;
+ std::basic_istream<CharT>& is_;
+ bool eof_;
+ std::vector<CharT,char_allocator_type> buffer_;
+ size_t buffer_length_;
+ bool begin_;
+
+ // Noncopyable and nonmoveable
+ basic_json_reader(const basic_json_reader&) = delete;
+ basic_json_reader& operator=(const basic_json_reader&) = delete;
+
+public:
+
+ basic_json_reader(std::basic_istream<CharT>& is)
+ : parser_(),
+ is_(is),
+ eof_(false),
+ buffer_length_(default_max_buffer_length),
+ begin_(true)
+ {
+ buffer_.reserve(buffer_length_);
+ }
+
+ basic_json_reader(std::basic_istream<CharT>& is,
+ parse_error_handler& err_handler)
+ : parser_(err_handler),
+ is_(is),
+ eof_(false),
+ buffer_length_(default_max_buffer_length),
+ begin_(true)
+ {
+ buffer_.reserve(buffer_length_);
+ }
+
+ basic_json_reader(std::basic_istream<CharT>& is,
+ basic_json_input_handler<CharT>& handler)
+ : parser_(handler),
+ is_(is),
+ eof_(false),
+ buffer_length_(default_max_buffer_length),
+ begin_(true)
+ {
+ buffer_.reserve(buffer_length_);
+ }
+
+ basic_json_reader(std::basic_istream<CharT>& is,
+ basic_json_input_handler<CharT>& handler,
+ parse_error_handler& err_handler)
+ : parser_(handler,err_handler),
+ is_(is),
+ eof_(false),
+ buffer_length_(default_max_buffer_length),
+ begin_(true)
+ {
+ buffer_.reserve(buffer_length_);
+ }
+
+ size_t buffer_length() const
+ {
+ return buffer_length_;
+ }
+
+ void buffer_length(size_t length)
+ {
+ buffer_length_ = length;
+ buffer_.reserve(buffer_length_);
+ }
+
+ size_t max_nesting_depth() const
+ {
+ return parser_.max_nesting_depth();
+ }
+
+ void max_nesting_depth(size_t depth)
+ {
+ parser_.max_nesting_depth(depth);
+ }
+
+ void read_next()
+ {
+ std::error_code ec;
+ read_next(ec);
+ if (ec)
+ {
+ throw parse_error(ec,parser_.line_number(),parser_.column_number());
+ }
+ }
+
+ void read_buffer(std::error_code& ec)
+ {
+ buffer_.clear();
+ buffer_.resize(buffer_length_);
+ is_.read(buffer_.data(), buffer_length_);
+ buffer_.resize(static_cast<size_t>(is_.gcount()));
+ if (buffer_.size() == 0)
+ {
+ eof_ = true;
+ }
+ else if (begin_)
+ {
+ auto result = unicons::skip_bom(buffer_.begin(), buffer_.end());
+ if (result.ec != unicons::encoding_errc())
+ {
+ ec = result.ec;
+ return;
+ }
+ size_t offset = result.it - buffer_.begin();
+ parser_.set_source(buffer_.data()+offset,buffer_.size()-offset);
+ begin_ = false;
+ }
+ else
+ {
+ parser_.set_source(buffer_.data(),buffer_.size());
+ }
+ }
+
+ void read_next(std::error_code& ec)
+ {
+ parser_.reset();
+ while (!eof_ && !parser_.done())
+ {
+ if (parser_.source_exhausted())
+ {
+ if (!is_.eof())
+ {
+ if (is_.fail())
+ {
+ ec = json_parser_errc::source_error;
+ return;
+ }
+ read_buffer(ec);
+ if (ec) return;
+ }
+ else
+ {
+ eof_ = true;
+ }
+ }
+ if (!eof_)
+ {
+ parser_.parse_some(ec);
+ if (ec) return;
+ }
+ }
+ if (eof_)
+ {
+ parser_.end_parse(ec);
+ if (ec) return;
+ }
+ }
+
+ void check_done()
+ {
+ std::error_code ec;
+ check_done(ec);
+ if (ec)
+ {
+ throw parse_error(ec,parser_.line_number(),parser_.column_number());
+ }
+ }
+
+ size_t line_number() const
+ {
+ return parser_.line_number();
+ }
+
+ size_t column_number() const
+ {
+ return parser_.column_number();
+ }
+
+ void check_done(std::error_code& ec)
+ {
+ if (eof_)
+ {
+ parser_.check_done(ec);
+ if (ec) return;
+ }
+ else
+ {
+ while (!eof_)
+ {
+ if (parser_.source_exhausted())
+ {
+ if (!is_.eof())
+ {
+ if (is_.fail())
+ {
+ ec = json_parser_errc::source_error;
+ return;
+ }
+ read_buffer(ec);
+ if (ec) return;
+ }
+ else
+ {
+ eof_ = true;
+ }
+ }
+ if (!eof_)
+ {
+ parser_.check_done(ec);
+ if (ec) return;
+ }
+ }
+ }
+ }
+
+ bool eof() const
+ {
+ return eof_;
+ }
+
+ void read()
+ {
+ read_next();
+ check_done();
+ }
+
+ void read(std::error_code& ec)
+ {
+ read_next(ec);
+ if (!ec)
+ {
+ check_done(ec);
+ }
+ }
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+
+ size_t buffer_capacity() const
+ {
+ return buffer_length_;
+ }
+
+ void buffer_capacity(size_t length)
+ {
+ buffer_length_ = length;
+ buffer_.reserve(buffer_length_);
+ }
+ size_t max_depth() const
+ {
+ return parser_.max_nesting_depth();
+ }
+
+ void max_depth(size_t depth)
+ {
+ parser_.max_nesting_depth(depth);
+ }
+#endif
+
+private:
+};
+
+typedef basic_json_reader<char> json_reader;
+typedef basic_json_reader<wchar_t> wjson_reader;
+
+}
+
+#endif
+
diff --git a/vendor/jsoncons-0.104.0/jsoncons/json_serializer.hpp b/vendor/jsoncons-0.104.0/jsoncons/json_serializer.hpp
new file mode 100644
index 00000000..42538671
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/json_serializer.hpp
@@ -0,0 +1,585 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSON_SERIALIZER_HPP
+#define JSONCONS_JSON_SERIALIZER_HPP
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <ostream>
+#include <cstdlib>
+#include <limits> // std::numeric_limits
+#include <fstream>
+#include <memory>
+#include <jsoncons/json_exception.hpp>
+#include <jsoncons/jsoncons_utilities.hpp>
+#include <jsoncons/serialization_options.hpp>
+#include <jsoncons/json_output_handler.hpp>
+#include <jsoncons/detail/writer.hpp>
+#include <jsoncons/detail/number_printers.hpp>
+
+namespace jsoncons {
+
+template<class CharT,class Writer=detail::ostream_buffered_writer<CharT>>
+class basic_json_serializer final : public basic_json_output_handler<CharT>
+{
+public:
+ using typename basic_json_output_handler<CharT>::string_view_type;
+ typedef Writer writer_type;
+ typedef typename Writer::output_type output_type;
+
+private:
+ static const size_t default_buffer_length = 16384;
+
+ struct stack_item
+ {
+ stack_item(bool is_object)
+ : is_object_(is_object), count_(0), split_lines_(line_split_kind::same_line), indent_once_(false), unindent_at_end_(false)
+ {
+ }
+ stack_item(bool is_object, line_split_kind split_lines, bool indent_once = false)
+ : is_object_(is_object), count_(0), split_lines_(split_lines), indent_once_(indent_once), unindent_at_end_(false)
+ {
+ }
+
+ size_t count() const
+ {
+ return count_;
+ }
+
+ bool unindent_at_end() const
+ {
+ return unindent_at_end_;
+ }
+
+ bool is_object() const
+ {
+ return is_object_;
+ }
+
+ bool is_new_line() const
+ {
+ return split_lines_ != line_split_kind::same_line;
+ }
+
+ bool is_multi_line() const
+ {
+ return split_lines_ == line_split_kind::multi_line;
+ }
+
+ bool is_indent_once() const
+ {
+ return count_ == 0 ? indent_once_ : false;
+ }
+
+ bool is_object_;
+ size_t count_;
+ line_split_kind split_lines_;
+ bool indent_once_;
+ bool unindent_at_end_;
+ };
+ basic_serialization_options<CharT> options_;
+ std::vector<stack_item> stack_;
+ int indent_;
+ bool indenting_;
+ detail::print_double fp_;
+ Writer writer_;
+
+ // Noncopyable and nonmoveable
+ basic_json_serializer(const basic_json_serializer&) = delete;
+ basic_json_serializer& operator=(const basic_json_serializer&) = delete;
+public:
+ basic_json_serializer(output_type& os)
+ : indent_(0),
+ indenting_(false),
+ fp_(options_.precision()),
+ writer_(os)
+ {
+ }
+
+ basic_json_serializer(output_type& os, bool pprint)
+ : indent_(0),
+ indenting_(pprint),
+ fp_(options_.precision()),
+ writer_(os)
+ {
+ }
+
+ basic_json_serializer(output_type& os, const basic_serialization_options<CharT>& options)
+ : options_(options),
+ indent_(0),
+ indenting_(false),
+ fp_(options_.precision()),
+ writer_(os)
+ {
+ }
+ basic_json_serializer(output_type& os, const basic_serialization_options<CharT>& options, bool pprint)
+ : options_(options),
+ indent_(0),
+ indenting_(pprint),
+ fp_(options_.precision()),
+ writer_(os)
+ {
+ }
+
+ ~basic_json_serializer()
+ {
+ }
+
+private:
+ void escape_string(const CharT* s,
+ size_t length,
+ const basic_serialization_options<CharT>& options,
+ writer_type& writer)
+ {
+ const CharT* begin = s;
+ const CharT* end = s + length;
+ for (const CharT* it = begin; it != end; ++it)
+ {
+ CharT c = *it;
+ switch (c)
+ {
+ case '\\':
+ writer.put('\\');
+ writer.put('\\');
+ break;
+ case '"':
+ writer.put('\\');
+ writer.put('\"');
+ break;
+ case '\b':
+ writer.put('\\');
+ writer.put('b');
+ break;
+ case '\f':
+ writer.put('\\');
+ writer.put('f');
+ break;
+ case '\n':
+ writer.put('\\');
+ writer.put('n');
+ break;
+ case '\r':
+ writer.put('\\');
+ writer.put('r');
+ break;
+ case '\t':
+ writer.put('\\');
+ writer.put('t');
+ break;
+ default:
+ if (options.escape_solidus() && c == '/')
+ {
+ writer.put('\\');
+ writer.put('/');
+ }
+ else if (is_control_character(c) || options.escape_all_non_ascii())
+ {
+ // convert utf8 to codepoint
+ unicons::sequence_generator<const CharT*> g(it,end,unicons::conv_flags::strict);
+ if (g.done() || g.status() != unicons::conv_errc())
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Invalid codepoint"));
+ }
+ uint32_t cp = g.get().codepoint();
+ it += (g.get().length() - 1);
+ if (is_non_ascii_codepoint(cp) || is_control_character(c))
+ {
+ if (cp > 0xFFFF)
+ {
+ cp -= 0x10000;
+ uint32_t first = (cp >> 10) + 0xD800;
+ uint32_t second = ((cp & 0x03FF) + 0xDC00);
+
+ writer.put('\\');
+ writer.put('u');
+ writer.put(to_hex_character(first >> 12 & 0x000F));
+ writer.put(to_hex_character(first >> 8 & 0x000F));
+ writer.put(to_hex_character(first >> 4 & 0x000F));
+ writer.put(to_hex_character(first & 0x000F));
+ writer.put('\\');
+ writer.put('u');
+ writer.put(to_hex_character(second >> 12 & 0x000F));
+ writer.put(to_hex_character(second >> 8 & 0x000F));
+ writer.put(to_hex_character(second >> 4 & 0x000F));
+ writer.put(to_hex_character(second & 0x000F));
+ }
+ else
+ {
+ writer.put('\\');
+ writer.put('u');
+ writer.put(to_hex_character(cp >> 12 & 0x000F));
+ writer.put(to_hex_character(cp >> 8 & 0x000F));
+ writer.put(to_hex_character(cp >> 4 & 0x000F));
+ writer.put(to_hex_character(cp & 0x000F));
+ }
+ }
+ else
+ {
+ writer.put(c);
+ }
+ }
+ else
+ {
+ writer.put(c);
+ }
+ break;
+ }
+ }
+ }
+ // Implementing methods
+ void do_begin_json() override
+ {
+ }
+
+ void do_end_json() override
+ {
+ writer_.flush();
+ }
+
+ void do_begin_object() override
+ {
+ if (!stack_.empty() && !stack_.back().is_object())
+ {
+ if (!stack_.empty())
+ {
+ if (stack_.back().count_ > 0)
+ {
+ writer_. put(',');
+ }
+ }
+ }
+
+ if (indenting_)
+ {
+ if (!stack_.empty() && stack_.back().is_object())
+ {
+ stack_.push_back(stack_item(true,options_.object_object_split_lines(), false));
+ }
+ else if (!stack_.empty())
+ {
+ if (options_.array_object_split_lines() != line_split_kind::same_line)
+ {
+ stack_.back().unindent_at_end_ = true;
+ stack_.push_back(stack_item(true,options_.array_object_split_lines(), false));
+ write_indent1();
+ }
+ else
+ {
+ stack_.push_back(stack_item(true,options_.array_object_split_lines(), false));
+ }
+ }
+ else
+ {
+ stack_.push_back(stack_item(true, line_split_kind::multi_line, false));
+ }
+ indent();
+ }
+ else
+ {
+ stack_.push_back(stack_item(true));
+ }
+ writer_.put('{');
+ }
+
+ void do_end_object() override
+ {
+ JSONCONS_ASSERT(!stack_.empty());
+ if (indenting_)
+ {
+ unindent();
+ if (stack_.back().unindent_at_end())
+ {
+ write_indent();
+ }
+ }
+ stack_.pop_back();
+ writer_.put('}');
+
+ end_value();
+ }
+
+
+ void do_begin_array() override
+ {
+ if (!stack_.empty() && !stack_.back().is_object())
+ {
+ if (!stack_.empty())
+ {
+ if (stack_.back().count_ > 0)
+ {
+ writer_. put(',');
+ }
+ }
+ }
+ if (indenting_)
+ {
+ if (!stack_.empty() && stack_.back().is_object())
+ {
+ writer_.put('[');
+ indent();
+ if (options_.object_array_split_lines() != line_split_kind::same_line)
+ {
+ stack_.push_back(stack_item(false,options_.object_array_split_lines(),true));
+ }
+ else
+ {
+ stack_.push_back(stack_item(false,options_.object_array_split_lines(),false));
+ }
+ }
+ else if (!stack_.empty())
+ {
+ if (options_.array_array_split_lines() != line_split_kind::same_line)
+ {
+ write_indent();
+ }
+ stack_.push_back(stack_item(false,options_.array_array_split_lines(), false));
+ indent();
+ writer_.put('[');
+ }
+ else
+ {
+ stack_.push_back(stack_item(false, line_split_kind::multi_line, false));
+ indent();
+ writer_.put('[');
+ }
+ }
+ else
+ {
+ stack_.push_back(stack_item(false));
+ writer_.put('[');
+ }
+ }
+
+ void do_end_array() override
+ {
+ JSONCONS_ASSERT(!stack_.empty());
+ if (indenting_)
+ {
+ unindent();
+ if (stack_.back().unindent_at_end())
+ {
+ write_indent();
+ }
+ }
+ stack_.pop_back();
+ writer_.put(']');
+ end_value();
+ }
+
+ void do_name(const string_view_type& name) override
+ {
+ if (!stack_.empty())
+ {
+ if (stack_.back().count_ > 0)
+ {
+ writer_. put(',');
+ }
+ if (indenting_)
+ {
+ if (stack_.back().is_multi_line())
+ {
+ write_indent();
+ }
+ }
+ }
+
+ writer_.put('\"');
+ escape_string(name.data(), name.length(), options_, writer_);
+ writer_.put('\"');
+ writer_.put(':');
+ if (indenting_)
+ {
+ writer_.put(' ');
+ }
+ }
+
+ void do_null_value() override
+ {
+ if (!stack_.empty() && !stack_.back().is_object())
+ {
+ begin_scalar_value();
+ }
+
+ auto buf = detail::null_literal<CharT>();
+ writer_.write(buf, 4);
+
+ end_value();
+ }
+
+ void do_string_value(const string_view_type& value) override
+ {
+ if (!stack_.empty() && !stack_.back().is_object())
+ {
+ begin_scalar_value();
+ }
+
+ writer_. put('\"');
+ escape_string(value.data(), value.length(), options_, writer_);
+ writer_. put('\"');
+
+ end_value();
+ }
+
+ void do_byte_string_value(const uint8_t* data, size_t length) override
+ {
+ std::basic_string<CharT> s;
+ encode_base64url(data,data+length,s);
+ do_string_value(s);
+ }
+
+ void do_double_value(double value, const number_format& fmt) override
+ {
+ if (!stack_.empty() && !stack_.back().is_object())
+ {
+ begin_scalar_value();
+ }
+
+ if ((std::isnan)(value))
+ {
+ writer_.write(options_.nan_replacement());
+ }
+ else if (value == std::numeric_limits<double>::infinity())
+ {
+ writer_.write(options_.pos_inf_replacement());
+ }
+ else if (!(std::isfinite)(value))
+ {
+ writer_.write(options_.neg_inf_replacement());
+ }
+ else
+ {
+ fp_(value, fmt.precision(), writer_);
+ }
+
+ end_value();
+ }
+
+ void do_integer_value(int64_t value) override
+ {
+ if (!stack_.empty() && !stack_.back().is_object())
+ {
+ begin_scalar_value();
+ }
+ detail::print_integer(value, writer_);
+ end_value();
+ }
+
+ void do_uinteger_value(uint64_t value) override
+ {
+ if (!stack_.empty() && !stack_.back().is_object())
+ {
+ begin_scalar_value();
+ }
+ detail::print_uinteger(value, writer_);
+ end_value();
+ }
+
+ void do_bool_value(bool value) override
+ {
+ if (!stack_.empty() && !stack_.back().is_object())
+ {
+ begin_scalar_value();
+ }
+
+ if (value)
+ {
+ auto buf = detail::true_literal<CharT>();
+ writer_.write(buf,4);
+ }
+ else
+ {
+ auto buf = detail::false_literal<CharT>();
+ writer_.write(buf,5);
+ }
+
+ end_value();
+ }
+
+ void begin_scalar_value()
+ {
+ if (!stack_.empty())
+ {
+ if (stack_.back().count_ > 0)
+ {
+ writer_. put(',');
+ }
+ if (indenting_)
+ {
+ if (stack_.back().is_multi_line() || stack_.back().is_indent_once())
+ {
+ write_indent();
+ }
+ }
+ }
+ }
+
+ void begin_value()
+ {
+ if (!stack_.empty())
+ {
+ if (stack_.back().count_ > 0)
+ {
+ writer_. put(',');
+ }
+ if (indenting_)
+ {
+ if (stack_.back().is_new_line())
+ {
+ write_indent();
+ }
+ }
+ }
+ }
+
+ void end_value()
+ {
+ if (!stack_.empty())
+ {
+ ++stack_.back().count_;
+ }
+ }
+
+ void indent()
+ {
+ indent_ += static_cast<int>(options_.indent());
+ }
+
+ void unindent()
+ {
+ indent_ -= static_cast<int>(options_.indent());
+ }
+
+ void write_indent()
+ {
+ if (!stack_.empty())
+ {
+ stack_.back().unindent_at_end_ = true;
+ }
+ writer_. put('\n');
+ for (int i = 0; i < indent_; ++i)
+ {
+ writer_. put(' ');
+ }
+ }
+
+ void write_indent1()
+ {
+ writer_. put('\n');
+ for (int i = 0; i < indent_; ++i)
+ {
+ writer_. put(' ');
+ }
+ }
+};
+
+typedef basic_json_serializer<char,detail::ostream_buffered_writer<char>> json_serializer;
+typedef basic_json_serializer<wchar_t, detail::ostream_buffered_writer<wchar_t>> wjson_serializer;
+
+}
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/json_structures.hpp b/vendor/jsoncons-0.104.0/jsoncons/json_structures.hpp
new file mode 100644
index 00000000..74aa1507
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/json_structures.hpp
@@ -0,0 +1,1864 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSON_STRUCTURES_HPP
+#define JSONCONS_JSON_STRUCTURES_HPP
+
+#include <string>
+#include <vector>
+#include <deque>
+#include <exception>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include <algorithm>
+#include <sstream>
+#include <iomanip>
+#include <utility>
+#include <initializer_list>
+#include <jsoncons/json_exception.hpp>
+#include <jsoncons/jsoncons_utilities.hpp>
+#include <jsoncons/json_type_traits.hpp>
+
+namespace jsoncons {
+
+// json_array
+
+template <class Json>
+class Json_array_base_
+{
+public:
+ typedef typename Json::allocator_type allocator_type;
+
+public:
+ Json_array_base_()
+ : self_allocator_()
+ {
+ }
+ Json_array_base_(const allocator_type& allocator)
+ : self_allocator_(allocator)
+ {
+ }
+
+ allocator_type get_allocator() const
+ {
+ return self_allocator_;
+ }
+
+ allocator_type self_allocator_;
+};
+
+// json_array
+
+template <class Json>
+class json_array: public Json_array_base_<Json>
+{
+public:
+ typedef typename Json::allocator_type allocator_type;
+ typedef Json value_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<value_type> val_allocator_type;
+
+ typedef typename Json::array_storage_type array_storage_type;
+
+ typedef typename array_storage_type::iterator iterator;
+ typedef typename array_storage_type::const_iterator const_iterator;
+
+ typedef typename std::iterator_traits<iterator>::reference reference;
+ typedef typename std::iterator_traits<const_iterator>::reference const_reference;
+
+ using Json_array_base_<Json>::get_allocator;
+
+ json_array()
+ : Json_array_base_<Json>(),
+ elements_()
+ {
+ }
+
+ explicit json_array(const allocator_type& allocator)
+ : Json_array_base_<Json>(allocator),
+ elements_(val_allocator_type(allocator))
+ {
+ }
+
+ explicit json_array(size_t n,
+ const allocator_type& allocator = allocator_type())
+ : Json_array_base_<Json>(allocator),
+ elements_(n,Json(),val_allocator_type(allocator))
+ {
+ }
+
+ explicit json_array(size_t n,
+ const Json& value,
+ const allocator_type& allocator = allocator_type())
+ : Json_array_base_<Json>(allocator),
+ elements_(n,value,val_allocator_type(allocator))
+ {
+ }
+
+ template <class InputIterator>
+ json_array(InputIterator begin, InputIterator end, const allocator_type& allocator = allocator_type())
+ : Json_array_base_<Json>(allocator),
+ elements_(begin,end,val_allocator_type(allocator))
+ {
+ }
+ json_array(const json_array& val)
+ : Json_array_base_<Json>(val.get_allocator()),
+ elements_(val.elements_)
+ {
+ }
+ json_array(const json_array& val, const allocator_type& allocator)
+ : Json_array_base_<Json>(allocator),
+ elements_(val.elements_,val_allocator_type(allocator))
+ {
+ }
+
+ json_array(json_array&& val) JSONCONS_NOEXCEPT
+ : Json_array_base_<Json>(val.get_allocator()),
+ elements_(std::move(val.elements_))
+ {
+ }
+ json_array(json_array&& val, const allocator_type& allocator)
+ : Json_array_base_<Json>(allocator),
+ elements_(std::move(val.elements_),val_allocator_type(allocator))
+ {
+ }
+
+ json_array(std::initializer_list<Json> init)
+ : Json_array_base_<Json>(),
+ elements_(std::move(init))
+ {
+ }
+
+ json_array(std::initializer_list<Json> init,
+ const allocator_type& allocator)
+ : Json_array_base_<Json>(allocator),
+ elements_(std::move(init),val_allocator_type(allocator))
+ {
+ }
+ ~json_array()
+ {
+ }
+
+ void swap(json_array<Json>& val)
+ {
+ elements_.swap(val.elements_);
+ }
+
+ size_t size() const {return elements_.size();}
+
+ size_t capacity() const {return elements_.capacity();}
+
+ void clear() {elements_.clear();}
+
+ void shrink_to_fit()
+ {
+ for (size_t i = 0; i < elements_.size(); ++i)
+ {
+ elements_[i].shrink_to_fit();
+ }
+ elements_.shrink_to_fit();
+ }
+
+ void reserve(size_t n) {elements_.reserve(n);}
+
+ void resize(size_t n) {elements_.resize(n);}
+
+ void resize(size_t n, const Json& val) {elements_.resize(n,val);}
+
+ void remove_range(size_t from_index, size_t to_index)
+ {
+ JSONCONS_ASSERT(from_index <= to_index);
+ JSONCONS_ASSERT(to_index <= elements_.size());
+ elements_.erase(elements_.begin()+from_index,elements_.begin()+to_index);
+ }
+
+ void erase(const_iterator pos)
+ {
+ elements_.erase(pos);
+ }
+
+ void erase(const_iterator first, const_iterator last)
+ {
+ elements_.erase(first,last);
+ }
+
+ Json& operator[](size_t i) {return elements_[i];}
+
+ const Json& operator[](size_t i) const {return elements_[i];}
+
+ // push_back
+
+ template <class T, class A=allocator_type>
+ typename std::enable_if<is_stateless<A>::value,void>::type
+ push_back(T&& value)
+ {
+ elements_.emplace_back(std::forward<T>(value));
+ }
+
+ template <class T, class A=allocator_type>
+ typename std::enable_if<!is_stateless<A>::value,void>::type
+ push_back(T&& value)
+ {
+ elements_.emplace_back(std::forward<T>(value),get_allocator());
+ }
+
+ template <class T, class A=allocator_type>
+ typename std::enable_if<is_stateless<A>::value,iterator>::type
+ insert(const_iterator pos, T&& value)
+ {
+#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 9
+ // work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54577
+ iterator it = elements_.begin() + (pos - elements_.begin());
+ return elements_.emplace(it, std::forward<T>(value));
+#else
+ return elements_.emplace(pos, std::forward<T>(value));
+#endif
+ }
+ template <class T, class A=allocator_type>
+ typename std::enable_if<!is_stateless<A>::value,iterator>::type
+ insert(const_iterator pos, T&& value)
+ {
+#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 9
+ // work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54577
+ iterator it = elements_.begin() + (pos - elements_.begin());
+ return elements_.emplace(it, std::forward<T>(value), get_allocator());
+#else
+ return elements_.emplace(pos, std::forward<T>(value), get_allocator());
+#endif
+ }
+
+ template <class InputIt>
+ iterator insert(const_iterator pos, InputIt first, InputIt last)
+ {
+#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 9
+ // work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54577
+ iterator it = elements_.begin() + (pos - elements_.begin());
+ return elements_.insert(it, first, last);
+#else
+ return elements_.insert(pos, first, last);
+#endif
+ }
+
+#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 9
+ // work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54577
+ template <class A=allocator_type, class... Args>
+ typename std::enable_if<is_stateless<A>::value,iterator>::type
+ emplace(const_iterator pos, Args&&... args)
+ {
+ iterator it = elements_.begin() + (pos - elements_.begin());
+ return elements_.emplace(it, std::forward<Args>(args)...);
+ }
+#else
+ template <class A=allocator_type, class... Args>
+ typename std::enable_if<is_stateless<A>::value,iterator>::type
+ emplace(const_iterator pos, Args&&... args)
+ {
+ return elements_.emplace(pos, std::forward<Args>(args)...);
+ }
+#endif
+ template <class... Args>
+ Json& emplace_back(Args&&... args)
+ {
+ elements_.emplace_back(std::forward<Args>(args)...);
+ return elements_.back();
+ }
+
+ iterator begin() {return elements_.begin();}
+
+ iterator end() {return elements_.end();}
+
+ const_iterator begin() const {return elements_.begin();}
+
+ const_iterator end() const {return elements_.end();}
+
+ bool operator==(const json_array<Json>& rhs) const
+ {
+ if (size() != rhs.size())
+ {
+ return false;
+ }
+ for (size_t i = 0; i < size(); ++i)
+ {
+ if (elements_[i] != rhs.elements_[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+private:
+ array_storage_type elements_;
+
+ json_array& operator=(const json_array<Json>&) = delete;
+};
+
+// json_object
+
+template <class BidirectionalIt,class BinaryPredicate>
+BidirectionalIt last_wins_unique_sequence(BidirectionalIt first, BidirectionalIt last, BinaryPredicate compare)
+{
+
+ if (first == last)
+ {
+ return last;
+ }
+
+ typedef typename BidirectionalIt::value_type value_type;
+ typedef typename BidirectionalIt::pointer pointer;
+ std::vector<value_type> dups;
+ {
+ std::vector<pointer> v(std::distance(first,last));
+ auto p = v.begin();
+ for (auto it = first; it != last; ++it)
+ {
+ *p++ = &(*it);
+ }
+ std::sort(v.begin(), v.end(), [&](pointer a, pointer b){return compare(*a,*b)<0;});
+ auto it = v.begin();
+ auto end = v.end();
+ for (auto begin = it+1; begin != end; ++it, ++begin)
+ {
+ if (compare(*(*it),*(*begin)) == 0)
+ {
+ dups.push_back(*(*it));
+ }
+ }
+ }
+ if (dups.size() == 0)
+ {
+ return last;
+ }
+
+ auto it = last;
+ for (auto p = first; p != last && p != it; )
+ {
+ bool no_dup = true;
+ if (dups.size() > 0)
+ {
+ for (auto q = dups.begin(); no_dup && q != dups.end();)
+ {
+ if (compare(*p,*q) == 0)
+ {
+ dups.erase(q);
+ no_dup = false;
+ }
+ else
+ {
+ ++q;
+ }
+ }
+ }
+ if (!no_dup)
+ {
+ --it;
+ for (auto r = p; r != it; ++r)
+ {
+ *r = std::move(*(r+1));
+ }
+ }
+ else
+ {
+ ++p;
+ }
+ }
+
+ return it;
+}
+
+template <class KeyT, class ValueT>
+class key_value_pair
+{
+public:
+ typedef KeyT key_storage_type;
+ typedef typename KeyT::value_type char_type;
+ typedef typename KeyT::allocator_type allocator_type;
+ typedef typename ValueT::string_view_type string_view_type;
+
+ key_value_pair()
+ {
+ }
+
+ key_value_pair(const key_storage_type& name, const ValueT& val)
+ : key_(name), value_(val)
+ {
+ }
+
+ template <class T>
+ key_value_pair(key_storage_type&& name, T&& val)
+ : key_(std::forward<key_storage_type>(name)),
+ value_(std::forward<T>(val))
+ {
+ }
+
+ template <class T>
+ key_value_pair(key_storage_type&& name,
+ T&& val,
+ const allocator_type& allocator)
+ : key_(std::forward<key_storage_type>(name)), value_(std::forward<T>(val), allocator)
+ {
+ }
+
+ key_value_pair(const key_value_pair& member)
+ : key_(member.key_), value_(member.value_)
+ {
+ }
+
+ key_value_pair(key_value_pair&& member)
+ : key_(std::move(member.key_)), value_(std::move(member.value_))
+ {
+ }
+
+ string_view_type key() const
+ {
+ return string_view_type(key_.data(),key_.size());
+ }
+
+ ValueT& value()
+ {
+ return value_;
+ }
+
+ const ValueT& value() const
+ {
+ return value_;
+ }
+
+ template <class T>
+ void value(T&& value)
+ {
+ value_ = std::forward<T>(value);
+ }
+
+ void swap(key_value_pair& member)
+ {
+ key_.swap(member.key_);
+ value_.swap(member.value_);
+ }
+
+ key_value_pair& operator=(const key_value_pair& member)
+ {
+ if (this != & member)
+ {
+ key_ = member.key_;
+ value_ = member.value_;
+ }
+ return *this;
+ }
+
+ key_value_pair& operator=(key_value_pair&& member)
+ {
+ if (this != &member)
+ {
+ key_.swap(member.key_);
+ value_.swap(member.value_);
+ }
+ return *this;
+ }
+
+ void shrink_to_fit()
+ {
+ key_.shrink_to_fit();
+ value_.shrink_to_fit();
+ }
+#if !defined(JSONCONS_NO_DEPRECATED)
+ const key_storage_type& name() const
+ {
+ return key_;
+ }
+#endif
+private:
+ key_storage_type key_;
+ ValueT value_;
+};
+
+template <class KeyT,class Json>
+class Json_object_
+{
+public:
+ typedef typename Json::allocator_type allocator_type;
+ typedef typename Json::char_type char_type;
+ typedef typename Json::char_allocator_type char_allocator_type;
+ typedef KeyT key_storage_type;
+ typedef typename Json::string_view_type string_view_type;
+ typedef key_value_pair<KeyT,Json> value_type;
+
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<value_type> kvp_allocator_type;
+ typedef typename Json::object_storage_type object_storage_type;
+
+ typedef typename object_storage_type::iterator iterator;
+ typedef typename object_storage_type::const_iterator const_iterator;
+
+protected:
+ allocator_type self_allocator_;
+ object_storage_type members_;
+public:
+ Json_object_()
+ : self_allocator_(), members_()
+ {
+ }
+ Json_object_(const allocator_type& allocator)
+ : self_allocator_(allocator),
+ members_(kvp_allocator_type(allocator))
+ {
+ }
+
+ Json_object_(const Json_object_& val)
+ : self_allocator_(val.get_allocator()), members_(val.members_)
+ {
+ }
+
+ Json_object_(Json_object_&& val)
+ : self_allocator_(val.get_allocator()),
+ members_(std::move(val.members_))
+ {
+ }
+
+ Json_object_(const Json_object_& val, const allocator_type& allocator) :
+ self_allocator_(allocator),
+ members_(val.members_,kvp_allocator_type(allocator))
+ {
+ }
+
+ Json_object_(Json_object_&& val,const allocator_type& allocator) :
+ self_allocator_(allocator), members_(std::move(val.members_),kvp_allocator_type(allocator))
+ {
+ }
+
+ void swap(Json_object_& val)
+ {
+ members_.swap(val.members_);
+ }
+
+ allocator_type get_allocator() const
+ {
+ return this->self_allocator_;
+ }
+};
+
+// json_object
+
+template <class KeyT,class Json,bool PreserveOrder>
+class json_object
+{
+};
+
+// Do not preserve order
+template <class KeyT,class Json>
+class json_object<KeyT,Json,false> final : public Json_object_<KeyT,Json>
+{
+public:
+ using typename Json_object_<KeyT,Json>::allocator_type;
+ using typename Json_object_<KeyT,Json>::char_type;
+ using typename Json_object_<KeyT,Json>::char_allocator_type;
+ using typename Json_object_<KeyT,Json>::key_storage_type;
+ using typename Json_object_<KeyT,Json>::string_view_type;
+ using typename Json_object_<KeyT,Json>::value_type;
+ using typename Json_object_<KeyT,Json>::kvp_allocator_type;
+ using typename Json_object_<KeyT,Json>::object_storage_type;
+ using typename Json_object_<KeyT,Json>::iterator;
+ using typename Json_object_<KeyT,Json>::const_iterator;
+ using Json_object_<KeyT,Json>::get_allocator;
+
+ json_object()
+ : Json_object_<KeyT,Json>()
+ {
+ }
+ json_object(const allocator_type& allocator)
+ : Json_object_<KeyT,Json>(allocator)
+ {
+ }
+
+ json_object(const json_object& val)
+ : Json_object_<KeyT,Json>(val)
+ {
+ }
+
+ json_object(json_object&& val)
+ : Json_object_<KeyT,Json>(std::forward<json_object>(val))
+ {
+ }
+
+ json_object(const json_object& val, const allocator_type& allocator)
+ : Json_object_<KeyT,Json>(val,allocator)
+ {
+ }
+
+ json_object(json_object&& val,const allocator_type& allocator)
+ : Json_object_<KeyT,Json>(std::forward<json_object>(val),allocator)
+ {
+ }
+
+ json_object(std::initializer_list<std::pair<string_view_type,Json>> init)
+ : Json_object_<KeyT,Json>()
+ {
+ this->members_.reserve(init.size());
+ for (auto& item : init)
+ {
+ insert_or_assign(item.first, std::move(item.second));
+ }
+ }
+
+ json_object(std::initializer_list<std::pair<string_view_type,Json>> init,
+ const allocator_type& allocator)
+ : Json_object_<KeyT,Json>(allocator)
+ {
+ this->members_.reserve(init.size());
+ for (auto& item : init)
+ {
+ insert_or_assign(item.first, std::move(item.second), allocator);
+ }
+ }
+
+ void swap(json_object& val)
+ {
+ Json_object_<KeyT,Json>::swap(val);
+ }
+
+ iterator begin()
+ {
+ return this->members_.begin();
+ }
+
+ iterator end()
+ {
+ return this->members_.end();
+ }
+
+ const_iterator begin() const
+ {
+ return this->members_.begin();
+ }
+
+ const_iterator end() const
+ {
+ return this->members_.end();
+ }
+
+ size_t size() const {return this->members_.size();}
+
+ size_t capacity() const {return this->members_.capacity();}
+
+ void clear() {this->members_.clear();}
+
+ void shrink_to_fit()
+ {
+ for (size_t i = 0; i < this->members_.size(); ++i)
+ {
+ this->members_[i].shrink_to_fit();
+ }
+ this->members_.shrink_to_fit();
+ }
+
+ void reserve(size_t n) {this->members_.reserve(n);}
+
+ Json& at(size_t i)
+ {
+ if (i >= this->members_.size())
+ {
+ JSONCONS_THROW(json_exception_impl<std::out_of_range>("Invalid array subscript"));
+ }
+ return this->members_[i].value();
+ }
+
+ const Json& at(size_t i) const
+ {
+ if (i >= this->members_.size())
+ {
+ JSONCONS_THROW(json_exception_impl<std::out_of_range>("Invalid array subscript"));
+ }
+ return this->members_[i].value();
+ }
+
+ iterator find(const string_view_type& name)
+ {
+ auto it = std::lower_bound(this->members_.begin(),this->members_.end(), name,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ auto result = (it != this->members_.end() && it->key() == name) ? it : this->members_.end();
+ return result;
+ }
+
+ const_iterator find(const string_view_type& name) const
+ {
+ auto it = std::lower_bound(this->members_.begin(),this->members_.end(),
+ name,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ auto result = (it != this->members_.end() && it->key() == name) ? it : this->members_.end();
+ return result;
+ }
+
+ void erase(const_iterator pos)
+ {
+ this->members_.erase(pos);
+ }
+
+ void erase(const_iterator first, const_iterator last)
+ {
+ this->members_.erase(first,last);
+ }
+
+ void erase(const string_view_type& name)
+ {
+ auto it = std::lower_bound(this->members_.begin(),this->members_.end(), name,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ if (it != this->members_.end() && it->key() == name)
+ {
+ this->members_.erase(it);
+ }
+ }
+
+ template<class InputIt, class UnaryPredicate>
+ void insert(InputIt first, InputIt last, UnaryPredicate pred)
+ {
+ size_t count = std::distance(first,last);
+ this->members_.reserve(this->members_.size() + count);
+ for (auto s = first; s != last; ++s)
+ {
+ this->members_.emplace_back(pred(*s));
+ }
+ std::stable_sort(this->members_.begin(),this->members_.end(),
+ [](const value_type& a, const value_type& b){return a.key().compare(b.key()) < 0;});
+ auto it = std::unique(this->members_.rbegin(), this->members_.rend(),
+ [](const value_type& a, const value_type& b){ return !(a.key().compare(b.key()));});
+ this->members_.erase(this->members_.begin(),it.base());
+ }
+
+ // merge
+
+ void merge(const json_object& source)
+ {
+ for (auto it = source.begin(); it != source.end(); ++it)
+ {
+ try_emplace(it->key(),it->value());
+ }
+ }
+
+ void merge(json_object&& source)
+ {
+ auto it = std::make_move_iterator(source.begin());
+ auto end = std::make_move_iterator(source.end());
+ for (; it != end; ++it)
+ {
+ auto pos = std::lower_bound(this->members_.begin(),this->members_.end(), it->key(),
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ if (pos == this->members_.end() )
+ {
+ this->members_.emplace_back(*it);
+ }
+ else if (it->key() != pos->key())
+ {
+ this->members_.emplace(pos,*it);
+ }
+ }
+ }
+
+ void merge(iterator hint, const json_object& source)
+ {
+ for (auto it = source.begin(); it != source.end(); ++it)
+ {
+ hint = try_emplace(hint, it->key(),it->value());
+ }
+ }
+
+ void merge(iterator hint, json_object&& source)
+ {
+ auto it = std::make_move_iterator(source.begin());
+ auto end = std::make_move_iterator(source.end());
+ for (; it != end; ++it)
+ {
+ iterator pos;
+ if (hint != this->members_.end() && hint->key() <= it->key())
+ {
+ pos = std::lower_bound(hint,this->members_.end(), it->key(),
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ }
+ else
+ {
+ pos = std::lower_bound(this->members_.begin(),this->members_.end(), it->key(),
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ }
+ if (pos == this->members_.end() )
+ {
+ this->members_.emplace_back(*it);
+ hint = this->members_.begin() + (this->members_.size() - 1);
+ }
+ else if (it->key() != pos->key())
+ {
+ hint = this->members_.emplace(pos,*it);
+ }
+ }
+ }
+
+ // merge_or_update
+
+ void merge_or_update(const json_object& source)
+ {
+ for (auto it = source.begin(); it != source.end(); ++it)
+ {
+ insert_or_assign(it->key(),it->value());
+ }
+ }
+
+ void merge_or_update(json_object&& source)
+ {
+ auto it = std::make_move_iterator(source.begin());
+ auto end = std::make_move_iterator(source.end());
+ for (; it != end; ++it)
+ {
+ auto pos = std::lower_bound(this->members_.begin(),this->members_.end(), it->key(),
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ if (pos == this->members_.end() )
+ {
+ this->members_.emplace_back(*it);
+ }
+ else
+ {
+ pos->value(it->value());
+ }
+ }
+ }
+
+ void merge_or_update(iterator hint, const json_object& source)
+ {
+ for (auto it = source.begin(); it != source.end(); ++it)
+ {
+ hint = insert_or_assign(hint, it->key(),it->value());
+ }
+ }
+
+ void merge_or_update(iterator hint, json_object&& source)
+ {
+ auto it = std::make_move_iterator(source.begin());
+ auto end = std::make_move_iterator(source.end());
+ for (; it != end; ++it)
+ {
+ iterator pos;
+ if (hint != this->members_.end() && hint->key() <= it->key())
+ {
+ pos = std::lower_bound(hint,this->members_.end(), it->key(),
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ }
+ else
+ {
+ pos = std::lower_bound(this->members_.begin(),this->members_.end(), it->key(),
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ }
+ if (pos == this->members_.end() )
+ {
+ this->members_.emplace_back(*it);
+ hint = this->members_.begin() + (this->members_.size() - 1);
+ }
+ else
+ {
+ pos->value(it->value());
+ hint = pos;
+ }
+ }
+ }
+
+ // insert_or_assign
+
+ template <class T, class A=allocator_type>
+ typename std::enable_if<is_stateless<A>::value,std::pair<iterator,bool>>::type
+ insert_or_assign(const string_view_type& name, T&& value)
+ {
+ bool inserted;
+ auto it = std::lower_bound(this->members_.begin(),this->members_.end(), name,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(key_storage_type(name.begin(),name.end()),
+ std::forward<T>(value));
+ inserted = true;
+ it = this->members_.begin() + this->members_.size() - 1;
+ }
+ else if (it->key() == name)
+ {
+ it->value(Json(std::forward<T>(value)));
+ inserted = false; // assigned
+ }
+ else
+ {
+ it = this->members_.emplace(it,
+ key_storage_type(name.begin(),name.end()),
+ std::forward<T>(value));
+ inserted = true;
+ }
+ return std::make_pair(it,inserted);
+ }
+
+ template <class T, class A=allocator_type>
+ typename std::enable_if<!is_stateless<A>::value,std::pair<iterator,bool>>::type
+ insert_or_assign(const string_view_type& name, T&& value)
+ {
+ bool inserted;
+ auto it = std::lower_bound(this->members_.begin(),this->members_.end(), name,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(key_storage_type(name.begin(),name.end(), get_allocator()),
+ std::forward<T>(value),get_allocator());
+ inserted = true;
+ it = this->members_.begin() + this->members_.size() - 1;
+ }
+ else if (it->key() == name)
+ {
+ it->value(Json(std::forward<T>(value), get_allocator()));
+ inserted = false; // assigned
+ }
+ else
+ {
+ it = this->members_.emplace(it,
+ key_storage_type(name.begin(),name.end(), get_allocator()),
+ std::forward<T>(value),get_allocator());
+ inserted = true;
+ }
+ return std::make_pair(it,inserted);
+ }
+
+ // try_emplace
+
+ template <class A=allocator_type, class... Args>
+ typename std::enable_if<is_stateless<A>::value,std::pair<iterator,bool>>::type
+ try_emplace(const string_view_type& name, Args&&... args)
+ {
+ bool inserted;
+ auto it = std::lower_bound(this->members_.begin(),this->members_.end(), name,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(key_storage_type(name.begin(),name.end()),
+ std::forward<Args>(args)...);
+ it = this->members_.begin() + this->members_.size() - 1;
+ inserted = true;
+ }
+ else if (it->key() == name)
+ {
+ inserted = false;
+ }
+ else
+ {
+ it = this->members_.emplace(it,
+ key_storage_type(name.begin(),name.end()),
+ std::forward<Args>(args)...);
+ inserted = true;
+ }
+ return std::make_pair(it,inserted);
+ }
+
+ template <class A=allocator_type, class... Args>
+ typename std::enable_if<!is_stateless<A>::value,std::pair<iterator,bool>>::type
+ try_emplace(const string_view_type& name, Args&&... args)
+ {
+ bool inserted;
+ auto it = std::lower_bound(this->members_.begin(),this->members_.end(), name,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(key_storage_type(name.begin(),name.end(), get_allocator()),
+ std::forward<Args>(args)...);
+ it = this->members_.begin() + this->members_.size() - 1;
+ inserted = true;
+ }
+ else if (it->key() == name)
+ {
+ inserted = false;
+ }
+ else
+ {
+ it = this->members_.emplace(it,
+ key_storage_type(name.begin(),name.end(), get_allocator()),
+ std::forward<Args>(args)...);
+ inserted = true;
+ }
+ return std::make_pair(it,inserted);
+ }
+
+ template <class A=allocator_type, class ... Args>
+ typename std::enable_if<is_stateless<A>::value,iterator>::type
+ try_emplace(iterator hint, const string_view_type& name, Args&&... args)
+ {
+ iterator it;
+ if (hint != this->members_.end() && hint->key() <= name)
+ {
+ it = std::lower_bound(hint,this->members_.end(), name,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ }
+ else
+ {
+ it = std::lower_bound(this->members_.begin(),this->members_.end(), name,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ }
+
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(key_storage_type(name.begin(),name.end()),
+ std::forward<Args>(args)...);
+ it = this->members_.begin() + (this->members_.size() - 1);
+ }
+ else if (it->key() == name)
+ {
+ }
+ else
+ {
+ it = this->members_.emplace(it,
+ key_storage_type(name.begin(),name.end()),
+ std::forward<Args>(args)...);
+ }
+ return it;
+ }
+
+ template <class A=allocator_type, class ... Args>
+ typename std::enable_if<!is_stateless<A>::value,iterator>::type
+ try_emplace(iterator hint, const string_view_type& name, Args&&... args)
+ {
+ iterator it;
+ if (hint != this->members_.end() && hint->key() <= name)
+ {
+ it = std::lower_bound(hint,this->members_.end(), name,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ }
+ else
+ {
+ it = std::lower_bound(this->members_.begin(),this->members_.end(), name,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ }
+
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(key_storage_type(name.begin(),name.end(), get_allocator()),
+ std::forward<Args>(args)...);
+ it = this->members_.begin() + (this->members_.size() - 1);
+ }
+ else if (it->key() == name)
+ {
+ }
+ else
+ {
+ it = this->members_.emplace(it,
+ key_storage_type(name.begin(),name.end(), get_allocator()),
+ std::forward<Args>(args)...);
+ }
+ return it;
+ }
+
+ // set_
+
+ template <class T, class A=allocator_type>
+ typename std::enable_if<is_stateless<A>::value,void>::type
+ set_(key_storage_type&& name, T&& value)
+ {
+ string_view_type s(name.data(), name.size());
+ auto it = std::lower_bound(this->members_.begin(),this->members_.end(), s,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(std::forward<key_storage_type>(name),
+ std::forward<T>(value));
+ }
+ else if (string_view_type(it->key().data(),it->key().length()) == s)
+ {
+ it->value(Json(std::forward<T>(value)));
+ }
+ else
+ {
+ this->members_.emplace(it,
+ std::forward<key_storage_type>(name),
+ std::forward<T>(value));
+ }
+ }
+
+ template <class T, class A=allocator_type>
+ typename std::enable_if<!is_stateless<A>::value,void>::type
+ set_(key_storage_type&& name, T&& value)
+ {
+ string_view_type s(name.data(), name.size());
+ auto it = std::lower_bound(this->members_.begin(),this->members_.end(), s,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(std::forward<key_storage_type>(name),
+ std::forward<T>(value),get_allocator() );
+ }
+ else if (string_view_type(it->key().data(), it->key().length()) == s)
+ {
+ it->value(Json(std::forward<T>(value),get_allocator() ));
+ }
+ else
+ {
+ this->members_.emplace(it,
+ std::forward<key_storage_type>(name),
+ std::forward<T>(value),get_allocator() );
+ }
+ }
+
+ template <class T, class A=allocator_type>
+ typename std::enable_if<is_stateless<A>::value,iterator>::type
+ insert_or_assign(iterator hint, const string_view_type& name, T&& value)
+ {
+ iterator it;
+ if (hint != this->members_.end() && hint->key() <= name)
+ {
+ it = std::lower_bound(hint,this->members_.end(), name,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ }
+ else
+ {
+ it = std::lower_bound(this->members_.begin(),this->members_.end(), name,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ }
+
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(key_storage_type(name.begin(),name.end()),
+ std::forward<T>(value));
+ it = this->members_.begin() + (this->members_.size() - 1);
+ }
+ else if (it->key() == name)
+ {
+ it->value(Json(std::forward<T>(value)));
+ }
+ else
+ {
+ it = this->members_.emplace(it,
+ key_storage_type(name.begin(),name.end()),
+ std::forward<T>(value));
+ }
+ return it;
+ }
+
+ template <class T, class A=allocator_type>
+ typename std::enable_if<!is_stateless<A>::value,iterator>::type
+ insert_or_assign(iterator hint, const string_view_type& name, T&& value)
+ {
+ iterator it;
+ if (hint != this->members_.end() && hint->key() <= name)
+ {
+ it = std::lower_bound(hint,this->members_.end(), name,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ }
+ else
+ {
+ it = std::lower_bound(this->members_.begin(),this->members_.end(), name,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ }
+
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(key_storage_type(name.begin(),name.end(), get_allocator()),
+ std::forward<T>(value),get_allocator());
+ it = this->members_.begin() + (this->members_.size() - 1);
+ }
+ else if (it->key() == name)
+ {
+ it->value(Json(std::forward<T>(value),get_allocator()));
+ }
+ else
+ {
+ it = this->members_.emplace(it,
+ key_storage_type(name.begin(),name.end(), get_allocator()),
+ std::forward<T>(value),get_allocator());
+ }
+ return it;
+ }
+
+ template <class T, class A=allocator_type>
+ typename std::enable_if<is_stateless<A>::value,iterator>::type
+ set_(iterator hint, key_storage_type&& name, T&& value)
+ {
+ string_view_type s(name.data(), name.size());
+ iterator it;
+ if (hint != this->members_.end() && hint->key() <= s)
+ {
+ it = std::lower_bound(hint,this->members_.end(), s,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ }
+ else
+ {
+ it = std::lower_bound(this->members_.begin(),this->members_.end(), s,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ }
+
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(std::forward<key_storage_type>(name),
+ std::forward<T>(value));
+ it = this->members_.begin() + (this->members_.size() - 1);
+ }
+ else if (string_view_type(it->key().data(), it->key().length()) == s)
+ {
+ it->value(Json(std::forward<T>(value)));
+ }
+ else
+ {
+ it = this->members_.emplace(it,
+ std::forward<key_storage_type>(name),
+ std::forward<T>(value));
+ }
+ return it;
+ }
+
+ template <class T, class A=allocator_type>
+ typename std::enable_if<!is_stateless<A>::value,iterator>::type
+ set_(iterator hint, key_storage_type&& name, T&& value)
+ {
+ string_view_type s(name.data(), name.size());
+ iterator it;
+ if (hint != this->members_.end() && hint->key() <= s)
+ {
+ it = std::lower_bound(hint,this->members_.end(), s,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ }
+ else
+ {
+ it = std::lower_bound(this->members_.begin(),this->members_.end(), s,
+ [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;});
+ }
+
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(std::forward<key_storage_type>(name),
+ std::forward<T>(value),get_allocator() );
+ it = this->members_.begin() + (this->members_.size() - 1);
+ }
+ else if (string_view_type(it->key().data(), it->key().length()) == s)
+ {
+ it->value(Json(std::forward<T>(value),get_allocator() ));
+ }
+ else
+ {
+ it = this->members_.emplace(it,
+ std::forward<key_storage_type>(name),
+ std::forward<T>(value),get_allocator() );
+ }
+ return it;
+ }
+
+ bool operator==(const json_object& rhs) const
+ {
+ if (size() != rhs.size())
+ {
+ return false;
+ }
+ for (auto it = this->members_.begin(); it != this->members_.end(); ++it)
+ {
+
+ auto rhs_it = std::lower_bound(rhs.begin(), rhs.end(), *it,
+ [](const value_type& a, const value_type& b){return a.key().compare(b.key()) < 0;});
+ if (rhs_it == rhs.end() || rhs_it->key() != it->key() || rhs_it->value() != it->value())
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+private:
+ json_object& operator=(const json_object&) = delete;
+};
+
+// Preserve order
+template <class KeyT,class Json>
+class json_object<KeyT,Json,true> final : public Json_object_<KeyT,Json>
+{
+public:
+ using typename Json_object_<KeyT,Json>::allocator_type;
+ using typename Json_object_<KeyT,Json>::char_type;
+ using typename Json_object_<KeyT,Json>::char_allocator_type;
+ using typename Json_object_<KeyT,Json>::key_storage_type;
+ using typename Json_object_<KeyT,Json>::string_view_type;
+ using typename Json_object_<KeyT,Json>::value_type;
+ using typename Json_object_<KeyT,Json>::kvp_allocator_type;
+ using typename Json_object_<KeyT,Json>::object_storage_type;
+ using typename Json_object_<KeyT,Json>::iterator;
+ using typename Json_object_<KeyT,Json>::const_iterator;
+ using Json_object_<KeyT,Json>::get_allocator;
+
+ json_object()
+ : Json_object_<KeyT,Json>()
+ {
+ }
+ json_object(const allocator_type& allocator)
+ : Json_object_<KeyT,Json>(allocator)
+ {
+ }
+
+ json_object(const json_object& val)
+ : Json_object_<KeyT,Json>(val)
+ {
+ }
+
+ json_object(json_object&& val)
+ : Json_object_<KeyT,Json>(std::forward<json_object>(val))
+ {
+ }
+
+ json_object(const json_object& val, const allocator_type& allocator)
+ : Json_object_<KeyT,Json>(val,allocator)
+ {
+ }
+
+ json_object(json_object&& val,const allocator_type& allocator)
+ : Json_object_<KeyT,Json>(std::forward<json_object>(val),allocator)
+ {
+ }
+
+ json_object(std::initializer_list<typename Json::array> init)
+ : Json_object_<KeyT,Json>()
+ {
+ for (const auto& element : init)
+ {
+ if (element.size() != 2 || !element[0].is_string())
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Cannot create object from initializer list"));
+ break;
+ }
+ }
+ for (auto& element : init)
+ {
+ insert_or_assign(element[0].as_string_view(), std::move(element[1]));
+ }
+ }
+
+ json_object(std::initializer_list<typename Json::array> init,
+ const allocator_type& allocator)
+ : Json_object_<KeyT,Json>(allocator)
+ {
+ for (const auto& element : init)
+ {
+ if (element.size() != 2 || !element[0].is_string())
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Cannot create object from initializer list"));
+ break;
+ }
+ }
+ for (auto& element : init)
+ {
+ insert_or_assign(element[0].as_string_view(), std::move(element[1]));
+ }
+ }
+
+ void swap(json_object& val)
+ {
+ Json_object_<KeyT,Json>::swap(val);
+ }
+
+ iterator begin()
+ {
+ return this->members_.begin();
+ }
+
+ iterator end()
+ {
+ return this->members_.end();
+ }
+
+ const_iterator begin() const
+ {
+ return this->members_.begin();
+ }
+
+ const_iterator end() const
+ {
+ return this->members_.end();
+ }
+
+ size_t size() const {return this->members_.size();}
+
+ size_t capacity() const {return this->members_.capacity();}
+
+ void clear() {this->members_.clear();}
+
+ void shrink_to_fit()
+ {
+ for (size_t i = 0; i < this->members_.size(); ++i)
+ {
+ this->members_[i].shrink_to_fit();
+ }
+ this->members_.shrink_to_fit();
+ }
+
+ void reserve(size_t n) {this->members_.reserve(n);}
+
+ Json& at(size_t i)
+ {
+ if (i >= this->members_.size())
+ {
+ JSONCONS_THROW(json_exception_impl<std::out_of_range>("Invalid array subscript"));
+ }
+ return this->members_[i].value();
+ }
+
+ const Json& at(size_t i) const
+ {
+ if (i >= this->members_.size())
+ {
+ JSONCONS_THROW(json_exception_impl<std::out_of_range>("Invalid array subscript"));
+ }
+ return this->members_[i].value();
+ }
+
+ iterator find(const string_view_type& name)
+ {
+ return std::find_if(this->members_.begin(),this->members_.end(),
+ [name](const value_type& kv){return kv.key() == name;});
+ }
+
+ const_iterator find(const string_view_type& name) const
+ {
+ return std::find_if(this->members_.begin(),this->members_.end(),
+ [name](const value_type& kv){return kv.key() == name;});
+ }
+
+ void erase(const_iterator first, const_iterator last)
+ {
+ this->members_.erase(first,last);
+ }
+
+ void erase(const string_view_type& name)
+ {
+ auto it = std::find_if(this->members_.begin(),this->members_.end(),
+ [name](const value_type& kv){return kv.key() == name;});
+ if (it != this->members_.end())
+ {
+ this->members_.erase(it);
+ }
+ }
+
+ template<class InputIt, class UnaryPredicate>
+ void insert(InputIt first, InputIt last, UnaryPredicate pred)
+ {
+ size_t count = std::distance(first,last);
+ this->members_.reserve(this->members_.size() + count);
+ for (auto s = first; s != last; ++s)
+ {
+ this->members_.emplace_back(pred(*s));
+ }
+ auto it = last_wins_unique_sequence(this->members_.begin(), this->members_.end(),
+ [](const value_type& a, const value_type& b){ return a.key().compare(b.key());});
+ this->members_.erase(it,this->members_.end());
+ }
+
+ // insert_or_assign
+
+ template <class T, class A=allocator_type>
+ typename std::enable_if<is_stateless<A>::value,std::pair<iterator,bool>>::type
+ insert_or_assign(const string_view_type& name, T&& value)
+ {
+ bool inserted;
+ auto it = std::find_if(this->members_.begin(),this->members_.end(),
+ [name](const value_type& a){return a.key() == name;});
+
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(key_storage_type(name.begin(),name.end()),
+ std::forward<T>(value));
+ it = this->members_.begin() + this->members_.size() - 1;
+ inserted = true;
+ }
+ else
+ {
+ it->value(Json(std::forward<T>(value)));
+ inserted = false; // assigned
+ }
+ return std::make_pair(it,inserted);
+ }
+
+ template <class T, class A=allocator_type>
+ typename std::enable_if<!is_stateless<A>::value,std::pair<iterator,bool>>::type
+ insert_or_assign(const string_view_type& name, T&& value)
+ {
+ bool inserted;
+ auto it = std::find_if(this->members_.begin(),this->members_.end(),
+ [name](const value_type& a){return a.key() == name;});
+
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(key_storage_type(name.begin(),name.end(),get_allocator()),
+ std::forward<T>(value),get_allocator());
+ it = this->members_.begin() + this->members_.size() - 1;
+ inserted = true;
+ }
+ else
+ {
+ it->value(Json(std::forward<T>(value),get_allocator()));
+ inserted = false; // assigned
+ }
+ return std::make_pair(it,inserted);
+ }
+
+ template <class A=allocator_type, class T>
+ typename std::enable_if<is_stateless<A>::value,iterator>::type
+ insert_or_assign(iterator hint, const string_view_type& key, T&& value)
+ {
+ iterator it;
+ if (hint == this->members_.end())
+ {
+ auto result = insert_or_assign(key, std::forward<T>(value));
+ it = result.first;
+ }
+ else
+ {
+ it = std::find_if(this->members_.begin(),this->members_.end(),
+ [key](const value_type& a){return a.key() == key;});
+
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(key_storage_type(key.begin(),key.end()),
+ std::forward<T>(value));
+ it = this->members_.begin() + this->members_.size() - 1;
+ }
+ else
+ {
+ it->value(Json(std::forward<T>(value)));
+ }
+ }
+ return it;
+ }
+
+ template <class A=allocator_type, class T>
+ typename std::enable_if<!is_stateless<A>::value,iterator>::type
+ insert_or_assign(iterator hint, const string_view_type& key, T&& value)
+ {
+ iterator it;
+ if (hint == this->members_.end())
+ {
+ auto result = insert_or_assign(key, std::forward<T>(value));
+ it = result.first;
+ }
+ else
+ {
+ it = std::find_if(this->members_.begin(),this->members_.end(),
+ [key](const value_type& a){return a.key() == key;});
+
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(key_storage_type(key.begin(),key.end(),get_allocator()),
+ std::forward<T>(value),get_allocator());
+ it = this->members_.begin() + this->members_.size() - 1;
+ }
+ else
+ {
+ it->value(Json(std::forward<T>(value),get_allocator()));
+ }
+ }
+ return it;
+ }
+
+ // merge
+
+ void merge(const json_object& source)
+ {
+ for (auto it = source.begin(); it != source.end(); ++it)
+ {
+ try_emplace(it->key(),it->value());
+ }
+ }
+
+ void merge(json_object&& source)
+ {
+ auto it = std::make_move_iterator(source.begin());
+ auto end = std::make_move_iterator(source.end());
+ for (; it != end; ++it)
+ {
+ auto pos = std::find_if(this->members_.begin(),this->members_.end(),
+ [it](const value_type& a){return a.key() == it->key();});
+ if (pos == this->members_.end() )
+ {
+ this->members_.emplace_back(*it);
+ }
+ }
+ }
+
+ void merge(iterator hint, const json_object& source)
+ {
+ for (auto it = source.begin(); it != source.end(); ++it)
+ {
+ hint = try_emplace(hint, it->key(),it->value());
+ }
+ }
+
+ void merge(iterator hint, json_object&& source)
+ {
+ auto it = std::make_move_iterator(source.begin());
+ auto end = std::make_move_iterator(source.end());
+ for (; it != end; ++it)
+ {
+ auto pos = std::find_if(this->members_.begin(),this->members_.end(),
+ [it](const value_type& a){return a.key() == it->key();});
+ if (pos == this->members_.end() )
+ {
+ hint = this->members_.emplace(hint,*it);
+ }
+ }
+ }
+
+ // merge_or_update
+
+ void merge_or_update(const json_object& source)
+ {
+ for (auto it = source.begin(); it != source.end(); ++it)
+ {
+ insert_or_assign(it->key(),it->value());
+ }
+ }
+
+ void merge_or_update(json_object&& source)
+ {
+ auto it = std::make_move_iterator(source.begin());
+ auto end = std::make_move_iterator(source.end());
+ for (; it != end; ++it)
+ {
+ auto pos = std::find_if(this->members_.begin(),this->members_.end(),
+ [it](const value_type& a){return a.key() == it->key();});
+ if (pos == this->members_.end() )
+ {
+ this->members_.emplace_back(*it);
+ }
+ else
+ {
+ pos->value(it->value());
+ }
+ }
+ }
+
+ void merge_or_update(iterator hint, const json_object& source)
+ {
+ for (auto it = source.begin(); it != source.end(); ++it)
+ {
+ hint = insert_or_assign(hint, it->key(),it->value());
+ }
+ }
+
+ void merge_or_update(iterator hint, json_object&& source)
+ {
+ auto it = std::make_move_iterator(source.begin());
+ auto end = std::make_move_iterator(source.end());
+ for (; it != end; ++it)
+ {
+ auto pos = std::find_if(this->members_.begin(),this->members_.end(),
+ [it](const value_type& a){return a.key() == it->key();});
+ if (pos == this->members_.end() )
+ {
+ hint = this->members_.emplace(hint,*it);
+ }
+ else
+ {
+ pos->value(it->value());
+ hint = pos;
+ }
+ }
+ }
+
+ // try_emplace
+ template <class A=allocator_type, class... Args>
+ typename std::enable_if<is_stateless<A>::value,std::pair<iterator,bool>>::type
+ try_emplace(const string_view_type& key, Args&&... args)
+ {
+ bool inserted;
+ auto it = std::find_if(this->members_.begin(),this->members_.end(),
+ [key](const value_type& a){return a.key() == key;});
+
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(key_storage_type(key.begin(),key.end()),
+ std::forward<Args>(args)...);
+ it = this->members_.begin() + this->members_.size() - 1;
+ inserted = true;
+
+ }
+ else
+ {
+ inserted = false;
+ }
+ return std::make_pair(it,inserted);
+ }
+
+ template <class A=allocator_type, class... Args>
+ typename std::enable_if<!is_stateless<A>::value,std::pair<iterator,bool>>::type
+ try_emplace(const string_view_type& key, Args&&... args)
+ {
+ bool inserted;
+ auto it = std::find_if(this->members_.begin(),this->members_.end(),
+ [key](const value_type& a){return a.key() == key;});
+
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(key_storage_type(key.begin(),key.end(), get_allocator()),
+ std::forward<Args>(args)...);
+ it = this->members_.begin() + this->members_.size() - 1;
+ inserted = true;
+
+ }
+ else
+ {
+ inserted = false;
+ }
+ return std::make_pair(it,inserted);
+ }
+
+ template <class A=allocator_type, class ... Args>
+ typename std::enable_if<is_stateless<A>::value,iterator>::type
+ try_emplace(iterator hint, const string_view_type& key, Args&&... args)
+ {
+ auto it = std::find_if(this->members_.begin(),this->members_.end(),
+ [key](const value_type& a){return a.key() == key;});
+
+ if (it == this->members_.end())
+ {
+ if (hint == this->members_.end())
+ {
+ this->members_.emplace_back(key_storage_type(key.begin(),key.end()),
+ std::forward<Args>(args)...);
+ it = this->members_.begin() + (this->members_.size() - 1);
+ }
+ else
+ {
+ it = this->members_.emplace(hint,
+ key_storage_type(key.begin(),key.end()),
+ std::forward<Args>(args)...);
+ }
+ }
+ return it;
+ }
+
+ template <class A=allocator_type, class ... Args>
+ typename std::enable_if<!is_stateless<A>::value,iterator>::type
+ try_emplace(iterator hint, const string_view_type& key, Args&&... args)
+ {
+ auto it = std::find_if(this->members_.begin(),this->members_.end(),
+ [key](const value_type& a){return a.key() == key;});
+
+ if (it == this->members_.end())
+ {
+ if (hint == this->members_.end())
+ {
+ this->members_.emplace_back(key_storage_type(key.begin(),key.end(), get_allocator()),
+ std::forward<Args>(args)...);
+ it = this->members_.begin() + (this->members_.size() - 1);
+ }
+ else
+ {
+ it = this->members_.emplace(hint,
+ key_storage_type(key.begin(),key.end(), get_allocator()),
+ std::forward<Args>(args)...);
+ }
+ }
+ return it;
+ }
+
+ // set_
+
+ template <class T, class A=allocator_type>
+ typename std::enable_if<is_stateless<A>::value,void>::type
+ set_(key_storage_type&& key, T&& value)
+ {
+ string_view_type s(key.data(),key.size());
+ auto it = std::find_if(this->members_.begin(),this->members_.end(),
+ [s](const value_type& a){return a.key().compare(s) == 0;});
+
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(std::forward<key_storage_type>(key),
+ std::forward<T>(value));
+ }
+ else
+ {
+ it->value(Json(std::forward<T>(value)));
+ }
+ }
+
+ template <class T, class A=allocator_type>
+ typename std::enable_if<!is_stateless<A>::value,void>::type
+ set_(key_storage_type&& key, T&& value)
+ {
+ string_view_type s(key.data(),key.size());
+ auto it = std::find_if(this->members_.begin(),this->members_.end(),
+ [s](const value_type& a){return a.key().compare(s) == 0;});
+
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(std::forward<key_storage_type>(key),
+ std::forward<T>(value),get_allocator());
+ }
+ else
+ {
+ it->value(Json(std::forward<T>(value),get_allocator()));
+ }
+ }
+
+ template <class T, class A=allocator_type>
+ typename std::enable_if<is_stateless<A>::value,iterator>::type
+ set_(iterator hint, key_storage_type&& key, T&& value)
+ {
+ iterator it = hint;
+
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(std::forward<key_storage_type>(key),
+ std::forward<T>(value));
+ it = this->members_.begin() + (this->members_.size() - 1);
+ }
+ else if (it->key() == key)
+ {
+ it->value(Json(std::forward<T>(value)));
+ }
+ else
+ {
+ it = this->members_.emplace(it,
+ std::forward<key_storage_type>(key),
+ std::forward<T>(value));
+ }
+ return it;
+ }
+
+ template <class T, class A=allocator_type>
+ typename std::enable_if<!is_stateless<A>::value,iterator>::type
+ set_(iterator hint, key_storage_type&& key, T&& value)
+ {
+ iterator it = hint;
+
+ if (it == this->members_.end())
+ {
+ this->members_.emplace_back(std::forward<key_storage_type>(key),
+ std::forward<T>(value), get_allocator());
+ it = this->members_.begin() + (this->members_.size() - 1);
+ }
+ else if (it->key() == key)
+ {
+ it->value(Json(std::forward<T>(value), get_allocator()));
+ }
+ else
+ {
+ it = this->members_.emplace(it,
+ std::forward<key_storage_type>(key),
+ std::forward<T>(value), get_allocator());
+ }
+ return it;
+ }
+
+ bool operator==(const json_object& rhs) const
+ {
+ if (size() != rhs.size())
+ {
+ return false;
+ }
+ for (auto it = this->members_.begin(); it != this->members_.end(); ++it)
+ {
+ auto rhs_it = std::find_if(rhs.begin(),rhs.end(),
+ [it](const value_type& a){return a.key() == it->key();});
+ if (rhs_it == rhs.end() || rhs_it->key() != it->key() || rhs_it->value() != it->value())
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+private:
+ json_object& operator=(const json_object&) = delete;
+};
+
+}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/json_type_traits.hpp b/vendor/jsoncons-0.104.0/jsoncons/json_type_traits.hpp
new file mode 100644
index 00000000..1c76c4c0
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/json_type_traits.hpp
@@ -0,0 +1,966 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSON_TYPE_TRAITS_HPP
+#define JSONCONS_JSON_TYPE_TRAITS_HPP
+
+#include <array>
+#include <string>
+#include <vector>
+#include <valarray>
+#include <exception>
+#include <cstdlib>
+#include <cstring>
+#include <utility>
+#include <algorithm>
+#include <fstream>
+#include <limits>
+#include <type_traits>
+#include <jsoncons/jsoncons_utilities.hpp>
+#include <jsoncons/detail/type_traits_helper.hpp>
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wswitch"
+#endif
+
+namespace jsoncons {
+
+// null_type
+
+struct null_type
+{
+};
+
+// json_type_traits
+
+template <class Json, class T, class Enable=void>
+struct json_type_traits
+{
+ static const bool is_compatible = false;
+
+ static bool is(const Json&)
+ {
+ return false;
+ }
+};
+
+namespace detail {
+
+// is_incompatible
+template<class Json, class T, class Enable = void>
+struct is_incompatible : std::false_type {};
+
+
+// is_incompatible
+template<class Json, class T>
+struct is_incompatible<Json,T,
+ typename std::enable_if<!std::integral_constant<bool, json_type_traits<Json, T>::is_compatible>::value>::type
+> : std::true_type {};
+
+// is_compatible_string_type
+template<class Json, class T, class Enable=void>
+struct is_compatible_string_type : std::false_type {};
+
+template<class Json, class T>
+struct is_compatible_string_type<Json,T,
+ typename std::enable_if<!std::is_same<T,typename Json::array>::value &&
+ detail::is_string_like<T>::value &&
+ !is_incompatible<Json,typename std::iterator_traits<typename T::iterator>::value_type>::value
+>::type> : std::true_type {};
+
+// is_compatible_array_type
+template<class Json, class T, class Enable=void>
+struct is_compatible_array_type : std::false_type {};
+
+template<class Json, class T>
+struct is_compatible_array_type<Json,T,
+ typename std::enable_if<!std::is_same<T,typename Json::array>::value &&
+ detail::is_vector_like<T>::value &&
+ !is_incompatible<Json,typename std::iterator_traits<typename T::iterator>::value_type>::value
+>::type> : std::true_type {};
+
+// is_compatible_object_type
+template<class Json, class T, class Enable=void>
+struct is_compatible_object_type : std::false_type {};
+
+template<class Json, class T>
+struct is_compatible_object_type<Json,T,
+ typename std::enable_if<
+ !is_incompatible<Json,typename T::mapped_type>::value
+>::type> : std::true_type {};
+
+// is_std_array
+template<class T>
+struct is_std_array : std::false_type {};
+
+template<class E, size_t N>
+struct is_std_array<std::array<E, N>> : std::true_type {};
+
+template <class Json, class T>
+class json_array_input_iterator
+{
+public:
+ typedef typename Json::const_array_iterator iterator_base;
+ typedef typename std::iterator_traits<iterator_base>::value_type value_type;
+ typedef typename std::iterator_traits<iterator_base>::difference_type difference_type;
+ typedef typename std::iterator_traits<iterator_base>::pointer pointer;
+ typedef T reference;
+ typedef std::input_iterator_tag iterator_category;
+
+ json_array_input_iterator()
+ {
+ }
+
+ json_array_input_iterator(iterator_base it)
+ : it_(it)
+ {
+ }
+
+ json_array_input_iterator& operator=(json_array_input_iterator rhs)
+ {
+ swap(*this,rhs);
+ return *this;
+ }
+
+ json_array_input_iterator& operator++()
+ {
+ ++it_;
+ return *this;
+ }
+
+ json_array_input_iterator operator++(int) // postfix increment
+ {
+ json_array_input_iterator temp(*this);
+ ++it_;
+ return temp;
+ }
+
+ json_array_input_iterator& operator--()
+ {
+ --it_;
+ return *this;
+ }
+
+ json_array_input_iterator operator--(int)
+ {
+ json_array_input_iterator temp(*this);
+ --it_;
+ return temp;
+ }
+
+ reference operator*() const
+ {
+ return json_type_traits<Json,T>::as(*it_);
+ }
+
+ friend bool operator==(const json_array_input_iterator& it1, const json_array_input_iterator& it2)
+ {
+ return it1.it_ == it2.it_;
+ }
+ friend bool operator!=(const json_array_input_iterator& it1, const json_array_input_iterator& it2)
+ {
+ return !(it1.it_ == it2.it_);
+ }
+ friend void swap(json_array_input_iterator& lhs, json_array_input_iterator& rhs)
+ {
+ using std::swap;
+ swap(lhs.it_,rhs.it_);
+ swap(lhs.empty_,rhs.empty_);
+ }
+
+private:
+ iterator_base it_;
+};
+
+template <class Json, class T>
+class json_object_input_iterator
+{
+public:
+ typedef typename Json::const_object_iterator iterator_base;
+ typedef typename std::iterator_traits<iterator_base>::value_type value_type;
+ typedef typename std::iterator_traits<iterator_base>::difference_type difference_type;
+ typedef typename std::iterator_traits<iterator_base>::pointer pointer;
+ typedef T reference;
+ typedef std::input_iterator_tag iterator_category;
+ typedef typename T::first_type key_type;
+ typedef typename T::second_type mapped_type;
+
+ json_object_input_iterator()
+ {
+ }
+
+ json_object_input_iterator(iterator_base it)
+ : it_(it)
+ {
+ }
+
+ json_object_input_iterator& operator=(json_object_input_iterator rhs)
+ {
+ swap(*this,rhs);
+ return *this;
+ }
+
+ json_object_input_iterator& operator++()
+ {
+ ++it_;
+ return *this;
+ }
+
+ json_object_input_iterator operator++(int) // postfix increment
+ {
+ json_object_input_iterator temp(*this);
+ ++it_;
+ return temp;
+ }
+
+ json_object_input_iterator& operator--()
+ {
+ --it_;
+ return *this;
+ }
+
+ json_object_input_iterator operator--(int)
+ {
+ json_object_input_iterator temp(*this);
+ --it_;
+ return temp;
+ }
+
+ reference operator*() const
+ {
+ return T(key_type(it_->key()),json_type_traits<Json,mapped_type>::as(it_->value()));
+ }
+
+ friend bool operator==(const json_object_input_iterator& it1, const json_object_input_iterator& it2)
+ {
+ return it1.it_ == it2.it_;
+ }
+ friend bool operator!=(const json_object_input_iterator& it1, const json_object_input_iterator& it2)
+ {
+ return !(it1.it_ == it2.it_);
+ }
+ friend void swap(json_object_input_iterator& lhs, json_object_input_iterator& rhs)
+ {
+ using std::swap;
+ swap(lhs.it_,rhs.it_);
+ swap(lhs.empty_,rhs.empty_);
+ }
+
+private:
+ iterator_base it_;
+};
+
+}
+
+template<class Json>
+struct json_type_traits<Json, typename type_wrapper<typename Json::char_type>::const_pointer_type>
+{
+ typedef typename Json::char_type char_type;
+ typedef typename Json::allocator_type allocator_type;
+
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ return j.is_string();
+ }
+ static const char_type* as(const Json& j)
+ {
+ return j.as_cstring();
+ }
+ template <class ... Args>
+ static Json to_json(Args&&... args)
+ {
+ return Json(typename Json::variant(std::forward<Args>(args)...));
+ }
+};
+
+template<class Json>
+struct json_type_traits<Json, typename type_wrapper<typename Json::char_type>::pointer_type>
+{
+ typedef typename Json::char_type char_type;
+ typedef typename Json::allocator_type allocator_type;
+
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ return j.is_string();
+ }
+ template <class ... Args>
+ static Json to_json(Args&&... args)
+ {
+ return Json(typename Json::variant(std::forward<Args>(args)...));
+ }
+};
+
+// integral
+
+template<class Json, class T>
+struct json_type_traits<Json, T,
+ typename std::enable_if<detail::is_integer_like<T>::value
+>::type>
+{
+ typedef typename Json::allocator_type allocator_type;
+
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ if (j.is_integer())
+ {
+ return j.as_integer() >= (std::numeric_limits<T>::min)() && j.as_integer() <= (std::numeric_limits<T>::max)();
+ }
+ else if (j.is_uinteger())
+ {
+ return j.as_uinteger() <= static_cast<uint64_t>((std::numeric_limits<T>::max)());
+ }
+ else
+ {
+ return false;
+ }
+ }
+ static T as(const Json& j)
+ {
+ return static_cast<T>(j.as_integer());
+ }
+ template <class ... Args>
+ static Json to_json(Args&&... args)
+ {
+ return Json::from_integer(std::forward<Args>(args)...);
+ }
+};
+
+template<class Json, class T>
+struct json_type_traits<Json, T,
+ typename std::enable_if<detail::is_uinteger_like<T>::value
+>::type >
+{
+ typedef typename Json::allocator_type allocator_type;
+
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ if (j.is_integer())
+ {
+ return j.as_integer() >= 0 && static_cast<uint64_t>(j.as_integer()) <= (std::numeric_limits<T>::max)();
+ }
+ else if (j.is_uinteger())
+ {
+ return j.as_uinteger() <= (std::numeric_limits<T>::max)();
+ }
+ else
+ {
+ return false;
+ }
+ }
+ static T as(const Json& j)
+ {
+ return static_cast<T>(j.as_uinteger());
+ }
+
+ template <class ... Args>
+ static Json to_json(Args&&... args)
+ {
+ return Json::from_uinteger(std::forward<Args>(args)...);
+ }
+};
+
+template<class Json,class T>
+struct json_type_traits<Json, T,
+ typename std::enable_if<std::is_floating_point<T>::value
+>::type>
+{
+ typedef typename Json::allocator_type allocator_type;
+
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ return j.is_double();
+ }
+ static T as(const Json& j)
+ {
+ return static_cast<T>(j.as_double());
+ }
+ template <class ... Args>
+ static Json to_json(Args&&... args)
+ {
+ return Json::from_floating_point(std::forward<Args>(args)...);
+ }
+};
+
+template<class Json>
+struct json_type_traits<Json, typename Json::object>
+{
+ typedef typename Json::allocator_type allocator_type;
+
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ return j.is_object();
+ }
+ template <class ... Args>
+ static Json to_json(Args&&... args)
+ {
+ return Json(typename Json::variant(std::forward<Args>(args)...));
+ }
+};
+
+template<class Json>
+struct json_type_traits<Json, typename Json::array>
+{
+ typedef typename Json::allocator_type allocator_type;
+
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ return j.is_array();
+ }
+ template <class ... Args>
+ static Json to_json(Args&&... args)
+ {
+ return Json(typename Json::variant(std::forward<Args>(args)...));
+ }
+};
+
+template<class Json>
+struct json_type_traits<Json, Json>
+{
+ typedef typename Json::allocator_type allocator_type;
+
+ static bool is(const Json&) JSONCONS_NOEXCEPT
+ {
+ return true;
+ }
+ static Json as(Json j)
+ {
+ return j;
+ }
+ static Json to_json(const Json& val)
+ {
+ return val;
+ }
+ static Json to_json(const Json& val, allocator_type)
+ {
+ return val;
+ }
+};
+
+template<class Json>
+struct json_type_traits<Json, jsoncons::null_type>
+{
+ typedef typename Json::allocator_type allocator_type;
+
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ return j.is_null();
+ }
+ static typename jsoncons::null_type as(const Json& j)
+ {
+ JSONCONS_ASSERT(j.is_null());
+ return jsoncons::null_type();
+ }
+ static Json to_json(jsoncons::null_type)
+ {
+ return Json::null();
+ }
+ static Json to_json(jsoncons::null_type, allocator_type)
+ {
+ return Json::null();
+ }
+};
+
+template<class Json>
+struct json_type_traits<Json, bool>
+{
+ typedef typename Json::allocator_type allocator_type;
+
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ return j.is_bool();
+ }
+ static bool as(const Json& j)
+ {
+ return j.as_bool();
+ }
+ template <class ... Args>
+ static Json to_json(Args&&... args)
+ {
+ return Json(typename Json::variant(std::forward<Args>(args)...));
+ }
+};
+
+template<class Json,class T>
+struct json_type_traits<Json, T, typename std::enable_if<std::is_same<T,
+ std::conditional<!std::is_same<bool,std::vector<bool>::const_reference>::value,
+ std::vector<bool>::const_reference,
+ void>::type>::value>::type>
+{
+ typedef typename Json::allocator_type allocator_type;
+
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ return j.is_bool();
+ }
+ static bool as(const Json& j)
+ {
+ return j.as_bool();
+ }
+ template <class ... Args>
+ static Json to_json(Args&&... args)
+ {
+ return Json(typename Json::variant(std::forward<Args>(args)...));
+ }
+};
+
+template<class Json>
+struct json_type_traits<Json, std::vector<bool>::reference>
+{
+ typedef typename Json::allocator_type allocator_type;
+
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ return j.is_bool();
+ }
+ static bool as(const Json& j)
+ {
+ return j.as_bool();
+ }
+ template <class ... Args>
+ static Json to_json(Args&&... args)
+ {
+ return Json(typename Json::variant(std::forward<Args>(args)...));
+ }
+};
+
+template<class Json, typename T>
+struct json_type_traits<Json, T,
+ typename std::enable_if<detail::is_compatible_array_type<Json,T>::value &&
+ !detail::is_std_array<T>::value>::type>
+{
+ typedef typename std::iterator_traits<typename T::iterator>::value_type element_type;
+ typedef typename Json::allocator_type allocator_type;
+
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ bool result = j.is_array();
+ if (result)
+ {
+ for (auto e : j.array_range())
+ {
+ if (!e.template is<element_type>())
+ {
+ result = false;
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ template <class Ty = element_type>
+ static typename std::enable_if<!(std::is_integral<Ty>::value && !std::is_same<Ty,bool>::value),T>::type
+ as(const Json& j)
+ {
+ if (j.is_array())
+ {
+ T v(detail::json_array_input_iterator<Json, element_type>(j.array_range().begin()),
+ detail::json_array_input_iterator<Json, element_type>(j.array_range().end()));
+ return v;
+ }
+ else
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Attempt to cast json non-array to array"));
+ }
+ }
+
+ template <class Ty = element_type>
+ static typename std::enable_if<std::is_integral<Ty>::value && !std::is_same<Ty,bool>::value,T>::type
+ as(const Json& j)
+ {
+ if (j.is_array())
+ {
+ T v(detail::json_array_input_iterator<Json, element_type>(j.array_range().begin()),
+ detail::json_array_input_iterator<Json, element_type>(j.array_range().end()));
+ return v;
+ }
+ else if (j.is_byte_string())
+ {
+ T v(j.as_byte_string_view().begin(),j.as_byte_string_view().end());
+ return v;
+ }
+ else
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Attempt to cast json non-array to array"));
+ }
+ }
+
+ static Json to_json(const T& val)
+ {
+ Json j = typename Json::array();
+ auto first = std::begin(val);
+ auto last = std::end(val);
+ size_t size = std::distance(first,last);
+ j.reserve(size);
+ for (auto it = first; it != last; ++it)
+ {
+ j.push_back(*it);
+ }
+ return j;
+ }
+
+ static Json to_json(const T& val, const allocator_type& allocator)
+ {
+ Json j = typename Json::array(allocator);
+ auto first = std::begin(val);
+ auto last = std::end(val);
+ size_t size = std::distance(first, last);
+ j.reserve(size);
+ for (auto it = first; it != last; ++it)
+ {
+ j.push_back(*it);
+ }
+ return j;
+ }
+};
+
+template<class Json, typename T>
+struct json_type_traits<Json, T,
+ typename std::enable_if<detail::is_compatible_string_type<Json,T>::value>::type>
+{
+ typedef typename std::iterator_traits<typename T::iterator>::value_type element_type;
+ typedef typename Json::allocator_type allocator_type;
+ typedef typename T::allocator_type string_allocator_type;
+
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ return j.is_string();
+ }
+
+ static T as(const Json& j)
+ {
+ if (j.is_string())
+ {
+ return j.as_string(string_allocator_type());
+ }
+ else
+ {
+ T s;
+ j.dump(s);
+ return s;
+ }
+ }
+
+ static Json to_json(const T& val)
+ {
+ return Json(typename Json::variant(val.data(), val.size()));
+ }
+
+ static Json to_json(const T& val, const allocator_type& allocator)
+ {
+ return Json(typename Json::variant(val.data(),val.size(),allocator));
+ }
+};
+
+template<class Json, typename T>
+struct json_type_traits<Json, T,
+ typename std::enable_if<detail::is_compatible_object_type<Json,T>::value>::type
+>
+{
+ typedef typename T::mapped_type mapped_type;
+ typedef typename T::value_type value_type;
+ typedef typename Json::allocator_type allocator_type;
+
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ bool result = j.is_object();
+ for (auto member : j.object_range())
+ {
+ if (!member.value().template is<mapped_type>())
+ {
+ result = false;
+ }
+ }
+ return result;
+ }
+
+ static T as(const Json& j)
+ {
+ T v(detail::json_object_input_iterator<Json,value_type>(j.object_range().begin()),
+ detail::json_object_input_iterator<Json,value_type>(j.object_range().end()));
+ return v;
+ }
+
+ static Json to_json(const T& val)
+ {
+ Json j;
+ j.reserve(val.size());
+ for (auto p: val)
+ {
+ j.set(p.first, p.second);
+ }
+ return j;
+ }
+
+ static Json to_json(const T& val, const allocator_type& allocator)
+ {
+ Json j(allocator);
+ j.reserve(val.size());
+ for (auto p: val)
+ {
+ j.set(p.first, p.second);
+ }
+ return j;
+ }
+};
+
+template<class Json, class E, size_t N>
+struct json_type_traits<Json, std::array<E, N>>
+{
+ typedef typename Json::allocator_type allocator_type;
+
+ typedef E element_type;
+
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ bool result = j.is_array() && j.size() == N;
+ if (result)
+ {
+ for (auto e : j.array_range())
+ {
+ if (!e.template is<element_type>())
+ {
+ result = false;
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ static std::array<E, N> as(const Json& j)
+ {
+ std::array<E, N> buff;
+ JSONCONS_ASSERT(j.size() == N);
+ for (size_t i = 0; i < N; i++)
+ {
+ buff[i] = j[i].template as<E>();
+ }
+ return buff;
+ }
+
+ static Json to_json(const std::array<E, N>& val)
+ {
+ Json j = typename Json::array();
+ j.reserve(N);
+ for (auto it = val.begin(); it != val.end(); ++it)
+ {
+ j.push_back(*it);
+ }
+ return j;
+ }
+
+ static Json to_json(const std::array<E, N>& val,
+ const allocator_type& allocator)
+ {
+ Json j = typename Json::array(allocator);
+ j.reserve(N);
+ for (auto it = val.begin(); it != val.end(); ++it)
+ {
+ j.push_back(*it);
+ }
+ return j;
+ }
+};
+
+namespace detail
+{
+
+template<size_t Pos, class Json, class Tuple>
+struct json_tuple_helper
+{
+ using element_type = typename std::tuple_element<Pos - 1, Tuple>::type;
+ using next = json_tuple_helper<Pos - 1, Json, Tuple>;
+
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ if(j[Pos - 1].template is<element_type>())
+ {
+ return next::is(j);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ static void as(Tuple& tuple, const Json& j)
+ {
+ std::get<Pos - 1>(tuple) = j[Pos - 1].template as<element_type>();
+ next::as(tuple, j);
+ }
+
+ static void to_json(const Tuple& tuple, std::array<Json, std::tuple_size<Tuple>::value>& jsons)
+ {
+ jsons[Pos - 1] = json_type_traits<Json, element_type>::to_json(std::get<Pos-1>(tuple));
+ next::to_json(tuple, jsons);
+ }
+};
+
+template<class Json, class Tuple>
+struct json_tuple_helper<0, Json, Tuple>
+{
+ static bool is(const Json&) JSONCONS_NOEXCEPT
+ {
+ return true;
+ }
+
+ static void as(Tuple&, const Json&)
+ {
+ }
+
+ static void to_json(const Tuple&, std::array<Json, std::tuple_size<Tuple>::value>&)
+ {
+ }
+};
+
+}
+
+template<class Json, typename... E>
+struct json_type_traits<Json, std::tuple<E...>>
+{
+private:
+ using helper = detail::json_tuple_helper<sizeof...(E), Json, std::tuple<E...>>;
+
+public:
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ return helper::is(j);
+ }
+
+ static std::tuple<E...> as(const Json& j)
+ {
+ std::tuple<E...> buff;
+ helper::as(buff, j);
+ return buff;
+ }
+
+ static Json to_json(const std::tuple<E...>& val)
+ {
+ std::array<Json, sizeof...(E)> buf;
+ helper::to_json(val, buf);
+ return Json(typename Json::array(buf.begin(), buf.end()));
+ }
+};
+
+template<class Json, class T1, class T2>
+struct json_type_traits<Json, std::pair<T1,T2>>
+{
+public:
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ return j.is_array() && j.size() == 2;
+ }
+
+ static std::pair<T1,T2> as(const Json& j)
+ {
+ return std::make_pair<T1,T2>(j[0]. template as<T1>(),j[1]. template as<T2>());
+ }
+
+ static Json to_json(const std::pair<T1,T2>& val)
+ {
+ return typename Json::array{val.first,val.second};
+ }
+};
+
+template<class Json, class Allocator>
+struct json_type_traits<Json, basic_byte_string<Allocator>>
+{
+public:
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ return j.is_byte_string();
+ }
+
+ static basic_byte_string<Allocator> as(const Json& j)
+ {
+ return basic_byte_string<Allocator>(j.as_byte_string_view());
+ }
+
+ static Json to_json(const basic_byte_string<Allocator>& val)
+ {
+ return Json(val.data(),val.length());
+ }
+};
+
+// std::valarray
+
+template<class Json, class T>
+struct json_type_traits<Json, std::valarray<T>>
+{
+ typedef typename Json::allocator_type allocator_type;
+
+ static bool is(const Json& j) JSONCONS_NOEXCEPT
+ {
+ bool result = j.is_array();
+ if (result)
+ {
+ for (auto e : j.array_range())
+ {
+ if (!e.template is<T>())
+ {
+ result = false;
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ static std::valarray<T> as(const Json& j)
+ {
+ if (j.is_array())
+ {
+ std::valarray<T> v(j.size());
+ for (size_t i = 0; i < j.size(); ++i)
+ {
+ v[i] = j[i].template as<T>();
+ }
+ return v;
+ }
+ else
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Attempt to cast json non-array to array"));
+ }
+ }
+
+ static Json to_json(const std::valarray<T>& val)
+ {
+ Json j = typename Json::array();
+ auto first = std::begin(val);
+ auto last = std::end(val);
+ size_t size = std::distance(first,last);
+ j.reserve(size);
+ for (auto it = first; it != last; ++it)
+ {
+ j.push_back(*it);
+ }
+ return j;
+ }
+
+ static Json to_json(const std::valarray<T>& val, const allocator_type& allocator)
+ {
+ Json j = typename Json::array(allocator);
+ auto first = std::begin(val);
+ auto last = std::end(val);
+ size_t size = std::distance(first,last);
+ j.reserve(size);
+ for (auto it = first; it != last; ++it)
+ {
+ j.push_back(*it);
+ }
+ return j;
+ }
+};
+
+}
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/jsoncons_config.hpp b/vendor/jsoncons-0.104.0/jsoncons/jsoncons_config.hpp
new file mode 100644
index 00000000..59c6b650
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/jsoncons_config.hpp
@@ -0,0 +1,106 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSONCONS_CONFIG_HPP
+#define JSONCONS_JSONCONS_CONFIG_HPP
+
+#include <stdexcept>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <cstdlib>
+#include <cmath>
+#include <cstdarg>
+#include <exception>
+#include <limits> // std::numeric_limits
+
+// Uncomment the following line to suppress deprecated names (recommended for new code)
+//#define JSONCONS_NO_DEPRECATED
+
+// The definitions below follow the definitions in compiler_support_p.h, https://github.com/01org/tinycbor
+// MIT license
+
+#if defined(__GNUC__) || defined(__clang__)
+#define JSONCONS_LIKELY(x) __builtin_expect(!!(x), 1)
+#define JSONCONS_UNLIKELY(x) __builtin_expect(!!(x), 0)
+#define JSONCONS_UNREACHABLE() __builtin_unreachable()
+#elif defined(_MSC_VER)
+#define JSONCONS_LIKELY(x) x
+#define JSONCONS_UNLIKELY(x) x
+#define JSONCONS_UNREACHABLE() __assume(0)
+#else
+#define JSONCONS_LIKELY(x) x
+#define JSONCONS_UNLIKELY(x) x
+#define JSONCONS_UNREACHABLE() do {} while (0)
+#endif
+
+namespace jsoncons
+{
+
+#if _MSC_VER > 1800 // _MSC_VER == 1800 -> MS Visual Studio 2013
+#else
+#define JSONCONS_NO_CONSTEXPR
+#endif
+
+#define JSONCONS_NO_TO_CHARS
+
+#if defined(_MSC_VER)
+#if _MSC_VER >= 1900
+#define JSONCONS_HAS_USER_DEFINED_LITERALS
+#endif
+#else
+#define JSONCONS_HAS_USER_DEFINED_LITERALS
+#endif
+
+//#define JSONCONS_HAS_STRING_VIEW
+
+#if defined(ANDROID) || defined(__ANDROID__)
+#define JSONCONS_HAS_STRTOLD_L
+#define JSONCONS_NO_LOCALECONV
+#endif
+
+#if defined (__clang__)
+#if defined(_GLIBCXX_USE_NOEXCEPT)
+#define JSONCONS_NOEXCEPT _GLIBCXX_USE_NOEXCEPT
+#else
+#define JSONCONS_NOEXCEPT noexcept
+#endif
+#elif defined(__GNUC__)
+#define JSONCONS_NOEXCEPT _GLIBCXX_USE_NOEXCEPT
+#elif defined(_MSC_VER)
+#if _MSC_VER >= 1900
+#define JSONCONS_NOEXCEPT noexcept
+#else
+#define JSONCONS_NOEXCEPT
+#endif
+#else
+#define JSONCONS_NOEXCEPT
+#endif
+
+#if defined(_MSC_VER)
+#define JSONCONS_HAS_MSC__STRTOD_L
+#define JSONCONS_HAS__ECVT_S
+#define JSONCONS_HAS_FOPEN_S
+#if _MSC_VER >= 1900
+#define JSONCONS_ALIGNOF alignof
+#else
+#define JSONCONS_ALIGNOF __alignof
+#endif
+#else
+#define JSONCONS_ALIGNOF alignof
+#endif
+
+#define JSONCONS_DEFINE_LITERAL( name, lit ) \
+template< class Ch > Ch const* name(); \
+template<> inline char const * name<char>() { return lit; } \
+template<> inline wchar_t const* name<wchar_t>() { return L ## lit; }
+
+}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/jsoncons_utilities.hpp b/vendor/jsoncons-0.104.0/jsoncons/jsoncons_utilities.hpp
new file mode 100644
index 00000000..28a9eb71
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/jsoncons_utilities.hpp
@@ -0,0 +1,954 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSONCONSUTILITIES_HPP
+#define JSONCONS_JSONCONSUTILITIES_HPP
+
+#include <stdexcept>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <cstdlib>
+#include <cmath>
+#include <cstdarg>
+#include <locale>
+#include <limits>
+#include <type_traits>
+#include <algorithm>
+#include <memory>
+#include <iterator>
+#include <exception>
+#include <array>
+#include <initializer_list>
+#include <jsoncons/jsoncons_config.hpp>
+#include <jsoncons/json_exception.hpp>
+#if !defined(JSONCONS_NO_TO_CHARS)
+#include <charconv>
+#endif
+#include <jsoncons/detail/obufferedstream.hpp>
+
+namespace jsoncons
+{
+
+#if !defined(JSONCONS_HAS_STRING_VIEW)
+template <class CharT, class Traits = std::char_traits<CharT>>
+class Basic_string_view_
+{
+private:
+ const CharT* data_;
+ size_t length_;
+public:
+ typedef CharT value_type;
+ typedef const CharT& const_reference;
+ typedef Traits traits_type;
+ typedef std::size_t size_type;
+ static const size_type npos = size_type(-1);
+ typedef const CharT* const_iterator;
+ typedef const CharT* iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ Basic_string_view_()
+ : data_(nullptr), length_(0)
+ {
+ }
+ Basic_string_view_(const CharT* data, size_t length)
+ : data_(data), length_(length)
+ {
+ }
+ Basic_string_view_(const CharT* data)
+ : data_(data), length_(Traits::length(data))
+ {
+ }
+ Basic_string_view_(const Basic_string_view_& other) = default;
+
+ template <class Allocator>
+ Basic_string_view_(const std::basic_string<CharT,Traits,Allocator>& s)
+ : data_(s.data()), length_(s.length())
+ {
+ }
+
+ template <class Allocator>
+ explicit operator std::basic_string<CharT,Traits,Allocator>() const
+ {
+ return std::basic_string<CharT,Traits>(data_,length_);
+ }
+
+ // iterator support
+ const_iterator begin() const JSONCONS_NOEXCEPT
+ {
+ return data_;
+ }
+ const_iterator end() const JSONCONS_NOEXCEPT
+ {
+ return data_ + length_;
+ }
+ const_iterator cbegin() const JSONCONS_NOEXCEPT
+ {
+ return data_;
+ }
+ const_iterator cend() const JSONCONS_NOEXCEPT
+ {
+ return data_ + length_;
+ }
+ const_reverse_iterator rbegin() const JSONCONS_NOEXCEPT
+ {
+ return const_reverse_iterator(end());
+ }
+ const_reverse_iterator rend() const JSONCONS_NOEXCEPT
+ {
+ return const_reverse_iterator(begin());
+ }
+ const_reverse_iterator crbegin() const JSONCONS_NOEXCEPT
+ {
+ return const_reverse_iterator(end());
+ }
+ const_reverse_iterator crend() const JSONCONS_NOEXCEPT
+ {
+ return const_reverse_iterator(begin());
+ }
+
+ // capacity
+
+ size_t size() const
+ {
+ return length_;
+ }
+
+ size_t length() const
+ {
+ return length_;
+ }
+ size_type max_size() const JSONCONS_NOEXCEPT
+ {
+ return length_;
+ }
+ bool empty() const JSONCONS_NOEXCEPT
+ {
+ return length_ == 0;
+ }
+
+ // element access
+
+ const_reference operator[](size_type pos) const
+ {
+ return data_[pos];
+ }
+
+ const_reference at(size_t pos) const
+ {
+ if (pos >= length_)
+ {
+ JSONCONS_THROW(json_exception_impl<std::out_of_range>("pos exceeds length"));
+ }
+ return data_[pos];
+ }
+
+ const_reference front() const
+ {
+ return data_[0];
+ }
+ const_reference back() const
+ {
+ return data_[length_-1];
+ }
+
+ const CharT* data() const
+ {
+ return data_;
+ }
+
+ // string operations
+
+ Basic_string_view_ substr(size_type pos, size_type n=npos) const
+ {
+ if (pos > length_)
+ {
+ JSONCONS_THROW(json_exception_impl<std::out_of_range>("pos exceeds size"));
+ }
+ if (n == npos || pos + n > length_)
+ {
+ n = length_ - pos;
+ }
+ return Basic_string_view_(data_ + pos, n);
+ }
+
+ int compare(Basic_string_view_ s) const
+ {
+ const int rc = Traits::compare(data_, s.data_, (std::min)(length_, s.length_));
+ return rc != 0 ? rc : (length_ == s.length_ ? 0 : length_ < s.length_ ? -1 : 1);
+ }
+
+ int compare(const CharT* data) const
+ {
+ const size_t length = Traits::length(data);
+ const int rc = Traits::compare(data_, data, (std::min)(length_, length));
+ return rc != 0 ? rc : (length_ == length? 0 : length_ < length? -1 : 1);
+ }
+
+ template <class Allocator>
+ int compare(const std::basic_string<CharT,Traits,Allocator>& s) const
+ {
+ const int rc = Traits::compare(data_, s.data(), (std::min)(length_, s.length()));
+ return rc != 0 ? rc : (length_ == s.length() ? 0 : length_ < s.length() ? -1 : 1);
+ }
+
+ size_type find(Basic_string_view_ s, size_type pos = 0) const JSONCONS_NOEXCEPT
+ {
+ if (pos > length_)
+ {
+ return npos;
+ }
+ if (s.length_ == 0)
+ {
+ return pos;
+ }
+ const_iterator it = std::search(cbegin() + pos, cend(),
+ s.cbegin(), s.cend(), Traits::eq);
+ return it == cend() ? npos : std::distance(cbegin(), it);
+ }
+ size_type find(CharT ch, size_type pos = 0) const JSONCONS_NOEXCEPT
+ {
+ return find(Basic_string_view_(&ch, 1), pos);
+ }
+ size_type find(const CharT* s, size_type pos, size_type n) const JSONCONS_NOEXCEPT
+ {
+ return find(Basic_string_view_(s, n), pos);
+ }
+ size_type find(const CharT* s, size_type pos = 0) const JSONCONS_NOEXCEPT
+ {
+ return find(Basic_string_view_(s), pos);
+ }
+
+ size_type rfind(Basic_string_view_ s, size_type pos = npos) const JSONCONS_NOEXCEPT
+ {
+ if (length_ < s.length_)
+ {
+ return npos;
+ }
+ if (pos > length_ - s.length_)
+ {
+ pos = length_ - s.length_;
+ }
+ if (s.length_ == 0)
+ {
+ return pos;
+ }
+ for (const CharT* p = data_ + pos; true; --p)
+ {
+ if (Traits::compare(p, s.data_, s.length_) == 0)
+ {
+ return p - data_;
+ }
+ if (p == data_)
+ {
+ return npos;
+ }
+ };
+ }
+ size_type rfind(CharT ch, size_type pos = npos) const JSONCONS_NOEXCEPT
+ {
+ return rfind(Basic_string_view_(&ch, 1), pos);
+ }
+ size_type rfind(const CharT* s, size_type pos, size_type n) const JSONCONS_NOEXCEPT
+ {
+ return rfind(Basic_string_view_(s, n), pos);
+ }
+ size_type rfind(const CharT* s, size_type pos = npos) const JSONCONS_NOEXCEPT
+ {
+ return rfind(Basic_string_view_(s), pos);
+ }
+
+ size_type find_first_of(Basic_string_view_ s, size_type pos = 0) const JSONCONS_NOEXCEPT
+ {
+ if (pos >= length_ || s.length_ == 0)
+ {
+ return npos;
+ }
+ const_iterator it = std::find_first_of
+ (cbegin() + pos, cend(), s.cbegin(), s.cend(), Traits::eq);
+ return it == cend() ? npos : std::distance (cbegin(), it);
+ }
+ size_type find_first_of(CharT ch, size_type pos = 0) const JSONCONS_NOEXCEPT
+ {
+ return find_first_of(Basic_string_view_(&ch, 1), pos);
+ }
+ size_type find_first_of(const CharT* s, size_type pos, size_type n) const JSONCONS_NOEXCEPT
+ {
+ return find_first_of(Basic_string_view_(s, n), pos);
+ }
+ size_type find_first_of(const CharT* s, size_type pos = 0) const JSONCONS_NOEXCEPT
+ {
+ return find_first_of(Basic_string_view_(s), pos);
+ }
+
+ size_type find_last_of(Basic_string_view_ s, size_type pos = npos) const JSONCONS_NOEXCEPT
+ {
+ if (s.length_ == 0)
+ {
+ return npos;
+ }
+ if (pos >= length_)
+ {
+ pos = 0;
+ }
+ else
+ {
+ pos = length_ - (pos+1);
+ }
+ const_reverse_iterator it = std::find_first_of
+ (crbegin() + pos, crend(), s.cbegin(), s.cend(), Traits::eq);
+ return it == crend() ? npos : (length_ - 1 - std::distance(crbegin(), it));
+ }
+ size_type find_last_of(CharT ch, size_type pos = npos) const JSONCONS_NOEXCEPT
+ {
+ return find_last_of(Basic_string_view_(&ch, 1), pos);
+ }
+ size_type find_last_of(const CharT* s, size_type pos, size_type n) const JSONCONS_NOEXCEPT
+ {
+ return find_last_of(Basic_string_view_(s, n), pos);
+ }
+ size_type find_last_of(const CharT* s, size_type pos = npos) const JSONCONS_NOEXCEPT
+ {
+ return find_last_of(Basic_string_view_(s), pos);
+ }
+
+ size_type find_first_not_of(Basic_string_view_ s, size_type pos = 0) const JSONCONS_NOEXCEPT
+ {
+ if (pos >= length_)
+ return npos;
+ if (s.length_ == 0)
+ return pos;
+
+ const_iterator it = cend();
+ for (auto p = cbegin()+pos; p != cend(); ++p)
+ {
+ if (Traits::find(s.data_, s.length_, *p) == 0)
+ {
+ it = p;
+ break;
+ }
+ }
+ return it == cend() ? npos : std::distance (cbegin(), it);
+ }
+ size_type find_first_not_of(CharT ch, size_type pos = 0) const JSONCONS_NOEXCEPT
+ {
+ return find_first_not_of(Basic_string_view_(&ch, 1), pos);
+ }
+ size_type find_first_not_of(const CharT* s, size_type pos, size_type n) const JSONCONS_NOEXCEPT
+ {
+ return find_first_not_of(Basic_string_view_(s, n), pos);
+ }
+ size_type find_first_not_of(const CharT* s, size_type pos = 0) const JSONCONS_NOEXCEPT
+ {
+ return find_first_not_of(Basic_string_view_(s), pos);
+ }
+
+ size_type find_last_not_of(Basic_string_view_ s, size_type pos = npos) const JSONCONS_NOEXCEPT
+ {
+ if (pos >= length_)
+ {
+ pos = length_ - 1;
+ }
+ if (s.length_ == 0)
+ {
+ return pos;
+ }
+ pos = length_ - (pos+1);
+
+ const_iterator it = crend();
+ for (auto p = crbegin()+pos; p != crend(); ++p)
+ {
+ if (Traits::find(s.data_, s.length_, *p) == 0)
+ {
+ it = p;
+ break;
+ }
+ }
+ return it == crend() ? npos : (length_ - 1 - std::distance(crbegin(), it));
+ }
+ size_type find_last_not_of(CharT ch, size_type pos = npos) const JSONCONS_NOEXCEPT
+ {
+ return find_last_not_of(Basic_string_view_(&ch, 1), pos);
+ }
+ size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const JSONCONS_NOEXCEPT
+ {
+ return find_last_not_of(Basic_string_view_(s, n), pos);
+ }
+ size_type find_last_not_of(const CharT* s, size_type pos = npos) const JSONCONS_NOEXCEPT
+ {
+ return find_last_not_of(Basic_string_view_(s), pos);
+ }
+
+ friend std::basic_ostream<CharT>& operator<<(std::basic_ostream<CharT>& os, const Basic_string_view_& sv)
+ {
+ os.write(sv.data_,sv.length_);
+ return os;
+ }
+};
+
+// ==
+template<class CharT,class Traits>
+bool operator==(const Basic_string_view_<CharT,Traits>& lhs,
+ const Basic_string_view_<CharT,Traits>& rhs)
+{
+ return lhs.compare(rhs) == 0;
+}
+template<class CharT,class Traits,class Allocator>
+bool operator==(const Basic_string_view_<CharT,Traits>& lhs,
+ const std::basic_string<CharT,Traits,Allocator>& rhs)
+{
+ return lhs.compare(rhs) == 0;
+}
+template<class CharT,class Traits,class Allocator>
+bool operator==(const std::basic_string<CharT,Traits,Allocator>& lhs,
+ const Basic_string_view_<CharT,Traits>& rhs)
+{
+ return rhs.compare(lhs) == 0;
+}
+template<class CharT,class Traits>
+bool operator==(const Basic_string_view_<CharT,Traits>& lhs,
+ const CharT* rhs)
+{
+ return lhs.compare(rhs) == 0;
+}
+template<class CharT,class Traits>
+bool operator==(const CharT* lhs,
+ const Basic_string_view_<CharT,Traits>& rhs)
+{
+ return rhs.compare(lhs) == 0;
+}
+
+// !=
+template<class CharT,class Traits>
+bool operator!=(const Basic_string_view_<CharT,Traits>& lhs,
+ const Basic_string_view_<CharT,Traits>& rhs)
+{
+ return lhs.compare(rhs) != 0;
+}
+template<class CharT,class Traits,class Allocator>
+bool operator!=(const Basic_string_view_<CharT,Traits>& lhs,
+ const std::basic_string<CharT,Traits,Allocator>& rhs)
+{
+ return lhs.compare(rhs) != 0;
+}
+template<class CharT,class Traits,class Allocator>
+bool operator!=(const std::basic_string<CharT,Traits,Allocator>& lhs,
+ const Basic_string_view_<CharT,Traits>& rhs)
+{
+ return rhs.compare(lhs) != 0;
+}
+template<class CharT,class Traits>
+bool operator!=(const Basic_string_view_<CharT,Traits>& lhs,
+ const CharT* rhs)
+{
+ return lhs.compare(rhs) != 0;
+}
+template<class CharT,class Traits>
+bool operator!=(const CharT* lhs,
+ const Basic_string_view_<CharT,Traits>& rhs)
+{
+ return rhs.compare(lhs) != 0;
+}
+
+// <=
+template<class CharT,class Traits>
+bool operator<=(const Basic_string_view_<CharT,Traits>& lhs,
+ const Basic_string_view_<CharT,Traits>& rhs)
+{
+ return lhs.compare(rhs) <= 0;
+}
+template<class CharT,class Traits,class Allocator>
+bool operator<=(const Basic_string_view_<CharT,Traits>& lhs,
+ const std::basic_string<CharT,Traits,Allocator>& rhs)
+{
+ return lhs.compare(rhs) <= 0;
+}
+template<class CharT,class Traits,class Allocator>
+bool operator<=(const std::basic_string<CharT,Traits,Allocator>& lhs,
+ const Basic_string_view_<CharT,Traits>& rhs)
+{
+ return rhs.compare(lhs) >= 0;
+}
+
+// <
+template<class CharT,class Traits>
+bool operator<(const Basic_string_view_<CharT,Traits>& lhs,
+ const Basic_string_view_<CharT,Traits>& rhs)
+{
+ return lhs.compare(rhs) < 0;
+}
+template<class CharT,class Traits,class Allocator>
+bool operator<(const Basic_string_view_<CharT,Traits>& lhs,
+ const std::basic_string<CharT,Traits,Allocator>& rhs)
+{
+ return lhs.compare(rhs) < 0;
+}
+template<class CharT,class Traits,class Allocator>
+bool operator<(const std::basic_string<CharT,Traits,Allocator>& lhs,
+ const Basic_string_view_<CharT,Traits>& rhs)
+{
+ return rhs.compare(lhs) > 0;
+}
+
+// >=
+template<class CharT,class Traits>
+bool operator>=(const Basic_string_view_<CharT,Traits>& lhs,
+ const Basic_string_view_<CharT,Traits>& rhs)
+{
+ return lhs.compare(rhs) >= 0;
+}
+template<class CharT,class Traits,class Allocator>
+bool operator>=(const Basic_string_view_<CharT,Traits>& lhs,
+ const std::basic_string<CharT,Traits,Allocator>& rhs)
+{
+ return lhs.compare(rhs) >= 0;
+}
+template<class CharT,class Traits,class Allocator>
+bool operator>=(const std::basic_string<CharT,Traits,Allocator>& lhs,
+ const Basic_string_view_<CharT,Traits>& rhs)
+{
+ return rhs.compare(lhs) <= 0;
+}
+
+// >
+template<class CharT,class Traits>
+bool operator>(const Basic_string_view_<CharT,Traits>& lhs,
+ const Basic_string_view_<CharT,Traits>& rhs)
+{
+ return lhs.compare(rhs) > 0;
+}
+template<class CharT,class Traits,class Allocator>
+bool operator>(const Basic_string_view_<CharT,Traits>& lhs,
+ const std::basic_string<CharT,Traits,Allocator>& rhs)
+{
+ return lhs.compare(rhs) > 0;
+}
+template<class CharT,class Traits,class Allocator>
+bool operator>(const std::basic_string<CharT,Traits,Allocator>& lhs,
+ const Basic_string_view_<CharT,Traits>& rhs)
+{
+ return rhs.compare(lhs) < 0;
+}
+#endif
+
+#if !defined(JSONCONS_HAS_STRING_VIEW)
+template <class CharT, class Traits = std::char_traits<CharT>>
+using basic_string_view_ext = Basic_string_view_<CharT, Traits>;
+#else
+#include <string_view>
+template <class CharT, class Traits = std::char_traits<CharT>>
+using basic_string_view_ext = std::basic_string_view<CharT, Traits>;
+#endif
+
+#if !defined(JSONCONS_NO_TO_CHARS)
+using chars_format = std::chars_format;
+#else
+enum class chars_format : uint8_t {fixed=1,scientific=2,hex=4,general=fixed|scientific};
+#endif
+
+// number_format
+
+class number_format
+{
+ chars_format format_;
+ uint8_t precision_;
+ uint8_t decimal_places_;
+public:
+ number_format()
+ : format_(chars_format::general), precision_(0), decimal_places_(0)
+ {
+ }
+
+ number_format(uint8_t precision, uint8_t decimal_places)
+ : format_(chars_format::general), precision_(precision), decimal_places_(decimal_places)
+ {
+ }
+
+ number_format(chars_format format, uint8_t precision, uint8_t decimal_places)
+ : format_(format), precision_(precision), decimal_places_(decimal_places)
+ {
+ }
+
+ number_format(chars_format format)
+ : format_(format), precision_(0), decimal_places_(0)
+ {
+ }
+
+ number_format(const number_format&) = default;
+ number_format(number_format&&) = default;
+ number_format& operator=(const number_format& e) = default;
+ number_format& operator=(number_format&& e) = default;
+
+ uint8_t precision() const
+ {
+ return precision_;
+ }
+
+ uint8_t decimal_places() const
+ {
+ return decimal_places_;
+ }
+
+ chars_format floating_point_format() const
+ {
+ return format_;
+ }
+};
+
+// byte_string_view
+class byte_string_view
+{
+ const uint8_t* data_;
+ size_t length_;
+public:
+ typedef const uint8_t* const_iterator;
+ typedef const uint8_t* iterator;
+ typedef std::size_t size_type;
+
+ byte_string_view(const uint8_t* data, size_t length)
+ : data_(data), length_(length)
+ {
+ }
+
+ const uint8_t* data() const
+ {
+ return data_;
+ }
+
+ size_t length() const
+ {
+ return length_;
+ }
+
+ size_t size() const
+ {
+ return length_;
+ }
+
+ // iterator support
+ const_iterator begin() const JSONCONS_NOEXCEPT
+ {
+ return data_;
+ }
+ const_iterator end() const JSONCONS_NOEXCEPT
+ {
+ return data_ + length_;
+ }
+
+ uint8_t operator[](size_type pos) const
+ {
+ return data_[pos];
+ }
+
+ friend bool operator==(const byte_string_view& lhs, const byte_string_view& rhs)
+ {
+ if (lhs.length() != rhs.length())
+ {
+ return false;
+ }
+ for (size_t i = 0; i < lhs.length(); ++i)
+ {
+ if (lhs[i] != rhs[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ friend bool operator!=(const byte_string_view& lhs, const byte_string_view& rhs)
+ {
+ return !(lhs == rhs);
+ }
+
+ template <class CharT>
+ friend std::basic_ostream<CharT>& operator<<(std::basic_ostream<CharT>& os, const byte_string_view& o)
+ {
+ std::basic_ostringstream<CharT> ss;
+ ss.flags(std::ios::hex | std::ios::showbase);
+ for (auto b : o)
+ {
+ ss << (int)b;
+ }
+ os << ss.str();
+ return os;
+ }
+};
+
+// basic_byte_string
+template <class Allocator = std::allocator<uint8_t>>
+class basic_byte_string
+{
+ std::vector<uint8_t,Allocator> data_;
+public:
+ typedef typename std::vector<uint8_t,Allocator>::const_iterator const_iterator;
+ typedef typename std::vector<uint8_t,Allocator>::const_iterator iterator;
+ typedef std::size_t size_type;
+
+ basic_byte_string() = default;
+
+ explicit basic_byte_string(const Allocator& alloc)
+ : data_(alloc)
+ {
+ }
+
+ basic_byte_string(std::initializer_list<uint8_t> init)
+ : data_(std::move(init))
+ {
+ }
+
+ basic_byte_string(std::initializer_list<uint8_t> init, const Allocator& alloc)
+ : data_(std::move(init), alloc)
+ {
+ }
+
+ explicit basic_byte_string(const byte_string_view& v)
+ : data_(v.begin(),v.end())
+ {
+ }
+
+ basic_byte_string(const byte_string_view& v, const Allocator& alloc)
+ : data_(v.begin(),v.end(),alloc)
+ {
+ }
+
+ basic_byte_string(const char* s)
+ {
+ while (*s)
+ {
+ data_.push_back(*s++);
+ }
+ }
+
+ basic_byte_string(const uint8_t* data, size_t length)
+ {
+ data_.insert(data,data+length);
+ }
+
+ basic_byte_string(const basic_byte_string& s) = default;
+
+ basic_byte_string(basic_byte_string&& s) = default;
+
+ basic_byte_string& operator=(const basic_byte_string& s) = default;
+
+ basic_byte_string& operator=(basic_byte_string&& s) = default;
+
+ operator byte_string_view() const JSONCONS_NOEXCEPT
+ {
+ return byte_string_view(data(),length());
+ }
+
+ void push_back(uint8_t b)
+ {
+ data_.push_back(b);
+ }
+
+ void assign(const uint8_t* s, size_t count)
+ {
+ data_.clear();
+ data_.insert(s, s+count);
+ }
+
+ void append(const uint8_t* s, size_t count)
+ {
+ data_.insert(s, s+count);
+ }
+
+ void clear()
+ {
+ data_.clear();
+ }
+
+ uint8_t operator[](size_type pos) const
+ {
+ return data_[pos];
+ }
+
+ // iterator support
+ const_iterator begin() const JSONCONS_NOEXCEPT
+ {
+ return data_.begin();
+ }
+ const_iterator end() const JSONCONS_NOEXCEPT
+ {
+ return data_.end();
+ }
+
+ const uint8_t* data() const
+ {
+ return data_.data();
+ }
+
+ size_t size() const
+ {
+ return data_.size();
+ }
+
+ size_t length() const
+ {
+ return data_.size();
+ }
+
+ friend bool operator==(const basic_byte_string& lhs, const basic_byte_string& rhs)
+ {
+ return byte_string_view(lhs) == byte_string_view(rhs);
+ }
+
+ friend bool operator!=(const basic_byte_string& lhs, const basic_byte_string& rhs)
+ {
+ return byte_string_view(lhs) != byte_string_view(rhs);
+ }
+
+ template <class CharT>
+ friend std::basic_ostream<CharT>& operator<<(std::basic_ostream<CharT>& os, const basic_byte_string& o)
+ {
+ os << byte_string_view(o);
+ return os;
+ }
+};
+
+typedef basic_byte_string<std::allocator<uint8_t>> byte_string;
+
+static const std::string base64_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/"
+ "=";
+static const std::string base64url_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789-_"
+ "\0";
+
+inline
+static bool is_base64(uint8_t c)
+{
+ return isalnum(c) || c == '+' || c == '/';
+}
+
+template <class InputIt,class CharT>
+void encode_base64(InputIt first, InputIt last, const std::string& alphabet, std::basic_string<CharT>& result)
+{
+ unsigned char a3[3];
+ unsigned char a4[4];
+ unsigned char fill = alphabet.back();
+ int i = 0;
+ int j = 0;
+
+ while (first != last)
+ {
+ a3[i++] = *first++;
+ if (i == 3)
+ {
+ a4[0] = (a3[0] & 0xfc) >> 2;
+ a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
+ a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
+ a4[3] = a3[2] & 0x3f;
+
+ for (i = 0; i < 4; i++)
+ {
+ result.push_back(alphabet[a4[i]]);
+ }
+ i = 0;
+ }
+ }
+
+ if (i > 0)
+ {
+ for (j = i; j < 3; ++j)
+ {
+ a3[j] = 0;
+ }
+
+ a4[0] = (a3[0] & 0xfc) >> 2;
+ a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
+ a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
+
+ for (j = 0; j < i + 1; ++j)
+ {
+ result.push_back(alphabet[a4[j]]);
+ }
+
+ if (fill != 0)
+ {
+ while (i++ < 3)
+ {
+ result.push_back(fill);
+ }
+ }
+ }
+}
+
+template <class InputIt,class CharT>
+void encode_base64url(InputIt first, InputIt last, std::basic_string<CharT>& result)
+{
+ return encode_base64(first,last,base64url_alphabet,result);
+}
+
+template <class InputIt,class CharT>
+void encode_base64(InputIt first, InputIt last, std::basic_string<CharT>& result)
+{
+ encode_base64(first,last,base64_alphabet,result);
+}
+
+inline
+std::string decode_base64(const std::string& base64_string)
+{
+ std::string result;
+ uint8_t a4[4], a3[3];
+ uint8_t i = 0;
+ uint8_t j = 0;
+
+ auto first = base64_string.begin();
+ auto last = base64_string.end();
+
+ while (first != last && *first != '=')
+ {
+ JSONCONS_ASSERT(is_base64(*first));
+
+ a4[i++] = *first++;
+ if (i == 4)
+ {
+ for (i = 0; i < 4; ++i)
+ {
+ a4[i] = static_cast<uint8_t>(base64_alphabet.find(a4[i]));
+ }
+
+ a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4);
+ a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2);
+ a3[2] = ((a4[2] & 0x3) << 6) + a4[3];
+
+ for (i = 0; i < 3; i++)
+ {
+ result.push_back(a3[i]);
+ }
+ i = 0;
+ }
+ }
+
+ if (i > 0)
+ {
+ for (j = 0; j < i; ++j)
+ {
+ a4[j] = static_cast<uint8_t>(base64_alphabet.find(a4[j]));
+ }
+
+ a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4);
+ a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2);
+
+ for (j = 0; j < i - 1; ++j)
+ {
+ result.push_back(a3[j]);
+ }
+ }
+
+ return result;
+}
+
+}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/parse_error_handler.hpp b/vendor/jsoncons-0.104.0/jsoncons/parse_error_handler.hpp
new file mode 100644
index 00000000..e38785ae
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/parse_error_handler.hpp
@@ -0,0 +1,165 @@
+/// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_PARSE_ERROR_HANDLER_HPP
+#define JSONCONS_PARSE_ERROR_HANDLER_HPP
+
+#include <jsoncons/json_exception.hpp>
+#include <jsoncons/json_error_category.hpp>
+#include <system_error>
+
+namespace jsoncons {
+
+class parse_error : public std::exception, public virtual json_exception
+{
+public:
+ parse_error()
+ : line_number_(0),
+ column_number_(0)
+ {
+ }
+ parse_error(std::error_code ec,
+ size_t line,
+ size_t column)
+ : error_code_(ec),
+ line_number_(line),
+ column_number_(column)
+ {
+ }
+ parse_error(const parse_error& other)
+ : error_code_(other.error_code_),
+ line_number_(other.line_number_),
+ column_number_(other.column_number_)
+ {
+ }
+
+ const char* what() const JSONCONS_NOEXCEPT override
+ {
+ try
+ {
+ std::ostringstream os;
+ os << error_code_.message() << " at line " << line_number_ << " and column " << column_number_;
+ const_cast<std::string&>(buffer_) = os.str();
+ return buffer_.c_str();
+ }
+ catch (...)
+ {
+ return "";
+ }
+ }
+
+ const std::error_code code() const
+ {
+ return error_code_;
+ }
+
+ size_t line_number() const
+ {
+ return line_number_;
+ }
+
+ size_t column_number() const
+ {
+ return column_number_;
+ }
+
+ parse_error& operator=(const parse_error& e)
+ {
+ error_code_ = e.error_code_;
+ line_number_ = e.line_number_;
+ column_number_ = e.column_number_;
+ return *this;
+ }
+private:
+ std::error_code error_code_;
+ std::string buffer_;
+ size_t line_number_;
+ size_t column_number_;
+};
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+typedef parse_error json_parse_exception;
+typedef parse_error parse_exception;
+#endif
+
+class parsing_context
+{
+public:
+ virtual ~parsing_context() = default;
+
+ size_t line_number() const
+ {
+ return do_line_number();
+ }
+ size_t column_number() const
+ {
+ return do_column_number();
+ }
+
+private:
+ virtual size_t do_line_number() const = 0;
+ virtual size_t do_column_number() const = 0;
+};
+
+class parse_error_handler
+{
+public:
+ virtual ~parse_error_handler()
+ {
+ }
+
+ bool error(std::error_code ec,
+ const parsing_context& context) JSONCONS_NOEXCEPT
+ {
+ return do_error(ec,context);
+ }
+
+ void fatal_error(std::error_code ec,
+ const parsing_context& context) JSONCONS_NOEXCEPT
+ {
+ do_fatal_error(ec,context);
+ }
+
+private:
+ virtual bool do_error(std::error_code,
+ const parsing_context& context) JSONCONS_NOEXCEPT = 0;
+
+ virtual void do_fatal_error(std::error_code,
+ const parsing_context&) JSONCONS_NOEXCEPT
+ {
+ }
+};
+
+class default_parse_error_handler : public parse_error_handler
+{
+private:
+ bool do_error(std::error_code code,
+ const parsing_context&) JSONCONS_NOEXCEPT override
+ {
+ static const std::error_code illegal_comment = make_error_code(json_parser_errc::illegal_comment);
+
+ if (code == illegal_comment)
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+};
+
+class strict_parse_error_handler : public parse_error_handler
+{
+private:
+ bool do_error(std::error_code, const parsing_context&) JSONCONS_NOEXCEPT override
+ {
+ return true;
+ }
+};
+
+}
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/serialization_options.hpp b/vendor/jsoncons-0.104.0/jsoncons/serialization_options.hpp
new file mode 100644
index 00000000..18be2ce3
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/serialization_options.hpp
@@ -0,0 +1,279 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_SERIALIZATION_OPTIONS_HPP
+#define JSONCONS_SERIALIZATION_OPTIONS_HPP
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <ostream>
+#include <cstdlib>
+#include <limits>
+#include <cwchar>
+#include <jsoncons/json_exception.hpp>
+#include <jsoncons/jsoncons_utilities.hpp>
+#include <jsoncons/detail/type_traits_helper.hpp>
+
+namespace jsoncons {
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+enum class block_options {next_line,same_line};
+#endif
+
+enum class line_split_kind{same_line,new_line,multi_line};
+
+template <class CharT,class Allocator=std::allocator<CharT>>
+class basic_serialization_options
+{
+public:
+ typedef basic_string_view_ext<CharT> string_view_type;
+ typedef CharT char_type;
+ typedef Allocator allocator_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<CharT> char_allocator_type;
+ typedef std::basic_string<CharT,std::char_traits<CharT>,char_allocator_type> string_type;
+private:
+ int indent_;
+ uint8_t precision_;
+ uint8_t decimal_places_;
+ bool replace_nan_;
+ bool replace_pos_inf_;
+ bool replace_neg_inf_;
+ string_type nan_replacement_;
+ string_type pos_inf_replacement_;
+ string_type neg_inf_replacement_;
+ bool escape_all_non_ascii_;
+ bool escape_solidus_;
+
+ line_split_kind object_object_split_lines_;
+ line_split_kind object_array_split_lines_;
+ line_split_kind array_array_split_lines_;
+ line_split_kind array_object_split_lines_;
+
+ chars_format floating_point_format_;
+public:
+ static const size_t default_indent = 4;
+
+// Constructors
+
+ basic_serialization_options()
+ :
+ indent_(default_indent),
+ precision_(0),
+ replace_nan_(true),
+ replace_pos_inf_(true),
+ replace_neg_inf_(true),
+ nan_replacement_(detail::null_literal<CharT>()),
+ pos_inf_replacement_(detail::null_literal<CharT>()),
+ neg_inf_replacement_(detail::null_literal<CharT>()),
+ escape_all_non_ascii_(false),
+ escape_solidus_(false),
+ object_object_split_lines_(line_split_kind::multi_line),
+ object_array_split_lines_(line_split_kind::same_line),
+ array_array_split_lines_(line_split_kind::new_line),
+ array_object_split_lines_(line_split_kind::multi_line)
+ {
+ }
+
+// Accessors
+ line_split_kind object_object_split_lines() const {return object_object_split_lines_;}
+ line_split_kind array_object_split_lines() const {return array_object_split_lines_;}
+ line_split_kind object_array_split_lines() const {return object_array_split_lines_;}
+ line_split_kind array_array_split_lines() const {return array_array_split_lines_;}
+
+ basic_serialization_options<CharT>& object_object_split_lines(line_split_kind value) {object_object_split_lines_ = value; return *this;}
+ basic_serialization_options<CharT>& array_object_split_lines(line_split_kind value) {array_object_split_lines_ = value; return *this;}
+ basic_serialization_options<CharT>& object_array_split_lines(line_split_kind value) {object_array_split_lines_ = value; return *this;}
+ basic_serialization_options<CharT>& array_array_split_lines(line_split_kind value) {array_array_split_lines_ = value; return *this;}
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+ block_options array_array_block_option()
+ {
+ return (array_array_split_lines_ == line_split_kind::same_line) ? block_options::same_line : block_options::next_line;
+ }
+
+ basic_serialization_options<CharT>& array_array_block_option(block_options value)
+ {
+ array_array_split_lines_ = (value == block_options::same_line) ? line_split_kind::same_line : line_split_kind::new_line;
+ return *this;
+ }
+
+ block_options array_object_block_option()
+ {
+ return (array_object_split_lines_ == line_split_kind::same_line) ? block_options::same_line : block_options::next_line;
+ }
+
+ basic_serialization_options<CharT>& array_object_block_option(block_options value)
+ {
+ array_object_split_lines_ = (value == block_options::same_line) ? line_split_kind::same_line : line_split_kind::new_line;
+ return *this;
+ }
+
+ block_options object_array_block_option()
+ {
+ return (object_array_split_lines_ == line_split_kind::same_line) ? block_options::same_line : block_options::next_line;
+ }
+
+ basic_serialization_options<CharT>& object_array_block_option(block_options value)
+ {
+ object_array_split_lines_ = (value == block_options::same_line) ? line_split_kind::same_line : line_split_kind::new_line;
+ return *this;
+ }
+
+ block_options object_object_block_option()
+ {
+ return (object_object_split_lines_ == line_split_kind::same_line) ? block_options::same_line : block_options::next_line;
+ }
+
+ basic_serialization_options<CharT>& object_object_block_option(block_options value)
+ {
+ object_object_split_lines_ = (value == block_options::same_line) ? line_split_kind::same_line : line_split_kind::new_line;
+ return *this;
+ }
+#endif
+
+ int indent() const
+ {
+ return indent_;
+ }
+
+ basic_serialization_options<CharT>& indent(int value)
+ {
+ indent_ = value;
+ return *this;
+ }
+
+ chars_format floating_point_format() const
+ {
+ return floating_point_format_;
+ }
+
+ basic_serialization_options<CharT>& floating_point_format(chars_format value)
+ {
+ floating_point_format_ = value;
+ return *this;
+ }
+
+ uint8_t precision() const
+ {
+ return precision_;
+ }
+
+ basic_serialization_options<CharT>& precision(uint8_t value)
+ {
+ precision_ = value;
+ return *this;
+ }
+
+ uint8_t decimal_places() const
+ {
+ return decimal_places_;
+ }
+
+ basic_serialization_options<CharT>& decimal_places(uint8_t value)
+ {
+ decimal_places_ = value;
+ return *this;
+ }
+
+ bool escape_all_non_ascii() const
+ {
+ return escape_all_non_ascii_;
+ }
+
+ basic_serialization_options<CharT>& escape_all_non_ascii(bool value)
+ {
+ escape_all_non_ascii_ = value;
+ return *this;
+ }
+
+ bool escape_solidus() const
+ {
+ return escape_solidus_;
+ }
+
+ basic_serialization_options<CharT>& escape_solidus(bool value)
+ {
+ escape_solidus_ = value;
+ return *this;
+ }
+
+ bool replace_nan() const {return replace_nan_;}
+
+ basic_serialization_options<CharT>& replace_nan(bool replace)
+ {
+ replace_nan_ = replace;
+ return *this;
+ }
+
+ bool replace_pos_inf() const {return replace_pos_inf_;}
+
+ bool replace_neg_inf() const {return replace_neg_inf_;}
+
+ basic_serialization_options<CharT>& replace_inf(bool replace)
+ {
+ replace_pos_inf_ = replace;
+ replace_neg_inf_ = replace;
+ return *this;
+ }
+
+ basic_serialization_options<CharT>& replace_pos_inf(bool replace)
+ {
+ replace_pos_inf_ = replace;
+ return *this;
+ }
+
+ basic_serialization_options<CharT>& replace_neg_inf(bool replace)
+ {
+ replace_neg_inf_ = replace;
+ return *this;
+ }
+
+ const string_type& nan_replacement() const
+ {
+ return nan_replacement_;
+ }
+
+ basic_serialization_options<CharT>& nan_replacement(const string_type& replacement)
+ {
+ nan_replacement_ = replacement;
+ return *this;
+ }
+
+ basic_serialization_options<CharT>& neg_inf_replacement(const string_type& replacement)
+ {
+ neg_inf_replacement_ = replacement;
+ return *this;
+ }
+
+ const string_type& pos_inf_replacement() const
+ {
+ return pos_inf_replacement_;
+ }
+
+ basic_serialization_options<CharT>& pos_inf_replacement(const string_type& replacement)
+ {
+ pos_inf_replacement_ = replacement;
+ return *this;
+ }
+
+ const string_type& neg_inf_replacement() const
+ {
+ return neg_inf_replacement_;
+ }
+};
+
+typedef basic_serialization_options<char> serialization_options;
+typedef basic_serialization_options<wchar_t> wserialization_options;
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+typedef basic_serialization_options<char> output_format;
+typedef basic_serialization_options<wchar_t> woutput_format;
+#endif
+
+}
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons/serialization_traits.hpp b/vendor/jsoncons-0.104.0/jsoncons/serialization_traits.hpp
new file mode 100644
index 00000000..aa22769f
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/serialization_traits.hpp
@@ -0,0 +1,315 @@
+// Copyright 2017 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_SERIALIZATION_TRAITS_HPP
+#define JSONCONS_SERIALIZATION_TRAITS_HPP
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wswitch"
+#endif
+
+#include <iostream>
+#include <string>
+#include <tuple>
+#include <array>
+#include <type_traits>
+#include <memory>
+#include <jsoncons/json_output_handler.hpp>
+#include <jsoncons/serialization_options.hpp>
+#include <jsoncons/json_serializer.hpp>
+#include <jsoncons/jsoncons_utilities.hpp>
+
+namespace jsoncons {
+
+// serialization_traits
+
+template <class T, class Enable = void>
+struct serialization_traits
+{
+ template <class CharT>
+ static void encode(const T&, basic_json_output_handler<CharT>&)
+ {
+ }
+};
+
+// dump
+
+template <class CharT, class T>
+void dump(const T& val, basic_json_output_handler<CharT>& handler)
+{
+ handler.begin_json();
+ serialization_traits<T>::encode(val,handler);
+ handler.end_json();
+}
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+template <class CharT, class T>
+void dump_body(const T& val, basic_json_output_handler<CharT>& handler)
+{
+ dump_fragment(val,handler);
+}
+#endif
+
+template <class CharT, class T>
+void dump_fragment(const T& val, basic_json_output_handler<CharT>& handler)
+{
+ serialization_traits<T>::encode(val,handler);
+}
+
+template <class CharT, class T>
+void dump(const T& val, std::basic_ostream<CharT>& os)
+{
+ basic_json_serializer<CharT> serializer(os);
+ dump(val, serializer);
+}
+
+template <class CharT, class T>
+void dump(const T& val, const basic_serialization_options<CharT>& options,
+ std::basic_ostream<CharT>& os)
+{
+ basic_json_serializer<CharT> serializer(os, options);
+ dump(val, serializer);
+}
+
+template <class CharT, class T>
+void dump(const T& val, std::basic_ostream<CharT>& os, bool pprint)
+{
+ basic_json_serializer<CharT> serializer(os, pprint);
+ dump(val, serializer);
+}
+
+template <class CharT, class T>
+void dump(const T& val, const basic_serialization_options<CharT>& options,
+ std::basic_ostream<CharT>& os, bool pprint)
+{
+ basic_json_serializer<CharT> serializer(os, options, pprint);
+ dump(val, serializer);
+}
+
+// integer
+
+template<class T>
+struct serialization_traits<T,
+ typename std::enable_if<detail::is_integer_like<T>::value
+>::type>
+{
+ template <class CharT>
+ static void encode(T val, basic_json_output_handler<CharT>& handler)
+ {
+ handler.integer_value(val);
+ }
+};
+
+// uinteger
+
+template<class T>
+struct serialization_traits<T,
+ typename std::enable_if<detail::is_uinteger_like<T>::value
+>::type>
+{
+ template <class CharT>
+ static void encode(T val, basic_json_output_handler<CharT>& handler)
+ {
+ handler.uinteger_value(val);
+ }
+};
+
+// double
+
+template<class T>
+struct serialization_traits<T,
+ typename std::enable_if<detail::is_floating_point_like<T>::value
+>::type>
+{
+ template <class CharT>
+ static void encode(T val, basic_json_output_handler<CharT>& handler)
+ {
+ handler.double_value(val);
+ }
+};
+
+// bool
+
+template<>
+struct serialization_traits<bool>
+{
+ template <class CharT>
+ static void encode(bool val, basic_json_output_handler<CharT>& handler)
+ {
+ handler.bool_value(val);
+ }
+};
+
+// string
+
+template<class T>
+struct serialization_traits<T,
+ typename std::enable_if<detail::is_string_like<T>::value
+>::type>
+{
+ template <class CharT>
+ static void encode(const T& val, basic_json_output_handler<CharT>& handler)
+ {
+ handler.string_value(val);
+ }
+};
+
+/*template<>
+struct serialization_traits<typename type_wrapper<CharT>::const_pointer_type>
+{
+ template <class CharT>
+ static void encode(typename type_wrapper<CharT>::const_pointer_type val, basic_json_output_handler<CharT>& handler)
+ {
+ handler.string_value(val);
+ }
+};*/
+
+// sequence container (except string and array)
+
+template<class T>
+struct serialization_traits<T,
+ typename std::enable_if<detail::is_vector_like<T>::value
+>::type>
+{
+ typedef typename std::iterator_traits<typename T::iterator>::value_type value_type;
+
+ template <class CharT>
+ static void encode(const T& val, basic_json_output_handler<CharT>& handler)
+ {
+ handler.begin_array();
+ for (auto it = std::begin(val); it != std::end(val); ++it)
+ {
+ serialization_traits<value_type>::encode(*it,handler);
+ }
+ handler.end_array();
+ }
+};
+
+// std::array
+
+template<class T, size_t N>
+struct serialization_traits<std::array<T,N>>
+{
+ typedef typename std::array<T,N>::value_type value_type;
+public:
+
+ template <class CharT>
+ static void encode(const std::array<T, N>& val, basic_json_output_handler<CharT>& handler)
+ {
+ handler.begin_array();
+ for (auto it = std::begin(val); it != std::end(val); ++it)
+ {
+ serialization_traits<value_type>::encode(*it,handler);
+ }
+ handler.end_array();
+ }
+};
+
+// associative container
+
+template<class T>
+struct serialization_traits<T,
+ typename std::enable_if<detail::is_map_like<T>::value
+>::type>
+{
+ typedef typename T::mapped_type mapped_type;
+ typedef typename T::value_type value_type;
+
+ template <class CharT>
+ static void encode(const T& val, basic_json_output_handler<CharT>& handler)
+ {
+ handler.begin_object();
+ for (auto it = std::begin(val); it != std::end(val); ++it)
+ {
+ handler.name(it->first);
+ serialization_traits<mapped_type>::encode(it->second,handler);
+ }
+ handler.end_object();
+ }
+};
+
+namespace detail { namespace streaming {
+
+template<size_t Pos, class Tuple>
+struct tuple_helper
+{
+ using element_type = typename std::tuple_element<std::tuple_size<Tuple>::value - Pos, Tuple>::type;
+ using next = tuple_helper<Pos - 1, Tuple>;
+
+ template <class CharT>
+ static void encode(const Tuple& tuple, basic_json_output_handler<CharT>& handler)
+ {
+ serialization_traits<element_type>::encode(std::get<std::tuple_size<Tuple>::value - Pos>(tuple),handler);
+ next::encode(tuple, handler);
+ }
+};
+
+template<class Tuple>
+struct tuple_helper<0, Tuple>
+{
+ template <class CharT>
+ static void encode(const Tuple&, basic_json_output_handler<CharT>&)
+ {
+ }
+};
+
+}}
+
+template<typename... E>
+struct serialization_traits<std::tuple<E...>>
+{
+private:
+ using helper = detail::streaming::tuple_helper<sizeof...(E), std::tuple<E...>>;
+
+public:
+ template <class CharT>
+ static void encode(const std::tuple<E...>& value, basic_json_output_handler<CharT>& handler)
+ {
+ handler.begin_array();
+ helper::encode(value, handler);
+ handler.end_array();
+ }
+};
+
+template<class T1, class T2>
+struct serialization_traits<std::pair<T1,T2>>
+{
+public:
+
+ template <class CharT>
+ static void encode(const std::pair<T1,T2>& value, basic_json_output_handler<CharT>& handler)
+ {
+ handler.begin_array();
+ serialization_traits<T1>::encode(value.first, handler);
+ serialization_traits<T2>::encode(value.second, handler);
+ handler.end_array();
+ }
+};
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+template<class T>
+struct serialization_traits<std::shared_ptr<T>>
+{
+public:
+
+ template <class CharT>
+ static void encode(std::shared_ptr<T> p, basic_json_output_handler<CharT>& handler)
+ {
+ serialization_traits<T>::encode(*p, handler);
+ }
+};
+#endif
+
+}
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+#endif
+
+
diff --git a/vendor/jsoncons-0.104.0/jsoncons/version.hpp b/vendor/jsoncons-0.104.0/jsoncons/version.hpp
new file mode 100644
index 00000000..c7971685
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons/version.hpp
@@ -0,0 +1,50 @@
+// Copyright 2017 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_VERSION_HPP
+#define JSONCONS_VERSION_HPP
+
+#include <iostream>
+
+namespace jsoncons {
+
+struct versioning_info
+{
+ versioning_info(unsigned int major,
+ unsigned int minor,
+ unsigned int patch)
+ : major_(major),
+ minor_(minor),
+ patch_(patch)
+ {}
+
+ unsigned int const major_;
+ unsigned int const minor_;
+ unsigned int const patch_;
+
+ friend std::ostream& operator<<(std::ostream& os, const versioning_info& ver)
+ {
+ os << ver.major_ << '.'
+ << ver.minor_ << '.'
+ << ver.patch_;
+ return os;
+ }
+
+ versioning_info(const versioning_info&) = default;
+ versioning_info() = delete;
+ versioning_info& operator=(const versioning_info&) = delete;
+};
+
+inline
+versioning_info version()
+{
+ static versioning_info ver(0, 104, 0);
+ return ver;
+}
+
+}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons_ext/binary/binary_utilities.hpp b/vendor/jsoncons-0.104.0/jsoncons_ext/binary/binary_utilities.hpp
new file mode 100644
index 00000000..4d350e06
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons_ext/binary/binary_utilities.hpp
@@ -0,0 +1,354 @@
+// Copyright 2017 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_BINARY_BINARY_UTILITIES_HPP
+#define JSONCONS_BINARY_BINARY_UTILITIES_HPP
+
+#include <assert.h>
+#include <cfloat>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <istream>
+#include <limits>
+#include <memory>
+#include <sstream>
+#include <vector>
+
+// The definitions below follow the definitions in compiler_support_p.h, https://github.com/01org/tinycbor
+// MIT license
+
+#ifdef __F16C__
+# include <immintrin.h>
+#endif
+
+#ifndef __has_builtin
+# define __has_builtin(x) 0
+#endif
+
+#if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) || \
+ (__has_builtin(__builtin_bswap64) && __has_builtin(__builtin_bswap32))
+# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+# define JSONCONS_BINARY_TO_BE64 __builtin_bswap64
+# define JSONCONS_BINARY_FROM_BE64 __builtin_bswap64
+# define JSONCONS_BINARY_TO_BE32 __builtin_bswap32
+# define JSONCONS_BINARY_FROM_BE32 __builtin_bswap32
+# ifdef __INTEL_COMPILER
+# define JSONCONS_BINARY_TO_BE16 _bswap16
+# define JSONCONS_BINARY_FROM_BE16 _bswap16
+# elif (__GNUC__ * 100 + __GNUC_MINOR__ >= 608) || __has_builtin(__builtin_bswap16)
+# define JSONCONS_BINARY_TO_BE16 __builtin_bswap16
+# define JSONCONS_BINARY_FROM_BE16 __builtin_bswap16
+# else
+# define JSONCONS_BINARY_TO_BE16(x) (((uint16_t)x >> 8) | ((uint16_t)x << 8))
+# define JSONCONS_BINARY_FROM_BE16 JSONCONS_BINARY_TO_BE16
+# endif
+# else
+# define JSONCONS_BINARY_TO_BE64
+# define JSONCONS_BINARY_FROM_BE64
+# define JSONCONS_BINARY_TO_BE32
+# define JSONCONS_BINARY_FROM_BE32
+# define JSONCONS_BINARY_TO_BE16
+# define JSONCONS_BINARY_FROM_BE16
+# endif
+#elif defined(__sun)
+# include <sys/byteorder.h>
+#elif defined(_MSC_VER)
+/* MSVC, which implies Windows, which implies little-endian and sizeof(long) == 4 */
+# define JSONCONS_BINARY_TO_BE64 _byteswap_uint64
+# define JSONCONS_BINARY_FROM_BE64 _byteswap_uint64
+# define JSONCONS_BINARY_TO_BE32 _byteswap_ulong
+# define JSONCONS_BINARY_FROM_BE32 _byteswap_ulong
+# define JSONCONS_BINARY_TO_BE16 _byteswap_ushort
+# define JSONCONS_BINARY_FROM_BE16 _byteswap_ushort
+#endif
+#ifndef JSONCONS_BINARY_TO_BE16
+# include <arpa/inet.h>
+# define JSONCONS_BINARY_TO_BE16 ntohs
+# define JSONCONS_BINARY_FROM_BE16 htons
+#endif
+#ifndef JSONCONS_BINARY_TO_BE32
+# include <arpa/inet.h>
+# define JSONCONS_BINARY_TO_BE32 ntohl
+# define JSONCONS_BINARY_FROM_BE32 htonl
+#endif
+#ifndef JSONCONS_BINARY_TO_BE64
+# define JSONCONS_BINARY_TO_BE64 ntohll
+# define JSONCONS_BINARY_FROM_BE64 htonll
+/* ntohll isn't usually defined */
+# ifndef ntohll
+# if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+# define ntohll
+# define htonll
+# elif defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+# define ntohll(x) ((ntohl((uint32_t)(x)) * UINT64_C(0x100000000)) + (ntohl((x) >> 32)))
+# define htonll ntohll
+# else
+# error "Unable to determine byte order!"
+# endif
+# endif
+#endif
+
+namespace jsoncons { namespace binary {
+
+class read_nbytes_failed : public std::invalid_argument, public virtual json_exception
+{
+public:
+ explicit read_nbytes_failed(size_t count) JSONCONS_NOEXCEPT
+ : std::invalid_argument("")
+ {
+ buffer_.append("Failed attempting to read ");
+ buffer_.append(std::to_string(count));
+ buffer_.append(" bytes from vector");
+ }
+ ~read_nbytes_failed() JSONCONS_NOEXCEPT
+ {
+ }
+ const char* what() const JSONCONS_NOEXCEPT override
+ {
+ return buffer_.c_str();
+ }
+private:
+ std::string buffer_;
+};
+
+namespace detail {
+
+static inline bool add_check_overflow(size_t v1, size_t v2, size_t *r)
+{
+#if ((defined(__GNUC__) && (__GNUC__ >= 5)) && !defined(__INTEL_COMPILER)) || __has_builtin(__builtin_add_overflow)
+ return __builtin_add_overflow(v1, v2, r);
+#else
+ /* unsigned additions are well-defined */
+ *r = v1 + v2;
+ return v1 > v1 + v2;
+#endif
+}
+
+}
+
+inline
+uint16_t encode_half(double val)
+{
+#ifdef __F16C__
+ return _cvtss_sh(val, 3);
+#else
+ uint64_t v;
+ memcpy(&v, &val, sizeof(v));
+ int sign = v >> 63 << 15;
+ int exp = (v >> 52) & 0x7ff;
+ int mant = v << 12 >> 12 >> (53-11); /* keep only the 11 most significant bits of the mantissa */
+ exp -= 1023;
+ if (exp == 1024) {
+ /* infinity or NaN */
+ exp = 16;
+ mant >>= 1;
+ } else if (exp >= 16) {
+ /* overflow, as largest number */
+ exp = 15;
+ mant = 1023;
+ } else if (exp >= -14) {
+ /* regular normal */
+ } else if (exp >= -24) {
+ /* subnormal */
+ mant |= 1024;
+ mant >>= -(exp + 14);
+ exp = -15;
+ } else {
+ /* underflow, make zero */
+ return 0;
+ }
+
+ /* safe cast here as bit operations above guarantee not to overflow */
+ return (uint16_t)(sign | ((exp + 15) << 10) | mant);
+#endif
+}
+
+/* this function was copied & adapted from RFC 7049 Appendix D */
+inline
+double decode_half(uint16_t half)
+{
+#ifdef __F16C__
+ return _cvtsh_ss(half);
+#else
+ int exp = (half >> 10) & 0x1f;
+ int mant = half & 0x3ff;
+ double val;
+ if (exp == 0)
+ {
+ val = ldexp(mant, -24);
+ }
+ else if (exp != 31)
+ {
+ val = ldexp(mant + 1024, exp - 25);
+ }
+ else
+ {
+ val = mant == 0 ? INFINITY : NAN;
+ }
+ return half & 0x8000 ? -val : val;
+#endif
+}
+
+// to_big_endian
+
+template<typename T>
+typename std::enable_if<std::is_integral<T>::value && sizeof(T) == sizeof(uint8_t),void>::type
+to_big_endian(T val, std::vector<uint8_t>& v)
+{
+ v.push_back(static_cast<uint8_t>((val) & 0xff));
+}
+
+template<typename T>
+typename std::enable_if<std::is_integral<T>::value &&
+sizeof(T) == sizeof(uint16_t),void>::type
+to_big_endian(T val, std::vector<uint8_t>& v)
+{
+ T x = JSONCONS_BINARY_FROM_BE16(val);
+
+ uint8_t where[sizeof(T)];
+ memcpy(where, &x, sizeof(T));
+
+ for (auto e : where)
+ {
+ v.push_back(e);
+ }
+}
+
+template<typename T>
+typename std::enable_if<std::is_integral<T>::value &&
+sizeof(T) == sizeof(uint32_t),void>::type
+to_big_endian(T val, std::vector<uint8_t>& v)
+{
+ T x = JSONCONS_BINARY_FROM_BE32(val);
+
+ uint8_t where[sizeof(T)];
+ memcpy(where, &x, sizeof(T));
+
+ for (auto e : where)
+ {
+ v.push_back(e);
+ }
+}
+
+template<typename T>
+typename std::enable_if<std::is_integral<T>::value &&
+sizeof(T) == sizeof(uint64_t),void>::type
+to_big_endian(T val, std::vector<uint8_t>& v)
+{
+ T x = JSONCONS_BINARY_FROM_BE64(val);
+
+ uint8_t where[sizeof(T)];
+ memcpy(where, &x, sizeof(T));
+
+ for (auto e : where)
+ {
+ v.push_back(e);
+ }
+}
+
+inline
+void to_big_endian(float val, std::vector<uint8_t>& v)
+{
+ to_big_endian(*reinterpret_cast<uint32_t*>(&val), v);
+}
+
+inline
+void to_big_endian(double val, std::vector<uint8_t>& v)
+{
+ to_big_endian(*reinterpret_cast<uint64_t*>(&val), v);
+}
+
+// from_big_endian
+
+template<class T>
+typename std::enable_if<std::is_integral<T>::value &&
+sizeof(T) == sizeof(uint8_t),T>::type
+from_big_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp)
+{
+ if (first + sizeof(T) > last)
+ {
+ *endp = first;
+ return 0;
+ }
+ else
+ {
+ *endp = first + sizeof(T);
+ return static_cast<T>(*(first));
+ }
+}
+
+template<class T>
+typename std::enable_if<std::is_integral<T>::value &&
+sizeof(T) == sizeof(uint16_t),T>::type
+from_big_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp)
+{
+ if (first + sizeof(T) > last)
+ {
+ *endp = first;
+ return 0;
+ }
+ else
+ {
+ *endp = first + sizeof(T);
+ return JSONCONS_BINARY_TO_BE16(*reinterpret_cast<const uint16_t*>(first));
+ }
+}
+
+template<class T>
+typename std::enable_if<std::is_integral<T>::value && sizeof(T) == sizeof(uint32_t),T>::type
+from_big_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp)
+{
+ if (first + sizeof(T) > last)
+ {
+ *endp = first;
+ return 0;
+ }
+ else
+ {
+ *endp = first + sizeof(T);
+ return JSONCONS_BINARY_TO_BE32(*reinterpret_cast<const uint32_t*>(first));
+ }
+}
+
+template<class T>
+typename std::enable_if<std::is_integral<T>::value && sizeof(T) == sizeof(uint64_t),T>::type
+from_big_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp)
+{
+ if (first + sizeof(T) > last)
+ {
+ *endp = first;
+ return 0;
+ }
+ else
+ {
+ *endp = first + sizeof(T);
+ return JSONCONS_BINARY_TO_BE64(*reinterpret_cast<const uint64_t*>(first));
+ }
+}
+
+template<class T>
+typename std::enable_if<std::is_floating_point<T>::value &&
+sizeof(T) == sizeof(uint32_t),T>::type
+from_big_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp)
+{
+ uint32_t data = from_big_endian<uint32_t>(first,last,endp);
+ return *reinterpret_cast<T*>(&data);
+}
+
+template<class T>
+typename std::enable_if<std::is_floating_point<T>::value &&
+sizeof(T) == sizeof(uint64_t),T>::type
+from_big_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp)
+{
+ uint64_t data = from_big_endian<uint64_t>(first,last,endp);
+ return *reinterpret_cast<T*>(&data);
+}
+
+}}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons_ext/cbor/cbor.hpp b/vendor/jsoncons-0.104.0/jsoncons_ext/cbor/cbor.hpp
new file mode 100644
index 00000000..73f0cbcd
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons_ext/cbor/cbor.hpp
@@ -0,0 +1,2792 @@
+// Copyright 2017 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_CBOR_CBOR_HPP
+#define JSONCONS_CBOR_CBOR_HPP
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <cstdlib>
+#include <memory>
+#include <limits>
+#include <cassert>
+#include <iterator>
+#include <jsoncons/json.hpp>
+#include <jsoncons_ext/binary/binary_utilities.hpp>
+
+// Positive integer 0x00..0x17 (0..23)
+#define JSONCONS_CBOR_0x00_0x17 \
+ 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06:case 0x07:case 0x08:case 0x09:case 0x0a:case 0x0b:case 0x0c:case 0x0d:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12:case 0x13:case 0x14:case 0x15:case 0x16:case 0x17
+
+// Negative integer -1-0x00..-1-0x17 (-1..-24)
+#define JSONCONS_CBOR_0x20_0x37 \
+ 0x20:case 0x21:case 0x22:case 0x23:case 0x24:case 0x25:case 0x26:case 0x27:case 0x28:case 0x29:case 0x2a:case 0x2b:case 0x2c:case 0x2d:case 0x2e:case 0x2f:case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36:case 0x37
+
+// byte string (0x00..0x17 bytes follow)
+#define JSONCONS_CBOR_0x40_0x57 \
+ 0x40:case 0x41:case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:case 0x47:case 0x48:case 0x49:case 0x4a:case 0x4b:case 0x4c:case 0x4d:case 0x4e:case 0x4f:case 0x50:case 0x51:case 0x52:case 0x53:case 0x54:case 0x55:case 0x56:case 0x57
+
+// UTF-8 string (0x00..0x17 bytes follow)
+#define JSONCONS_CBOR_0x60_0x77 \
+ 0x60:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:case 0x67:case 0x68:case 0x69:case 0x6a:case 0x6b:case 0x6c:case 0x6d:case 0x6e:case 0x6f:case 0x70:case 0x71:case 0x72:case 0x73:case 0x74:case 0x75:case 0x76:case 0x77
+
+// array (0x00..0x17 data items follow)
+#define JSONCONS_CBOR_0x80_0x97 \
+ 0x80:case 0x81:case 0x82:case 0x83:case 0x84:case 0x85:case 0x86:case 0x87:case 0x88:case 0x89:case 0x8a:case 0x8b:case 0x8c:case 0x8d:case 0x8e:case 0x8f:case 0x90:case 0x91:case 0x92:case 0x93:case 0x94:case 0x95:case 0x96:case 0x97
+
+// map (0x00..0x17 pairs of data items follow)
+#define JSONCONS_CBOR_0xa0_0xb7 \
+ 0xa0:case 0xa1:case 0xa2:case 0xa3:case 0xa4:case 0xa5:case 0xa6:case 0xa7:case 0xa8:case 0xa9:case 0xaa:case 0xab:case 0xac:case 0xad:case 0xae:case 0xaf:case 0xb0:case 0xb1:case 0xb2:case 0xb3:case 0xb4:case 0xb5:case 0xb6:case 0xb7
+
+namespace jsoncons { namespace cbor {
+
+class cbor_decode_error : public std::invalid_argument, public virtual json_exception
+{
+public:
+ explicit cbor_decode_error(size_t pos) JSONCONS_NOEXCEPT
+ : std::invalid_argument("")
+ {
+ buffer_.append("Error decoding a cbor at position ");
+ buffer_.append(std::to_string(pos));
+ }
+ ~cbor_decode_error() JSONCONS_NOEXCEPT
+ {
+ }
+ const char* what() const JSONCONS_NOEXCEPT override
+ {
+ return buffer_.c_str();
+ }
+private:
+ std::string buffer_;
+};
+
+namespace detail {
+
+void walk(const uint8_t* first, const uint8_t* last, const uint8_t** endp);
+
+inline
+size_t get_byte_string_length(const uint8_t* first, const uint8_t* last,
+ const uint8_t** endp)
+{
+ size_t length = 0;
+ if (JSONCONS_UNLIKELY(last <= first))
+ {
+ *endp = first;
+ }
+ else
+ {
+ const uint8_t* p = first+1;
+ switch (*first)
+ {
+ case JSONCONS_CBOR_0x40_0x57: // byte string (0x00..0x17 bytes follow)
+ {
+ length = *first & 0x1f;
+ *endp = p;
+ break;
+ }
+ case 0x58: // byte string (one-byte uint8_t for n follows)
+ {
+ length = binary::from_big_endian<uint8_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ break;
+ }
+ case 0x59: // byte string (two-byte uint16_t for n follow)
+ {
+ length = binary::from_big_endian<uint16_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ break;
+ }
+ case 0x5a: // byte string (four-byte uint32_t for n follow)
+ {
+ length = binary::from_big_endian<uint32_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ break;
+ }
+ case 0x5b: // byte string (eight-byte uint64_t for n follow)
+ {
+ length = binary::from_big_endian<uint64_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ break;
+ }
+ case 0x5f: // byte string, byte strings follow, terminated by "break"
+ {
+ length = 0;
+ while (*p != 0xff)
+ {
+ size_t len = detail::get_byte_string_length(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ break;
+ }
+ length += len;
+ }
+ break;
+ }
+ default:
+ {
+ *endp = first;
+ }
+ }
+ }
+ return length;
+}
+
+inline
+std::vector<uint8_t> get_byte_string(const uint8_t* first, const uint8_t* last,
+ const uint8_t** endp)
+{
+ std::vector<uint8_t> v;
+ if (JSONCONS_UNLIKELY(last <= first))
+ {
+ *endp = first;
+ }
+ else
+ {
+ const uint8_t* p = first+1;
+ switch (*first)
+ {
+ case JSONCONS_CBOR_0x40_0x57: // byte string (0x00..0x17 bytes follow)
+ {
+ size_t length = *first & 0x1f;
+ *endp = p + length;
+ v = std::vector<uint8_t>(p, *endp);
+ break;
+ }
+ case 0x58: // byte string (one-byte uint8_t for n follows)
+ {
+ const auto length = binary::from_big_endian<uint8_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ p = *endp;
+ *endp = p + length;
+ v = std::vector<uint8_t>(p, *endp);
+ }
+ break;
+ }
+ case 0x59: // byte string (two-byte uint16_t for n follow)
+ {
+ const auto length = binary::from_big_endian<uint16_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ p = *endp;
+ *endp = p + length;
+ v = std::vector<uint8_t>(p, *endp);
+ }
+ break;
+ }
+ case 0x5a: // byte string (four-byte uint32_t for n follow)
+ {
+ const auto length = binary::from_big_endian<uint32_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ p = *endp;
+ *endp = p + length;
+ v = std::vector<uint8_t>(p, *endp);
+ }
+ break;
+ }
+ case 0x5b: // byte string (eight-byte uint64_t for n follow)
+ {
+ const auto length = binary::from_big_endian<uint64_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ p = *endp;
+ *endp = p + length;
+ v = std::vector<uint8_t>(p, *endp);
+ }
+ break;
+ }
+ case 0x5f: // byte string, byte strings follow, terminated by "break"
+ {
+ while (*p != 0xff)
+ {
+ std::vector<uint8_t> ss = detail::get_byte_string(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ break;
+ }
+ else
+ {
+ p = *endp;
+ v.insert(v.end(),ss.begin(),ss.end());
+ }
+ }
+ break;
+ }
+ default:
+ {
+ *endp = first;
+ }
+ }
+ }
+ return v;
+}
+
+inline
+size_t get_text_string_length(const uint8_t* first, const uint8_t* last,
+ const uint8_t** endp)
+{
+ size_t length = 0;
+ if (JSONCONS_UNLIKELY(last <= first))
+ {
+ *endp = first;
+ }
+ else
+ {
+ const uint8_t* p = first+1;
+ switch (*first)
+ {
+ case JSONCONS_CBOR_0x60_0x77: // UTF-8 string (0x00..0x17 bytes follow)
+ {
+ length = *first & 0x1f;
+ *endp = p;
+ break;
+ }
+ case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
+ {
+ length = binary::from_big_endian<uint8_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ break;
+ }
+ case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
+ {
+ length = binary::from_big_endian<uint16_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ break;
+ }
+ case 0x7a: // UTF-8 string (four-byte uint32_t for n follow)
+ {
+ length = binary::from_big_endian<uint32_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ break;
+ }
+ case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow)
+ {
+ length = binary::from_big_endian<uint64_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ break;
+ }
+ case 0x7f: // UTF-8 string, text strings follow, terminated by "break"
+ {
+ length = 0;
+ while (*p != 0xff)
+ {
+ size_t len = detail::get_text_string_length(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ break;
+ }
+ length += len;
+ }
+ break;
+ }
+ default:
+ *endp = first;
+ break;
+ }
+ }
+ return length;
+}
+
+inline
+std::string get_text_string(const uint8_t* first, const uint8_t* last,
+ const uint8_t** endp)
+{
+ std::string s;
+ if (JSONCONS_UNLIKELY(last <= first))
+ {
+ *endp = first;
+ }
+ else
+ {
+ const uint8_t* p = first+1;
+ switch (*first)
+ {
+ case JSONCONS_CBOR_0x60_0x77: // UTF-8 string (0x00..0x17 bytes follow)
+ {
+ size_t length = *first & 0x1f;
+ *endp = p + length;
+ s = std::string(p, *endp);
+ break;
+ }
+ case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
+ {
+ const auto length = binary::from_big_endian<uint8_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ p = *endp;
+ *endp = p + length;
+ s = std::string(p, *endp);
+ }
+ break;
+ }
+ case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
+ {
+ const auto length = binary::from_big_endian<uint16_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ p = *endp;
+ *endp = p + length;
+ s = std::string(p, *endp);
+ }
+ break;
+ }
+ case 0x7a: // UTF-8 string (four-byte uint32_t for n follow)
+ {
+ const auto length = binary::from_big_endian<uint32_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ p = *endp;
+ *endp = p + length;
+ s = std::string(p, *endp);
+ }
+ break;
+ }
+ case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow)
+ {
+ const auto length = binary::from_big_endian<uint64_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ p = *endp;
+ *endp = p + length;
+ s = std::string(p, *endp);
+ }
+ break;
+ }
+ case 0x7f: // UTF-8 string, text strings follow, terminated by "break"
+ {
+ while (*p != 0xff)
+ {
+ std::string ss = detail::get_text_string(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ break;
+ }
+ else
+ {
+ p = *endp;
+ s.append(std::move(ss));
+ }
+ }
+ break;
+ }
+ default:
+ *endp = first;
+ break;
+ }
+ }
+ return s;
+}
+
+inline
+void walk_object(const uint8_t* first, const uint8_t* last, const uint8_t** endp)
+{
+ size_t size = 0;
+
+ if (JSONCONS_UNLIKELY(last <= first))
+ {
+ *endp = first;
+ }
+ else
+ {
+ const uint8_t* p = first+1;
+ switch (*first)
+ {
+ case JSONCONS_CBOR_0xa0_0xb7: // map (0x00..0x17 pairs of data items follow)
+ {
+ size = *first & 0x1f;
+ *endp = p;
+ for (size_t i = 0; i < size; ++i)
+ {
+ walk(*endp, last, endp);
+ walk(*endp, last, endp);
+ }
+ break;
+ }
+
+ case 0xb8: // map (one-byte uint8_t for n follows)
+ {
+ size = binary::from_big_endian<uint8_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ for (size_t i = 0; i < size; ++i)
+ {
+ walk(*endp, last, endp);
+ walk(*endp, last, endp);
+ }
+ }
+ break;
+ }
+
+ case 0xb9: // map (two-byte uint16_t for n follow)
+ {
+ size = binary::from_big_endian<uint16_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ for (size_t i = 0; i < size; ++i)
+ {
+ walk(*endp, last, endp);
+ walk(*endp, last, endp);
+ }
+ }
+ break;
+ }
+
+ case 0xba: // map (four-byte uint32_t for n follow)
+ {
+ size = binary::from_big_endian<uint32_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ for (size_t i = 0; i < size; ++i)
+ {
+ walk(*endp, last, endp);
+ walk(*endp, last, endp);
+ }
+ }
+ break;
+ }
+
+ case 0xbb: // map (eight-byte uint64_t for n follow)
+ {
+ size = binary::from_big_endian<uint64_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ for (size_t i = 0; i < size; ++i)
+ {
+ walk(*endp, last, endp);
+ walk(*endp, last, endp);
+ }
+ }
+ break;
+ }
+ case 0xbf:
+ {
+ *endp = p;
+ while (*p != 0xff)
+ {
+ walk_object(p, last, endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ *endp = first;
+ }
+ }
+ }
+}
+
+inline
+void walk_array(const uint8_t* first, const uint8_t* last, const uint8_t** endp)
+{
+ size_t size = 0;
+
+ if (JSONCONS_UNLIKELY(last <= first))
+ {
+ *endp = first;
+ }
+ else
+ {
+ const uint8_t* p = first+1;
+ switch (*first)
+ {
+ case JSONCONS_CBOR_0x80_0x97: // array (0x00..0x17 data items follow)
+ {
+ size = *first & 0x1f;
+ *endp = p;
+ for (size_t i = 0; i < size; ++i)
+ {
+ walk(*endp, last, endp);
+ }
+ break;
+ }
+
+ case 0x98: // array (one-byte uint8_t for n follows)
+ {
+ size = binary::from_big_endian<uint8_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ for (size_t i = 0; i < size; ++i)
+ {
+ walk(*endp, last, endp);
+ }
+ }
+ break;
+ }
+
+ case 0x99: // array (two-byte uint16_t for n follow)
+ {
+ size = binary::from_big_endian<uint16_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ for (size_t i = 0; i < size; ++i)
+ {
+ walk(*endp, last, endp);
+ }
+ }
+ break;
+ }
+
+ case 0x9a: // array (four-byte uint32_t for n follow)
+ {
+ size = binary::from_big_endian<uint32_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ for (size_t i = 0; i < size; ++i)
+ {
+ walk(*endp, last, endp);
+ }
+ }
+ break;
+ }
+
+ case 0x9b: // array (eight-byte uint64_t for n follow)
+ {
+ size = binary::from_big_endian<uint64_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ for (size_t i = 0; i < size; ++i)
+ {
+ walk(*endp, last, endp);
+ }
+ }
+ break;
+ }
+ case 0x9f: // array (indefinite length)
+ {
+ *endp = p;
+ while (*p != 0xff)
+ {
+ walk_array(p, last, endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ *endp = first;
+ }
+ }
+ }
+}
+
+inline
+uint64_t get_uinteger(const uint8_t* first, const uint8_t* last, const uint8_t** endp)
+{
+ uint64_t val = 0;
+ if (JSONCONS_UNLIKELY(last <= first))
+ {
+ *endp = first;
+ }
+ else
+ {
+ const size_t length = last - first;
+ const uint8_t* p = first+1;
+ switch (*first)
+ {
+ case JSONCONS_CBOR_0x00_0x17: // Integer 0x00..0x17 (0..23)
+ val = *first;
+ *endp = p;
+ break;
+
+ case 0x18: // Unsigned integer (one-byte uint8_t follows)
+ {
+ val = binary::from_big_endian<uint8_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ break;
+ }
+
+ case 0x19: // Unsigned integer (two-byte uint16_t follows)
+ {
+ val = binary::from_big_endian<uint16_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ break;
+ }
+
+ case 0x1a: // Unsigned integer (four-byte uint32_t follows)
+ {
+ val = binary::from_big_endian<uint32_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ break;
+ }
+
+ case 0x1b: // Unsigned integer (eight-byte uint64_t follows)
+ {
+ val = binary::from_big_endian<uint64_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ break;
+ }
+ default:
+ {
+ *endp = first;
+ }
+ }
+ }
+ return val;
+}
+
+inline
+int64_t get_integer(const uint8_t* first, const uint8_t* last, const uint8_t** endp)
+{
+ int64_t val = 0;
+ if (JSONCONS_UNLIKELY(last <= first))
+ {
+ *endp = first;
+ }
+ else
+ {
+ const size_t length = last - first;
+ const uint8_t* p = first+1;
+ switch (*first)
+ {
+ case JSONCONS_CBOR_0x20_0x37: // Negative integer -1-0x00..-1-0x17 (-1..-24)
+ val = static_cast<int8_t>(0x20 - 1 - *first);
+ *endp = p;
+ break;
+
+ case 0x38: // Negative integer (one-byte uint8_t follows)
+ {
+ auto x = binary::from_big_endian<uint8_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ val = static_cast<int64_t>(-1)- x;
+ }
+ break;
+ }
+
+ case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
+ {
+ auto x = binary::from_big_endian<uint16_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ val = static_cast<int64_t>(-1)- x;
+ }
+ break;
+ }
+
+ case 0x3a: // Negative integer -1-n (four-byte uint32_t follows)
+ {
+ auto x = binary::from_big_endian<uint32_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ val = static_cast<int64_t>(-1)- x;
+ }
+ break;
+ }
+
+ case 0x3b: // Negative integer -1-n (eight-byte uint64_t follows)
+ {
+ auto x = binary::from_big_endian<uint64_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ val = static_cast<int64_t>(-1)- static_cast<int64_t>(x);
+ }
+ break;
+ }
+ case JSONCONS_CBOR_0x00_0x17: // Integer 0x00..0x17 (0..23)
+ // FALLTHRU
+ case 0x18: // Unsigned integer (one-byte uint8_t follows)
+ // FALLTHRU
+ case 0x19: // Unsigned integer (two-byte uint16_t follows)
+ // FALLTHRU
+ case 0x1a: // Unsigned integer (four-byte uint32_t follows)
+ // FALLTHRU
+ case 0x1b: // Unsigned integer (eight-byte uint64_t follows)
+ {
+ uint64_t x = detail::get_uinteger(first,last,endp);
+ if (*endp != first)
+ {
+ if (x <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)()))
+ {
+ val = x;
+ }
+ else
+ {
+ *endp = first;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ *endp = first;
+ }
+ }
+ }
+ return val;
+}
+
+inline
+double get_double(const uint8_t* first, const uint8_t* last, const uint8_t** endp)
+{
+ double val = 0;
+ if (JSONCONS_UNLIKELY(last <= first))
+ {
+ *endp = first;
+ }
+ else
+ {
+ const size_t length = last - first;
+ const uint8_t* p = first+1;
+ switch (*first)
+ {
+ case 0xf9: // Half-Precision Float (two-byte IEEE 754)
+ {
+ if (JSONCONS_UNLIKELY(1+sizeof(uint16_t) > length))
+ {
+ *endp = first;
+ }
+ else
+ {
+ uint16_t x = binary::from_big_endian<uint16_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ val = binary::decode_half(x);
+ }
+ }
+ }
+ break;
+
+
+ case 0xfa: // Single-Precision Float (four-byte IEEE 754)
+ {
+ if (JSONCONS_UNLIKELY(1+sizeof(float) > length))
+ {
+ *endp = first;
+ }
+ else
+ {
+ val = binary::from_big_endian<float>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ }
+ }
+ break;
+
+ case 0xfb: // Double-Precision Float (eight-byte IEEE 754)
+ {
+ if (JSONCONS_UNLIKELY(1+sizeof(double) > length))
+ {
+ *endp = first;
+ }
+ else
+ {
+ val = binary::from_big_endian<double>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ }
+ }
+ break;
+ default:
+ {
+ *endp = first;
+ }
+ }
+ }
+ return val;
+}
+
+inline
+bool is_array(uint8_t b)
+{
+ return (b >= 0x80 && b <= 0x9b) || b == 0x9f;
+}
+
+inline
+bool is_object(uint8_t b)
+{
+ return (b >= 0xa0 && b <= 0xbb) || b == 0xb8;
+}
+
+inline
+bool is_string(uint8_t b)
+{
+ return (b >= 0x60 && b <= 0x7b) || b == 0x7f;
+}
+
+inline
+bool is_bool(uint8_t b)
+{
+ return b == 0xf5 || b == 0xf4;
+}
+
+inline
+bool is_double(uint8_t b)
+{
+ return b == 0xf9 || b == 0xfa || b == 0xfb;
+}
+
+inline
+bool is_integer(const uint8_t* first, const uint8_t* last)
+{
+ bool result;
+
+ switch (*first)
+ {
+ case JSONCONS_CBOR_0x20_0x37: // Negative integer -1-0x00..-1-0x17 (-1..-24)
+ case 0x38: // Negative integer (one-byte uint8_t follows)
+ case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
+ case 0x3a: // Negative integer -1-n (four-byte uint32_t follows)
+ case 0x3b: // Negative integer -1-n (eight-byte uint64_t follows)
+ case JSONCONS_CBOR_0x00_0x17: // Integer 0x00..0x17 (0..23)
+ case 0x18: // Unsigned integer (one-byte uint8_t follows)
+ case 0x19: // Unsigned integer (two-byte uint16_t follows)
+ case 0x1a: // Unsigned integer (four-byte uint32_t follows)
+ result = true;
+ break;
+ case 0x1b: // Unsigned integer (eight-byte uint64_t follows)
+ {
+ const uint8_t* endp;
+ uint64_t x = detail::get_uinteger(first,last,&endp);
+ if (endp != first)
+ {
+ if (x <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)()))
+ {
+ result = true;
+ }
+ else
+ {
+ result = false;
+ }
+ }
+ else
+ {
+ result = false;
+ }
+ break;
+ }
+ default:
+ result = false;
+ break;
+ }
+ return result;
+}
+
+inline
+bool is_uinteger(uint8_t b)
+{
+ bool result;
+
+ switch (b)
+ {
+ case JSONCONS_CBOR_0x00_0x17: // Integer 0x00..0x17 (0..23)
+ // FALLTHRU
+ case 0x18: // Unsigned integer (one-byte uint8_t follows)
+ // FALLTHRU
+ case 0x19: // Unsigned integer (two-byte uint16_t follows)
+ // FALLTHRU
+ case 0x1a: // Unsigned integer (four-byte uint32_t follows)
+ // FALLTHRU
+ case 0x1b: // Unsigned integer (eight-byte uint64_t follows)
+ result = true;
+ break;
+ default:
+ result = false;
+ break;
+ }
+ return result;
+}
+
+inline
+void walk(const uint8_t* first, const uint8_t* last, const uint8_t** endp)
+{
+ if (first >= last)
+ {
+ *endp = first;
+ }
+ else
+ {
+ const uint8_t* p = first+1;
+ switch (*first)
+ {
+ case JSONCONS_CBOR_0x00_0x17: // Integer 0x00..0x17 (0..23)
+ {
+ *endp = p;
+ break;
+ }
+
+ case 0x18: // Unsigned integer (one-byte uint8_t follows)
+ {
+ p += sizeof(uint8_t);
+ *endp = p;
+ break;
+ }
+
+
+ case 0x19: // Unsigned integer (two-byte uint16_t follows)
+ {
+ p += sizeof(uint16_t);
+ *endp = p;
+ break;
+ }
+
+
+ case 0x1a: // Unsigned integer (four-byte uint32_t follows)
+ {
+ p += sizeof(uint32_t);
+ *endp = p;
+ break;
+ }
+
+
+ case 0x1b: // Unsigned integer (eight-byte uint64_t follows)
+ {
+ p += sizeof(uint64_t);
+ *endp = p;
+ break;
+ }
+
+ case JSONCONS_CBOR_0x20_0x37: // Negative integer -1-0x00..-1-0x17 (-1..-24)
+ {
+ *endp = p;
+ break;
+ }
+
+ case 0x38: // Negative integer (one-byte uint8_t follows)
+ {
+ p += sizeof(uint8_t);
+ *endp = p;
+ break;
+ }
+
+
+ case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
+ {
+ p += sizeof(uint16_t);
+ *endp = p;
+ break;
+ }
+
+
+ case 0x3a: // Negative integer -1-n (four-byte uint32_t follows)
+ {
+ p += sizeof(uint32_t);
+ *endp = p;
+ break;
+ }
+
+
+ case 0x3b: // Negative integer -1-n (eight-byte uint64_t follows)
+ {
+ p += sizeof(uint64_t);
+ *endp = p;
+ break;
+ }
+
+
+ case JSONCONS_CBOR_0x40_0x57: // byte string (0x00..0x17 bytes follow)
+ {
+ size_t len = *first & 0x1f;
+ *endp = p + len;
+ break;
+ }
+
+ case 0x58: // byte string (one-byte uint8_t for n follows)
+ {
+ const auto len = binary::from_big_endian<uint8_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ p = *endp;
+ }
+ *endp = p + len;
+ break;
+ }
+
+ case 0x59: // byte string (two-byte uint16_t for n follow)
+ {
+ const auto len = binary::from_big_endian<uint16_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ p = *endp;
+ }
+ *endp = p + len;
+ break;
+ }
+
+ case 0x5a: // byte string (four-byte uint32_t for n follow)
+ {
+ const auto len = binary::from_big_endian<uint32_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ p = *endp;
+ }
+ *endp = p + len;
+ break;
+ }
+
+ case 0x5b: // byte string (eight-byte uint64_t for n follow)
+ {
+ const auto len = binary::from_big_endian<uint64_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ p = *endp;
+ }
+ *endp = p + len;
+ break;
+ }
+
+ case 0x5f: // byte string (indefinite length)
+ {
+ while (*p != 0xff)
+ {
+ if (p == last)
+ {
+ JSONCONS_THROW(json_exception_impl<std::invalid_argument>("eof"));
+ }
+ walk(p, last, &p);
+ }
+ *endp = p;
+ break;
+ }
+
+ // UTF-8 string (0x00..0x17 bytes follow)
+ case JSONCONS_CBOR_0x60_0x77:
+ {
+ size_t len = *first & 0x1f;
+ *endp = p + len;
+ break;
+ }
+ // UTF-8 string (one-byte uint8_t for n follows)
+ case 0x78:
+ {
+ const auto len = binary::from_big_endian<uint8_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ p = *endp;
+ }
+ *endp = p + len;
+ break;
+ }
+ // UTF-8 string (two-byte uint16_t for n follow)
+ case 0x79:
+ {
+ const auto len = binary::from_big_endian<uint16_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ p = *endp;
+ }
+ *endp = p + len;
+ break;
+ }
+ // UTF-8 string (four-byte uint32_t for n follow)
+ case 0x7a:
+ {
+ const auto len = binary::from_big_endian<uint32_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ p = *endp;
+ }
+ *endp = p + len;
+ break;
+ }
+ // UTF-8 string (eight-byte uint64_t for n follow)
+ case 0x7b:
+ {
+ const auto len = binary::from_big_endian<uint64_t>(p,last,endp);
+ if (*endp == p)
+ {
+ *endp = first;
+ }
+ else
+ {
+ p = *endp;
+ }
+ *endp = p + len;
+ break;
+ }
+ // UTF-8 string (indefinite length)
+ case 0x7f:
+ {
+ while (*p != 0xff)
+ {
+ if (p == last)
+ {
+ JSONCONS_THROW(json_exception_impl<std::invalid_argument>("eof"));
+ }
+ walk(p, last, &p);
+ }
+ *endp = p;
+ break;
+ }
+
+
+ case JSONCONS_CBOR_0x80_0x97: // array (0x00..0x17 data items follow)
+ // FALLTHRU
+ case 0x98: // array (one-byte uint8_t for n follows)
+ // FALLTHRU
+ case 0x99: // array (two-byte uint16_t for n follow)
+ // FALLTHRU
+ case 0x9a: // array (four-byte uint32_t for n follow)
+ // FALLTHRU
+ case 0x9b: // array (eight-byte uint64_t for n follow)
+ // FALLTHRU
+ case 0x9f: // array (indefinite length)
+ {
+ walk_array(first,last,endp);
+ break;
+ }
+
+ case JSONCONS_CBOR_0xa0_0xb7: // map (0x00..0x17 pairs of data items follow)
+ // FALLTHRU
+ case 0xb8: // map (one-byte uint8_t for n follows)
+ // FALLTHRU
+ case 0xb9: // map (two-byte uint16_t for n follow)
+ // FALLTHRU
+ case 0xba: // map (four-byte uint32_t for n follow)
+ // FALLTHRU
+ case 0xbb: // map (eight-byte uint64_t for n follow)
+ // FALLTHRU
+ case 0xbf:
+ {
+ walk_object(first,last,endp);
+ break;
+ }
+
+ // False
+ case 0xf4:
+ {
+ *endp = p;
+ break;
+ }
+
+ // True
+ case 0xf5:
+ {
+ *endp = p;
+ break;
+ }
+
+ // Null
+ case 0xf6:
+ {
+ *endp = p;
+ break;
+ }
+
+ // Half-Precision Float (two-byte IEEE 754)
+ case 0xf9:
+ {
+ p += sizeof(uint16_t);
+ *endp = p;
+ break;
+ }
+
+ // Single-Precision Float (four-byte IEEE 754)
+ case 0xfa:
+ {
+ p += sizeof(float);
+ *endp = p;
+ break;
+ }
+
+ // Double-Precision Float (eight-byte IEEE 754)
+ case 0xfb:
+ {
+ p += sizeof(double);
+ *endp = p;
+ break;
+ }
+
+ default:
+ {
+ *endp = first;
+ break;
+ }
+ }
+ }
+}
+
+inline
+size_t get_size(const uint8_t* first, const uint8_t* last, const uint8_t** endp)
+{
+ const uint8_t* p = first + 1;
+ switch (*first)
+ {
+ // array (0x00..0x17 data items follow)
+ case JSONCONS_CBOR_0x80_0x97:
+ {
+ *endp = p;
+ return *first & 0x1f;
+ }
+
+ // array (one-byte uint8_t for n follows)
+ case 0x98:
+ {
+ const auto len = binary::from_big_endian<uint8_t>(p,last,endp);
+ if (*endp == p)
+ {
+ JSONCONS_THROW(cbor_decode_error(last-p));
+ }
+ else
+ {
+ p = *endp;
+ }
+ *endp = p;
+ return len;
+ }
+
+ // array (two-byte uint16_t for n follow)
+ case 0x99:
+ {
+ const auto len = binary::from_big_endian<uint16_t>(p,last,endp);
+ if (*endp == p)
+ {
+ JSONCONS_THROW(cbor_decode_error(last-p));
+ }
+ else
+ {
+ p = *endp;
+ }
+ *endp = p;
+ return len;
+ }
+
+ // array (four-byte uint32_t for n follow)
+ case 0x9a:
+ {
+ const auto len = binary::from_big_endian<int32_t>(p,last,endp);
+ if (*endp == p)
+ {
+ JSONCONS_THROW(cbor_decode_error(last-p));
+ }
+ else
+ {
+ p = *endp;
+ }
+ *endp = p;
+ return len;
+ }
+
+ // array (eight-byte uint64_t for n follow)
+ case 0x9b:
+ {
+ const auto len = binary::from_big_endian<int64_t>(p,last,endp);
+ if (*endp == p)
+ {
+ JSONCONS_THROW(cbor_decode_error(last-p));
+ }
+ else
+ {
+ p = *endp;
+ }
+ *endp = p;
+ return len;
+ }
+
+ // array (indefinite length)
+ case 0x9f:
+ {
+ size_t len = 0;
+ while (*p != 0xff)
+ {
+ size_t sz = get_size(p,last,&p);
+ len += sz;
+ walk(p, last, &p);
+ }
+ *endp = first + 1;
+ return len;
+ }
+
+ // map (0x00..0x17 pairs of data items follow)
+ case JSONCONS_CBOR_0xa0_0xb7:
+ {
+ *endp = p;
+ return *first & 0x1f;
+ }
+
+ // map (one-byte uint8_t for n follows)
+ case 0xb8:
+ {
+ const auto len = binary::from_big_endian<uint8_t>(p,last,endp);
+ if (*endp == p)
+ {
+ JSONCONS_THROW(cbor_decode_error(last-p));
+ }
+ else
+ {
+ p = *endp;
+ }
+ *endp = p;
+ return len;
+ }
+
+ // map (two-byte uint16_t for n follow)
+ case 0xb9:
+ {
+ const auto len = binary::from_big_endian<uint16_t>(p,last,endp);
+ if (*endp == p)
+ {
+ JSONCONS_THROW(cbor_decode_error(last-p));
+ }
+ else
+ {
+ p = *endp;
+ }
+ *endp = p;
+ return len;
+ }
+
+ // map (four-byte uint32_t for n follow)
+ case 0xba:
+ {
+ const auto len = binary::from_big_endian<uint32_t>(p,last,endp);
+ if (*endp == p)
+ {
+ JSONCONS_THROW(cbor_decode_error(last-p));
+ }
+ else
+ {
+ p = *endp;
+ }
+ *endp = p;
+ return len;
+ }
+
+ // map (eight-byte uint64_t for n follow)
+ case 0xbb:
+ {
+ const auto len = binary::from_big_endian<uint64_t>(p,last,endp);
+ if (*endp == p)
+ {
+ JSONCONS_THROW(cbor_decode_error(last-p));
+ }
+ else
+ {
+ p = *endp;
+ }
+ *endp = p;
+ return len;
+ }
+
+ // map (indefinite length)
+ case 0xbf:
+ {
+ size_t len = 0;
+ while (*p != 0xff)
+ {
+ walk(p, last, &p);
+ walk(p, last, &p);
+ }
+ *endp = first + 1;
+ return len;
+ }
+ default:
+ *endp = last;
+ return 0;
+ }
+}
+
+template <class T>
+class const_array_iterator
+{
+ const uint8_t* p_;
+ const uint8_t* last_;
+ T current_;
+public:
+ typedef typename T::difference_type difference_type;
+ typedef typename T::value_type value_type;
+ typedef typename T::const_reference reference;
+ typedef typename T::const_pointer pointer;
+ typedef std::forward_iterator_tag iterator_catagory;
+
+ const_array_iterator()
+ : p_(nullptr), last_(nullptr)
+ {
+ }
+
+ const_array_iterator(const uint8_t* p, const uint8_t* last)
+ : p_(p), last_(last)
+ {
+ }
+
+ const_array_iterator(const const_array_iterator& other) = default;
+
+ friend bool operator==(const const_array_iterator& lhs, const const_array_iterator& rhs)
+ {
+ return lhs.p_ == rhs.p_;
+ }
+
+ friend bool operator!=(const const_array_iterator& lhs, const const_array_iterator& rhs)
+ {
+ return lhs.p_ != rhs.p_;
+ }
+
+ friend bool operator<(const const_array_iterator& lhs, const const_array_iterator& rhs)
+ {
+ return lhs.p_ == rhs.p_;
+ }
+
+ const_array_iterator& operator++()
+ {
+ detail::walk(p_, last_, &p_);
+ return *this;
+ }
+
+ reference operator*() const
+ {
+ const uint8_t* endp;
+ detail::walk(p_, last_, &endp);
+ const_cast<T*>(&current_)->first_ = p_;
+ const_cast<T*>(&current_)->last_ = endp;
+ return current_;
+ }
+
+ pointer operator->() const
+ {
+ const uint8_t* endp;
+ detail::walk(p_, last_, &endp);
+ const_cast<T*>(&current_)->first_ = p_;
+ const_cast<T*>(&current_)->last_ = endp;
+ return &current_;
+ }
+};
+
+template <class T>
+class const_object_iterator;
+
+template <class T>
+class key_value_pair_view
+{
+ const uint8_t* key_begin_;
+ const uint8_t* key_end_;
+ const uint8_t* val_begin_;
+ const uint8_t* val_end_;
+
+public:
+ friend class const_object_iterator<T>;
+
+ key_value_pair_view()
+ : key_begin_(nullptr), key_end_(nullptr), val_begin_(nullptr), val_end_(nullptr)
+ {
+ }
+ key_value_pair_view(const uint8_t* key_begin, const uint8_t* key_end, const uint8_t* val_begin, const uint8_t* val_end)
+ : key_begin_(key_begin), key_end_(key_end), val_begin_(val_begin), val_end_(val_end)
+ {
+ }
+ key_value_pair_view(const key_value_pair_view& other) = default;
+
+ std::string key() const
+ {
+ const uint8_t* endp;
+ return get_text_string(key_begin_, key_end_, &endp);
+ }
+
+ T value() const
+ {
+ return T(val_begin_, val_end_ - val_begin_);
+ }
+};
+
+template <class T>
+class const_object_iterator
+{
+ const uint8_t* p_;
+ const uint8_t* last_;
+ key_value_pair_view<T> kvpair_;
+public:
+ typedef typename T::difference_type difference_type;
+ typedef key_value_pair_view<T> value_type;
+ typedef const key_value_pair_view<T>& reference;
+ typedef const key_value_pair_view<T>* pointer;
+ typedef std::forward_iterator_tag iterator_catagory;
+
+ const_object_iterator()
+ : p_(nullptr), last_(nullptr)
+ {
+ }
+
+ const_object_iterator(const uint8_t* p, const uint8_t* last)
+ : p_(p), last_(last)
+ {
+ }
+
+ const_object_iterator(const const_object_iterator& other) = default;
+
+ friend bool operator==(const const_object_iterator& lhs, const const_object_iterator& rhs)
+ {
+ return lhs.p_ == rhs.p_;
+ }
+
+ friend bool operator!=(const const_object_iterator& lhs, const const_object_iterator& rhs)
+ {
+ return lhs.p_ != rhs.p_;
+ }
+
+ friend bool operator<(const const_object_iterator& lhs, const const_object_iterator& rhs)
+ {
+ return lhs.p_ == rhs.p_;
+ }
+
+ const_object_iterator& operator++()
+ {
+ detail::walk(p_, last_, &p_);
+ detail::walk(p_, last_, &p_);
+ return *this;
+ }
+
+ reference operator*() const
+ {
+ const uint8_t* endp;
+
+ const_cast<key_value_pair_view<T>*>(&kvpair_)->key_begin_ = p_;
+ detail::walk(kvpair_.key_begin_, last_, &endp);
+ const_cast<key_value_pair_view<T>*>(&kvpair_)->key_end_ = endp;
+ const_cast<key_value_pair_view<T>*>(&kvpair_)->val_begin_ = kvpair_.key_end_;
+ detail::walk(kvpair_.val_begin_, last_, &endp);
+ const_cast<key_value_pair_view<T>*>(&kvpair_)->val_end_ = endp;
+
+ return kvpair_;
+ }
+
+ pointer operator->() const
+ {
+ const uint8_t* endp;
+
+ const_cast<key_value_pair_view<T>*>(&kvpair_)->key_begin_ = p_;
+ detail::walk(kvpair_.key_begin_, last_, &endp);
+ const_cast<key_value_pair_view<T>*>(&kvpair_)->key_end_ = endp;
+ const_cast<key_value_pair_view<T>*>(&kvpair_)->val_begin_ = kvpair_.key_end_;
+ detail::walk(kvpair_.val_begin_, last_, &endp);
+ const_cast<key_value_pair_view<T>*>(&kvpair_)->val_end_ = endp;
+
+ return &kvpair_;
+ }
+};
+
+} // namespace detail
+
+class cbor_view
+{
+ const uint8_t* first_;
+ const uint8_t* last_;
+public:
+ typedef std::ptrdiff_t difference_type;
+ typedef cbor_view value_type;
+ typedef cbor_view& reference;
+ typedef const cbor_view& const_reference;
+ typedef cbor_view* pointer;
+ typedef const cbor_view* const_pointer;
+ typedef std::string string_type;
+ typedef char char_type;
+ typedef std::char_traits<char_type> char_traits_type;
+ typedef basic_string_view_ext<char_type> string_view_type;
+ typedef detail::const_object_iterator<cbor_view> object_iterator;
+ typedef detail::const_object_iterator<cbor_view> const_object_iterator;
+ typedef detail::const_array_iterator<cbor_view> array_iterator;
+ typedef detail::const_array_iterator<cbor_view> const_array_iterator;
+ typedef detail::key_value_pair_view<cbor_view> key_value_pair_type;
+
+ friend class detail::const_array_iterator<cbor_view>;
+
+ range<const_object_iterator> object_range() const
+ {
+ const uint8_t* endp;
+ const uint8_t* begin;
+
+ switch (*first_)
+ {
+ case JSONCONS_CBOR_0xa0_0xb7: // map (0x00..0x17 pairs of data items follow)
+ // FALLTHRU
+ case 0xb8: // map (one-byte uint8_t for n follows)
+ // FALLTHRU
+ case 0xb9: // map (two-byte uint16_t for n follow)
+ // FALLTHRU
+ case 0xba: // map (four-byte uint32_t for n follow)
+ // FALLTHRU
+ case 0xbb: // map (eight-byte uint64_t for n follow)
+ // FALLTHRU
+ case 0xbf:
+ detail::get_size(first_,last_,&begin);
+ break;
+ default:
+ JSONCONS_THROW(json_exception_impl<std::invalid_argument>("Not an object"));
+ break;
+ }
+ detail::walk_object(first_,last_,&endp);
+
+ return range<const_object_iterator>(const_object_iterator(begin,endp), const_object_iterator(endp, endp));
+ }
+
+ range<const_array_iterator> array_range() const
+ {
+ const uint8_t* endp;
+ const uint8_t* begin;
+
+ switch (*first_)
+ {
+ case JSONCONS_CBOR_0x80_0x97: // array (0x00..0x17 data items follow)
+ // FALLTHRU
+ case 0x98: // array (one-byte uint8_t for n follows)
+ // FALLTHRU
+ case 0x99: // array (two-byte uint16_t for n follow)
+ // FALLTHRU
+ case 0x9a: // array (four-byte uint32_t for n follow)
+ // FALLTHRU
+ case 0x9b: // array (eight-byte uint64_t for n follow)
+ // FALLTHRU
+ case 0x9f: // array (indefinite length)
+ detail::get_size(first_,last_,&begin);
+ break;
+ default:
+ JSONCONS_THROW(json_exception_impl<std::invalid_argument>("Not an array"));
+ break;
+ }
+ detail::walk_array(first_,last_,&endp);
+ return range<const_array_iterator>(const_array_iterator(begin,endp), const_array_iterator(endp, endp));
+ }
+
+ cbor_view()
+ : first_(nullptr), last_(nullptr)
+ {
+ }
+
+ cbor_view(const uint8_t* buffer, size_t buflen)
+ : first_(buffer), last_(buffer+buflen)
+ {
+ }
+
+ cbor_view(const std::vector<uint8_t>& v)
+ : first_(v.data()), last_(v.data()+v.size())
+ {
+ }
+
+ cbor_view(const cbor_view& other)
+ : first_(other.first_), last_(other.last_)
+ {
+ }
+
+ cbor_view& operator=(const cbor_view&) = default;
+
+ friend bool operator==(const cbor_view& lhs, const cbor_view& rhs)
+ {
+ return lhs.first_ == rhs.first_ && lhs.last_ == rhs.last_;
+ }
+
+ friend bool operator!=(const cbor_view& lhs, const cbor_view& rhs)
+ {
+ return !(lhs == rhs);
+ }
+
+ const uint8_t* buffer() const
+ {
+ return first_;
+ }
+
+ const size_t buflen() const
+ {
+ return last_ - first_;
+ }
+
+ bool is_null() const
+ {
+ JSONCONS_ASSERT(buflen() > 0);
+ return first_[0] == 0xf6;
+ }
+
+ bool empty() const
+ {
+ bool is_empty;
+ if (is_array() || is_object())
+ {
+ is_empty = (size() == 0);
+ }
+ else if (is_string())
+ {
+ const uint8_t* endp;
+ size_t length = detail::get_text_string_length(first_,last_,&endp);
+ is_empty = (length == 0);
+ }
+ else if (is_byte_string())
+ {
+ const uint8_t* endp;
+ size_t length = detail::get_byte_string_length(first_, last_, &endp);
+ is_empty = (length == 0);
+ }
+ else
+ {
+ is_empty = false;
+ }
+
+ return is_empty;
+ }
+
+ bool is_array() const
+ {
+ JSONCONS_ASSERT(buflen() > 0);
+ return detail::is_array(first_[0]);
+ }
+
+ bool is_object() const
+ {
+ JSONCONS_ASSERT(buflen() > 0);
+ return detail::is_object(first_[0]);
+ }
+
+ bool is_string() const
+ {
+ JSONCONS_ASSERT(buflen() > 0);
+ return detail::is_string(first_[0]);
+ }
+
+ bool is_byte_string() const
+ {
+ JSONCONS_ASSERT(buflen() > 0);
+
+ bool result;
+ switch (first_[0])
+ {
+ case JSONCONS_CBOR_0x40_0x57: // byte string (0x00..0x17 bytes follow)
+ // FALLTHRU
+ case 0x58: // byte string (one-byte uint8_t for n follows)
+ // FALLTHRU
+ case 0x59: // byte string (two-byte uint16_t for n follow)
+ // FALLTHRU
+ case 0x5a: // byte string (four-byte uint32_t for n follow)
+ // FALLTHRU
+ case 0x5b: // byte string (eight-byte uint64_t for n follow)
+ // FALLTHRU
+ case 0x5f: // byte string, byte strings follow, terminated by "break"
+ result = true;
+ break;
+ default:
+ result = false;
+ break;
+ }
+ return result;
+ }
+
+ bool is_bool() const
+ {
+ JSONCONS_ASSERT(buflen() > 0);
+ return detail::is_bool(first_[0]);
+ }
+
+ bool is_double() const
+ {
+ JSONCONS_ASSERT(buflen() > 0);
+ return detail::is_double(first_[0]);
+ }
+
+ bool is_integer() const
+ {
+ JSONCONS_ASSERT(buflen() > 0);
+ return detail::is_integer(first_,last_);
+ }
+
+ bool is_uinteger() const
+ {
+ JSONCONS_ASSERT(buflen() > 0);
+ return detail::is_uinteger(first_[0]);
+ }
+
+ size_t size() const
+ {
+ const uint8_t* it;
+ size_t len = detail::get_size(first_,last_,&it);
+ return len;
+ }
+
+ cbor_view at(size_t index) const
+ {
+ JSONCONS_ASSERT(is_array());
+ const uint8_t* it = first_;
+
+ size_t len = detail::get_size(it, last_, &it);
+
+ for (size_t i = 0; i < index; ++i)
+ {
+ detail::walk(it, last_, &it);
+ }
+
+ const uint8_t* endp;
+ detail::walk(it, last_, &endp);
+
+ return cbor_view(it,endp-it);
+ }
+
+ cbor_view at(const string_view_type& key) const
+ {
+ JSONCONS_ASSERT(is_object());
+ const uint8_t* it = first_;
+
+ size_t len = detail::get_size(first_, last_, &it);
+
+ for (size_t i = 0; i < len; ++i)
+ {
+ const uint8_t* endp;
+ string_type a_key = detail::get_text_string(it, last_, &endp);
+ if (endp == it)
+ {
+ JSONCONS_THROW(cbor_decode_error(last_-it));
+ }
+ else
+ {
+ it = endp;
+ }
+ if (a_key == key)
+ {
+ const uint8_t* last;
+ detail::walk(it, last_, &last);
+ JSONCONS_ASSERT(last >= it);
+ return cbor_view(it,last-it);
+ }
+ const uint8_t* last;
+ detail::walk(it, last_, &last);
+ it = last;
+ }
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Key not found"));
+ }
+
+ bool has_key(const string_view_type& key) const
+ {
+ if (!is_object())
+ {
+ return false;
+ }
+ const uint8_t* it = first_;
+
+ size_t len = detail::get_size(it, last_, &it);
+
+ for (size_t i = 0; i < len; ++i)
+ {
+ const uint8_t* endp;
+ string_type a_key = detail::get_text_string(it, last_,&endp);
+ if (endp == it)
+ {
+ JSONCONS_THROW(cbor_decode_error(last_-it));
+ }
+ else
+ {
+ it = endp;
+ }
+ if (a_key == key)
+ {
+ return true;
+ }
+ detail::walk(it, last_, &it);
+ }
+ return false;
+ }
+
+ int64_t as_integer() const
+ {
+ const uint8_t* endp;
+ int64_t val = detail::get_integer(first_,last_,&endp);
+ if (endp == first_)
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not an integer"));
+ }
+ return val;
+ }
+
+ bool as_bool() const
+ {
+ if (*first_ == 0xf5)
+ {
+ return true;
+ }
+ else if (*first_ == 0xf4)
+ {
+ return false;
+ }
+ else
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not a bool"));
+ }
+ }
+
+ uint64_t as_uinteger() const
+ {
+ const uint8_t* endp;
+ uint64_t val = detail::get_uinteger(first_, last_, &endp);
+ if (endp == first_)
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not an unsigned integer"));
+ }
+ return val;
+ }
+
+ double as_double() const
+ {
+ double val;
+
+ if (is_double())
+ {
+ const uint8_t* endp;
+ val = detail::get_double(first_,last_,&endp);
+ if (endp == first_)
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Invalid CBOR"));
+ }
+ }
+ else if (is_uinteger())
+ {
+ val = static_cast<double>(as_uinteger());
+ }
+ else if (is_integer())
+ {
+ val = static_cast<double>(as_integer());
+ }
+ else
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not a double"));
+ }
+ return val;
+ }
+
+ std::string as_string() const
+ {
+ const uint8_t* endp;
+ std::string val = detail::get_text_string(first_,last_,&endp);
+ if (endp == first_)
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Not a string"));
+ }
+ return val;
+ }
+};
+
+struct Encode_cbor_
+{
+ template <typename T>
+ void operator()(T val, std::vector<uint8_t>& v)
+ {
+ binary::to_big_endian(val,v);
+ }
+};
+
+struct Calculate_size_
+{
+ template <typename T>
+ void operator()(T, size_t& size)
+ {
+ size += sizeof(T);
+ }
+};
+
+template<class Json>
+struct cbor_Encoder_
+{
+ typedef typename Json::string_view_type string_view_type;
+
+ static size_t calculate_size(const Json& j)
+ {
+ size_t n = 0;
+ cbor_Encoder_<Json>::encode(j,Calculate_size_(),n);
+ return n;
+ }
+
+ template <class Action, class Result>
+ static void encode(const Json& jval, Action action, Result& v)
+ {
+ switch (jval.type_id())
+ {
+ case json_type_tag::null_t:
+ {
+ action(static_cast<uint8_t>(0xf6), v);
+ break;
+ }
+
+ case json_type_tag::bool_t:
+ {
+ action(static_cast<uint8_t>(jval.as_bool() ? 0xf5 : 0xf4), v);
+ break;
+ }
+
+ case json_type_tag::integer_t:
+ {
+ int64_t val = jval.as_integer();
+ if (val >= 0)
+ {
+ if (val <= 0x17)
+ {
+ action(static_cast<uint8_t>(val), v);
+ } else if (val <= (std::numeric_limits<uint8_t>::max)())
+ {
+ action(static_cast<uint8_t>(0x18), v);
+ action(static_cast<uint8_t>(val), v);
+ } else if (val <= (std::numeric_limits<uint16_t>::max)())
+ {
+ action(static_cast<uint8_t>(0x19), v);
+ action(static_cast<uint16_t>(val), v);
+ } else if (val <= (std::numeric_limits<uint32_t>::max)())
+ {
+ action(static_cast<uint8_t>(0x1a), v);
+ action(static_cast<uint32_t>(val), v);
+ } else if (val <= (std::numeric_limits<int64_t>::max)())
+ {
+ action(static_cast<uint8_t>(0x1b), v);
+ action(static_cast<int64_t>(val), v);
+ }
+ } else
+ {
+ const auto posnum = -1 - val;
+ if (val >= -24)
+ {
+ action(static_cast<uint8_t>(0x20 + posnum), v);
+ } else if (posnum <= (std::numeric_limits<uint8_t>::max)())
+ {
+ action(static_cast<uint8_t>(0x38), v);
+ action(static_cast<uint8_t>(posnum), v);
+ } else if (posnum <= (std::numeric_limits<uint16_t>::max)())
+ {
+ action(static_cast<uint8_t>(0x39), v);
+ action(static_cast<uint16_t>(posnum), v);
+ } else if (posnum <= (std::numeric_limits<uint32_t>::max)())
+ {
+ action(static_cast<uint8_t>(0x3a), v);
+ action(static_cast<uint32_t>(posnum), v);
+ } else if (posnum <= (std::numeric_limits<int64_t>::max)())
+ {
+ action(static_cast<uint8_t>(0x3b), v);
+ action(static_cast<int64_t>(posnum), v);
+ }
+ }
+ break;
+ }
+
+ case json_type_tag::uinteger_t:
+ {
+ uint64_t val = jval.as_uinteger();
+ if (val <= 0x17)
+ {
+ action(static_cast<uint8_t>(val),v);
+ } else if (val <=(std::numeric_limits<uint8_t>::max)())
+ {
+ action(static_cast<uint8_t>(0x18), v);
+ action(static_cast<uint8_t>(val),v);
+ } else if (val <=(std::numeric_limits<uint16_t>::max)())
+ {
+ action(static_cast<uint8_t>(0x19), v);
+ action(static_cast<uint16_t>(val),v);
+ } else if (val <=(std::numeric_limits<uint32_t>::max)())
+ {
+ action(static_cast<uint8_t>(0x1a), v);
+ action(static_cast<uint32_t>(val),v);
+ } else if (val <=(std::numeric_limits<uint64_t>::max)())
+ {
+ action(static_cast<uint8_t>(0x1b), v);
+ action(static_cast<uint64_t>(val),v);
+ }
+ break;
+ }
+
+ case json_type_tag::double_t:
+ {
+ action(static_cast<uint8_t>(0xfb), v);
+ action(jval.as_double(),v);
+ break;
+ }
+
+ case json_type_tag::byte_string_t:
+ {
+ encode_byte_string(jval. template as<std::vector<uint8_t>>(), action, v);
+ break;
+ }
+
+ case json_type_tag::small_string_t:
+ case json_type_tag::string_t:
+ {
+ encode_string(jval.as_string_view(), action, v);
+ break;
+ }
+
+ case json_type_tag::array_t:
+ {
+ const auto length = jval.array_value().size();
+ if (length <= 0x17)
+ {
+ action(static_cast<uint8_t>(static_cast<uint8_t>(0x80 + length)), v);
+ } else if (length <= 0xff)
+ {
+ action(static_cast<uint8_t>(0x98), v);
+ action(static_cast<uint8_t>(static_cast<uint8_t>(length)), v);
+ } else if (length <= 0xffff)
+ {
+ action(static_cast<uint8_t>(0x99), v);
+ action(static_cast<uint16_t>(length),v);
+ } else if (length <= 0xffffffff)
+ {
+ action(static_cast<uint8_t>(0x9a), v);
+ action(static_cast<uint32_t>(length),v);
+ } else if (length <= 0xffffffffffffffff)
+ {
+ action(static_cast<uint8_t>(0x9b), v);
+ action(static_cast<uint64_t>(length),v);
+ }
+
+ // append each element
+ for (const auto& el : jval.array_range())
+ {
+ encode(el,action,v);
+ }
+ break;
+ }
+
+ case json_type_tag::object_t:
+ {
+ const auto length = jval.object_value().size();
+ if (length <= 0x17)
+ {
+ action(static_cast<uint8_t>(static_cast<uint8_t>(0xa0 + length)), v);
+ } else if (length <= 0xff)
+ {
+ action(static_cast<uint8_t>(0xb8), v);
+ action(static_cast<uint8_t>(static_cast<uint8_t>(length)), v);
+ } else if (length <= 0xffff)
+ {
+ action(static_cast<uint8_t>(0xb9), v);
+ action(static_cast<uint16_t>(length),v);
+ } else if (length <= 0xffffffff)
+ {
+ action(static_cast<uint8_t>(0xba), v);
+ action(static_cast<uint32_t>(length),v);
+ } else if (length <= 0xffffffffffffffff)
+ {
+ action(static_cast<uint8_t>(0xbb), v);
+ action(static_cast<uint64_t>(length),v);
+ }
+
+ // append each element
+ for (const auto& kv: jval.object_range())
+ {
+ encode_string(kv.key(), action, v);
+ encode(kv.value(), action, v);
+ }
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ template <class Action,class Result>
+ static void encode_string(const string_view_type& sv, Action action, Result& v)
+ {
+ std::basic_string<uint8_t> target;
+ auto result = unicons::convert(
+ sv.begin(), sv.end(), std::back_inserter(target),
+ unicons::conv_flags::strict);
+ if (result.ec != unicons::conv_errc())
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Illegal unicode"));
+ }
+
+ const size_t length = target.length();
+ if (length <= 0x17)
+ {
+ // fixstr stores a byte array whose length is upto 31 bytes
+ action(static_cast<uint8_t>(static_cast<uint8_t>(0x60 + length)), v);
+ }
+ else if (length <= 0xff)
+ {
+ action(static_cast<uint8_t>(0x78), v);
+ action(static_cast<uint8_t>(static_cast<uint8_t>(length)), v);
+ }
+ else if (length <= 0xffff)
+ {
+ action(static_cast<uint8_t>(0x79), v);
+ action(static_cast<uint16_t>(length), v);
+ }
+ else if (length <= 0xffffffff)
+ {
+ action(static_cast<uint8_t>(0x7a), v);
+ action(static_cast<uint32_t>(length), v);
+ }
+ else if (length <= 0xffffffffffffffff)
+ {
+ action(static_cast<uint8_t>(0x7b), v);
+ action(static_cast<uint64_t>(length),v);
+ }
+
+ for (size_t i = 0; i < length; ++i)
+ {
+ action(static_cast<uint8_t>(target.data()[i]), v);
+ }
+ }
+
+ template <class Action,class Result>
+ static void encode_byte_string(const std::vector<uint8_t>& target, Action action, Result& v)
+ {
+ const size_t length = target.size();
+ if (length <= 0x17)
+ {
+ // fixstr stores a byte array whose length is upto 31 bytes
+ action(static_cast<uint8_t>(static_cast<uint8_t>(0x40 + length)), v);
+ }
+ else if (length <= 0xff)
+ {
+ action(static_cast<uint8_t>(0x58), v);
+ action(static_cast<uint8_t>(static_cast<uint8_t>(length)), v);
+ }
+ else if (length <= 0xffff)
+ {
+ action(static_cast<uint8_t>(0x59), v);
+ action(static_cast<uint16_t>(length), v);
+ }
+ else if (length <= 0xffffffff)
+ {
+ action(static_cast<uint8_t>(0x5a), v);
+ action(static_cast<uint32_t>(length), v);
+ }
+ else if (length <= 0xffffffffffffffff)
+ {
+ action(static_cast<uint8_t>(0x5b), v);
+ action(static_cast<uint64_t>(length),v);
+ }
+
+ for (size_t i = 0; i < length; ++i)
+ {
+ action(static_cast<uint8_t>(target.data()[i]), v);
+ }
+ }
+};
+
+// decode_cbor
+
+template<class Json>
+class Decode_cbor_
+{
+ const uint8_t* begin_;
+ const uint8_t* end_;
+ const uint8_t* it_;
+public:
+ typedef typename Json::char_type char_type;
+
+ Decode_cbor_(const uint8_t* begin, const uint8_t* end)
+ : begin_(begin), end_(end), it_(begin)
+ {
+ }
+
+ Json decode()
+ {
+ const uint8_t* pos = it_++;
+ switch (*pos)
+ {
+
+ case JSONCONS_CBOR_0x00_0x17: // Integer 0x00..0x17 (0..23)
+ // FALLTHRU
+ case 0x18: // Unsigned integer (one-byte uint8_t follows)
+ // FALLTHRU
+ case 0x19: // Unsigned integer (two-byte uint16_t follows)
+ // FALLTHRU
+ case 0x1a: // Unsigned integer (four-byte uint32_t follows)
+ // FALLTHRU
+ case 0x1b: // Unsigned integer (eight-byte uint64_t follows)
+ {
+ const uint8_t* endp;
+ uint64_t val = detail::get_uinteger(pos,end_,&endp);
+ if (endp == pos)
+ {
+ JSONCONS_THROW(cbor_decode_error(endp-begin_));
+ }
+ it_ = endp;
+ return Json(val);
+ }
+ break;
+
+ case JSONCONS_CBOR_0x20_0x37: // Negative integer -1-0x00..-1-0x17 (-1..-24)
+ // FALLTHRU
+ case 0x38: // Negative integer (one-byte uint8_t follows)
+ // FALLTHRU
+ case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
+ // FALLTHRU
+ case 0x3a: // Negative integer -1-n (four-byte uint32_t follows)
+ // FALLTHRU
+ case 0x3b: // Negative integer -1-n (eight-byte uint64_t follows)
+ {
+ const uint8_t* endp;
+ int64_t val = detail::get_integer(pos,end_,&endp);
+ if (endp == pos)
+ {
+ JSONCONS_THROW(cbor_decode_error(endp-begin_));
+ }
+ it_ = endp;
+ return Json(val);
+ }
+ break;
+ // byte string (0x00..0x17 bytes follow)
+ case JSONCONS_CBOR_0x40_0x57:
+ case 0x58:
+ case 0x59:
+ case 0x5a:
+ case 0x5b:
+ case 0x5f:
+ {
+ const uint8_t* endp;
+ std::vector<uint8_t> v = detail::get_byte_string(pos,end_,&endp);
+ if (endp == pos)
+ {
+ JSONCONS_THROW(cbor_decode_error(end_-pos));
+ }
+ else
+ {
+ it_ = endp;
+ }
+
+ return Json(v.data(),v.size());
+ }
+
+ // UTF-8 string (0x00..0x17 bytes follow)
+ case JSONCONS_CBOR_0x60_0x77:
+ case 0x78:
+ case 0x79:
+ case 0x7a:
+ case 0x7b:
+ case 0x7f:
+ {
+ const uint8_t* endp;
+ std::string s = detail::get_text_string(pos,end_,&endp);
+ if (endp == pos)
+ {
+ JSONCONS_THROW(cbor_decode_error(end_-pos));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ std::basic_string<char_type> target;
+ auto result = unicons::convert(s.begin(),s.end(),std::back_inserter(target),unicons::conv_flags::strict);
+ if (result.ec != unicons::conv_errc())
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Illegal unicode"));
+ }
+ return Json(target);
+ }
+
+ // array (0x00..0x17 data items follow)
+ case JSONCONS_CBOR_0x80_0x97:
+ {
+ return get_fixed_length_array(*pos & 0x1f);
+ }
+
+ // array (one-byte uint8_t for n follows)
+ case 0x98:
+ {
+ const uint8_t* endp;
+ const auto len = binary::from_big_endian<uint8_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(cbor_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return get_fixed_length_array(len);
+ }
+
+ // array (two-byte uint16_t for n follow)
+ case 0x99:
+ {
+ const uint8_t* endp;
+ const auto len = binary::from_big_endian<uint16_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(cbor_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return get_fixed_length_array(len);
+ }
+
+ // array (four-byte uint32_t for n follow)
+ case 0x9a:
+ {
+ const uint8_t* endp;
+ const auto len = binary::from_big_endian<int32_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(cbor_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return get_fixed_length_array(len);
+ }
+
+ // array (eight-byte uint64_t for n follow)
+ case 0x9b:
+ {
+ const uint8_t* endp;
+ const auto len = binary::from_big_endian<int64_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(cbor_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return get_fixed_length_array(len);
+ }
+
+ // array (indefinite length)
+ case 0x9f:
+ {
+ Json result = typename Json::array();
+ while (*pos != 0xff)
+ {
+ result.push_back(decode());
+ pos = it_;
+ }
+ return result;
+ }
+
+ // map (0x00..0x17 pairs of data items follow)
+ case JSONCONS_CBOR_0xa0_0xb7:
+ {
+ return get_fixed_length_map(*pos & 0x1f);
+ }
+
+ // map (one-byte uint8_t for n follows)
+ case 0xb8:
+ {
+ const uint8_t* endp;
+ const auto len = binary::from_big_endian<uint8_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(cbor_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return get_fixed_length_map(len);
+ }
+
+ // map (two-byte uint16_t for n follow)
+ case 0xb9:
+ {
+ const uint8_t* endp;
+ const auto len = binary::from_big_endian<uint16_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(cbor_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return get_fixed_length_map(len);
+ }
+
+ // map (four-byte uint32_t for n follow)
+ case 0xba:
+ {
+ const uint8_t* endp;
+ const auto len = binary::from_big_endian<uint32_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(cbor_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return get_fixed_length_map(len);
+ }
+
+ // map (eight-byte uint64_t for n follow)
+ case 0xbb:
+ {
+ const uint8_t* endp;
+ const auto len = binary::from_big_endian<uint64_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(cbor_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return get_fixed_length_map(len);
+ }
+
+ // map (indefinite length)
+ case 0xbf:
+ {
+ Json result = typename Json::object();
+ while (*pos != 0xff)
+ {
+ auto j = decode();
+ result.set(j.as_string_view(),decode());
+ pos = it_;
+ }
+ return result;
+ }
+
+ // False
+ case 0xf4:
+ {
+ return Json(false);
+ }
+
+ // True
+ case 0xf5:
+ {
+ return Json(true);
+ }
+
+ // Null
+ case 0xf6:
+ {
+ return Json::null();
+ }
+
+
+ case 0xf9: // Half-Precision Float (two-byte IEEE 754)
+ // FALLTHRU
+ case 0xfa: // Single-Precision Float (four-byte IEEE 754)
+ // FALLTHRU
+ case 0xfb: // Double-Precision Float (eight-byte IEEE 754)
+ {
+ const uint8_t* endp;
+ double val = detail::get_double(pos,end_,&endp);
+ if (endp == pos)
+ {
+ JSONCONS_THROW(cbor_decode_error(endp-begin_));
+ }
+ it_ = endp;
+ return Json(val);
+ }
+
+ default:
+ {
+ JSONCONS_THROW(cbor_decode_error(end_-pos));
+ }
+ }
+ }
+
+ template<typename T>
+ Json get_fixed_length_array(const T len)
+ {
+ Json result = typename Json::array();
+ result.reserve(len);
+ for (T i = 0; i < len; ++i)
+ {
+ result.push_back(decode());
+ }
+ return result;
+ }
+
+ template<typename T>
+ Json get_fixed_length_map(const T len)
+ {
+ Json result = typename Json::object();
+ result.reserve(len);
+ for (T i = 0; i < len; ++i)
+ {
+ auto j = decode();
+ result.set(j.as_string_view(),decode());
+ }
+ return result;
+ }
+};
+
+template<class Json>
+void encode_cbor(const Json& j, std::vector<uint8_t>& v)
+{
+ size_t n = 0;
+ cbor_Encoder_<Json>::encode(j,Calculate_size_(),n);
+
+ v.reserve(n);
+ cbor_Encoder_<Json>::encode(j,Encode_cbor_(),v);
+}
+
+template<class Json>
+Json decode_cbor(const cbor_view& v)
+{
+ Decode_cbor_<Json> decoder(v.buffer(),v.buffer()+v.buflen());
+ return decoder.decode();
+}
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+template<class Json>
+std::vector<uint8_t> encode_cbor(const Json& j)
+{
+ std::vector<uint8_t> v;
+ encode_cbor(j, v);
+ return v;
+}
+#endif
+
+}}
+
+#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_error_category.hpp b/vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_error_category.hpp
index 5056d380..0e986cda 100644
--- a/vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_error_category.hpp
+++ b/vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_error_category.hpp
@@ -4,21 +4,22 @@
// See https://github.com/danielaparker/jsoncons for latest version
-#ifndef JSONCONS_CSV_CSV_TEXT_ERROR_CATEGORY_HPP
-#define JSONCONS_CSV_CSV_TEXT_ERROR_CATEGORY_HPP
+#ifndef JSONCONS_CSV_CSV_ERROR_CATEGORY_HPP
+#define JSONCONS_CSV_CSV_ERROR_CATEGORY_HPP
-#include "jsoncons/jsoncons.hpp"
#include <system_error>
+#include <jsoncons/json_exception.hpp>
namespace jsoncons { namespace csv {
-namespace csv_parser_errc
-{
- const int unexpected_eof = 1;
- const int expected_quote = 2;
- const int invalid_csv_text = 3;
- const int invalid_state = 4;
-}
+ enum class csv_parser_errc : int
+ {
+ ok = 0,
+ unexpected_eof = 1,
+ expected_quote = 2,
+ invalid_csv_text = 3,
+ invalid_state = 4
+ };
class csv_error_category_impl
: public std::error_category
@@ -30,7 +31,7 @@ public:
}
virtual std::string message(int ev) const
{
- switch (ev)
+ switch (static_cast<csv_parser_errc>(ev))
{
case csv_parser_errc::unexpected_eof:
return "Unexpected end of file";
@@ -51,5 +52,19 @@ const std::error_category& csv_error_category()
return instance;
}
+inline
+std::error_code make_error_code(csv_parser_errc result)
+{
+ return std::error_code(static_cast<int>(result),csv_error_category());
+}
+
}}
+
+namespace std {
+ template<>
+ struct is_error_code_enum<jsoncons::csv::csv_parser_errc> : public true_type
+ {
+ };
+}
+
#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_parameters.hpp b/vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_parameters.hpp
new file mode 100644
index 00000000..61b635f3
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_parameters.hpp
@@ -0,0 +1,635 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_CSV_CSV_PARAMETERS_HPP
+#define JSONCONS_CSV_CSV_PARAMETERS_HPP
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <unordered_map>
+#include <istream>
+#include <ostream>
+#include <cstdlib>
+#include <limits>
+#include <cwchar>
+
+namespace jsoncons { namespace csv {
+
+namespace detail {
+ JSONCONS_DEFINE_LITERAL(string_literal,"string")
+ JSONCONS_DEFINE_LITERAL(integer_literal,"integer")
+ JSONCONS_DEFINE_LITERAL(float_literal,"float")
+ JSONCONS_DEFINE_LITERAL(boolean_literal,"boolean")
+}
+
+enum class csv_column_type
+{
+ string_t,integer_t,float_t,boolean_t,repeat_t
+};
+
+enum class quote_style_type
+{
+ all,minimal,none,nonnumeric
+};
+
+typedef quote_style_type quote_styles;
+
+enum class mapping_type
+{
+ n_rows,
+ n_objects,
+ m_columns
+};
+
+enum class column_state {sequence,label};
+
+struct csv_type_info
+{
+ csv_type_info() = default;
+ csv_type_info(const csv_type_info&) = default;
+ csv_type_info(csv_type_info&&) = default;
+
+ csv_type_info(csv_column_type ctype, size_t lev, size_t repcount = 0)
+ {
+ col_type = ctype;
+ level = lev;
+ rep_count = repcount;
+ }
+
+ csv_column_type col_type;
+ size_t level;
+ size_t rep_count;
+};
+
+template <class CharT,class Allocator=std::allocator<CharT>>
+class basic_csv_parameters
+{
+ typedef CharT char_type;
+ typedef Allocator allocator_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<CharT> char_allocator_type;
+ typedef std::basic_string<CharT,std::char_traits<CharT>,char_allocator_type> string_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<string_type> string_allocator_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<csv_type_info> csv_type_info_allocator_type;
+
+ bool assume_header_;
+ bool ignore_empty_values_;
+ bool ignore_empty_lines_;
+ bool trim_leading_;
+ bool trim_trailing_;
+ bool trim_leading_inside_quotes_;
+ bool trim_trailing_inside_quotes_;
+ bool unquoted_empty_value_is_null_;
+ CharT field_delimiter_;
+ CharT quote_char_;
+ CharT quote_escape_char_;
+ CharT comment_starter_;
+ quote_style_type quote_style_;
+ std::pair<mapping_type,bool> mapping_;
+ unsigned long max_lines_;
+ size_t header_lines_;
+ string_type line_delimiter_;
+ bool infer_types_;
+
+ std::vector<string_type,string_allocator_type> column_names_;
+ std::vector<csv_type_info,csv_type_info_allocator_type> column_types_;
+ std::vector<string_type,string_allocator_type> column_defaults_;
+public:
+ static const size_t default_indent = 4;
+
+// Constructors
+
+ basic_csv_parameters()
+ :
+ assume_header_(false),
+ ignore_empty_values_(false),
+ ignore_empty_lines_(true),
+ trim_leading_(false),
+ trim_trailing_(false),
+ trim_leading_inside_quotes_(false),
+ trim_trailing_inside_quotes_(false),
+ unquoted_empty_value_is_null_(false),
+ field_delimiter_(','),
+ quote_char_('\"'),
+ quote_escape_char_('\"'),
+ comment_starter_('\0'),
+ quote_style_(quote_style_type::minimal),
+ mapping_({mapping_type::n_rows,false}),
+ max_lines_((std::numeric_limits<unsigned long>::max)()),
+ header_lines_(0),
+ infer_types_(true)
+ {
+ line_delimiter_.push_back('\n');
+ }
+
+// Properties
+
+ size_t header_lines() const
+ {
+ return (assume_header_ && header_lines_ <= 1) ? 1 : header_lines_;
+ }
+
+ basic_csv_parameters& header_lines(size_t value)
+ {
+ header_lines_ = value;
+ return *this;
+ }
+
+ bool assume_header() const
+ {
+ return assume_header_;
+ }
+
+ basic_csv_parameters& assume_header(bool value)
+ {
+ assume_header_ = value;
+ return *this;
+ }
+
+ bool ignore_empty_values() const
+ {
+ return ignore_empty_values_;
+ }
+
+ basic_csv_parameters& ignore_empty_values(bool value)
+ {
+ ignore_empty_values_ = value;
+ return *this;
+ }
+
+ bool ignore_empty_lines() const
+ {
+ return ignore_empty_lines_;
+ }
+
+ basic_csv_parameters& ignore_empty_lines(bool value)
+ {
+ ignore_empty_lines_ = value;
+ return *this;
+ }
+
+ bool trim_leading() const
+ {
+ return trim_leading_;
+ }
+
+ basic_csv_parameters& trim_leading(bool value)
+ {
+ trim_leading_ = value;
+ return *this;
+ }
+
+ bool trim_trailing() const
+ {
+ return trim_trailing_;
+ }
+
+ basic_csv_parameters& trim_trailing(bool value)
+ {
+ trim_trailing_ = value;
+ return *this;
+ }
+
+ bool trim_leading_inside_quotes() const
+ {
+ return trim_leading_inside_quotes_;
+ }
+
+ basic_csv_parameters& trim_leading_inside_quotes(bool value)
+ {
+ trim_leading_inside_quotes_ = value;
+ return *this;
+ }
+
+ bool trim_trailing_inside_quotes() const
+ {
+ return trim_trailing_inside_quotes_;
+ }
+
+ basic_csv_parameters& trim_trailing_inside_quotes(bool value)
+ {
+ trim_trailing_inside_quotes_ = value;
+ return *this;
+ }
+
+ bool trim() const
+ {
+ return trim_leading_ && trim_trailing_;
+ }
+
+ basic_csv_parameters& trim(bool value)
+ {
+ trim_leading_ = value;
+ trim_trailing_ = value;
+ return *this;
+ }
+
+ bool trim_inside_quotes() const
+ {
+ return trim_leading_inside_quotes_ && trim_trailing_inside_quotes_;
+ }
+
+ basic_csv_parameters& trim_inside_quotes(bool value)
+ {
+ trim_leading_inside_quotes_ = value;
+ trim_trailing_inside_quotes_ = value;
+ return *this;
+ }
+
+ bool unquoted_empty_value_is_null() const
+ {
+ return unquoted_empty_value_is_null_;
+ }
+
+ basic_csv_parameters& unquoted_empty_value_is_null(bool value)
+ {
+ unquoted_empty_value_is_null_ = value;
+ return *this;
+ }
+
+ std::vector<string_type,string_allocator_type> column_names() const
+ {
+ return column_names_;
+ }
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+ basic_csv_parameters& column_names(const std::vector<string_type,string_allocator_type>& value)
+ {
+ column_names_ = value;
+ return *this;
+ }
+
+ basic_csv_parameters& column_defaults(const std::vector<string_type,string_allocator_type>& value)
+ {
+ column_defaults_ = value;
+ return *this;
+ }
+
+ basic_csv_parameters& column_types(const std::vector<string_type,string_allocator_type>& value)
+ {
+ if (value.size() > 0)
+ {
+ column_types_.reserve(value.size());
+ for (size_t i = 0; i < value.size(); ++i)
+ {
+ if (value[i] == detail::string_literal<CharT>()())
+ {
+ column_types_.emplace_back(csv_column_type::string_t,0);
+ }
+ else if (value[i] == detail::integer_literal<CharT>()())
+ {
+ column_types_.emplace_back(csv_column_type::integer_t,0);
+ }
+ else if (value[i] == detail::float_literal<CharT>()())
+ {
+ column_types_.emplace_back(csv_column_type::float_t,0);
+ }
+ else if (value[i] == detail::boolean_literal<CharT>()())
+ {
+ column_types_.emplace_back(csv_column_type::boolean_t,0);
+ }
+ }
+ }
+ return *this;
+ }
+#endif
+ basic_csv_parameters& column_names(const string_type& names)
+ {
+ column_names_ = parse_column_names(names);
+ return *this;
+ }
+
+ std::vector<csv_type_info,csv_type_info_allocator_type> column_types() const
+ {
+ return column_types_;
+ }
+
+ basic_csv_parameters& column_types(const string_type& types)
+ {
+ column_types_ = parse_column_types(types);
+ return *this;
+ }
+
+ std::vector<string_type,string_allocator_type> column_defaults() const
+ {
+ return column_defaults_;
+ }
+
+ basic_csv_parameters& column_defaults(const string_type& defaults)
+ {
+ column_defaults_ = parse_column_names(defaults);
+ return *this;
+ }
+
+ CharT field_delimiter() const
+ {
+ return field_delimiter_;
+ }
+
+ basic_csv_parameters& field_delimiter(CharT value)
+ {
+ field_delimiter_ = value;
+ return *this;
+ }
+
+ string_type line_delimiter() const
+ {
+ return line_delimiter_;
+ }
+
+ basic_csv_parameters& line_delimiter(string_type value)
+ {
+ line_delimiter_ = value;
+ return *this;
+ }
+
+ CharT quote_char() const
+ {
+ return quote_char_;
+ }
+
+ basic_csv_parameters& quote_char(CharT value)
+ {
+ quote_char_ = value;
+ return *this;
+ }
+
+ bool infer_types() const
+ {
+ return infer_types_;
+ }
+
+ basic_csv_parameters& infer_types(bool value)
+ {
+ infer_types_ = value;
+ return *this;
+ }
+
+ CharT quote_escape_char() const
+ {
+ return quote_escape_char_;
+ }
+
+ basic_csv_parameters& quote_escape_char(CharT value)
+ {
+ quote_escape_char_ = value;
+ return *this;
+ }
+
+ CharT comment_starter() const
+ {
+ return comment_starter_;
+ }
+
+ basic_csv_parameters& comment_starter(CharT value)
+ {
+ comment_starter_ = value;
+ return *this;
+ }
+
+ quote_style_type quote_style() const
+ {
+ return quote_style_;
+ }
+
+ mapping_type mapping() const
+ {
+ return mapping_.second ? (mapping_.first) : (assume_header() || column_names_.size() > 0 ? mapping_type::n_objects : mapping_type::n_rows);
+ }
+
+ basic_csv_parameters& quote_style(quote_style_type value)
+ {
+ quote_style_ = value;
+ return *this;
+ }
+
+ basic_csv_parameters& mapping(mapping_type value)
+ {
+ mapping_ = {value,true};
+ return *this;
+ }
+
+ unsigned long max_lines() const
+ {
+ return max_lines_;
+ }
+
+ basic_csv_parameters& max_lines(unsigned long value)
+ {
+ max_lines_ = value;
+ return *this;
+ }
+
+ static std::vector<string_type,string_allocator_type> parse_column_names(const string_type& names)
+ {
+ std::vector<string_type,string_allocator_type> column_names;
+
+ column_state state = column_state::sequence;
+ string_type buffer;
+
+ auto p = names.begin();
+ while (p != names.end())
+ {
+ switch (state)
+ {
+ case column_state::sequence:
+ {
+ switch (*p)
+ {
+ case ' ': case '\t':case '\r': case '\n':
+ ++p;
+ break;
+ default:
+ buffer.clear();
+ state = column_state::label;
+ break;
+ }
+ break;
+ }
+ case column_state::label:
+ {
+ switch (*p)
+ {
+ case ',':
+ column_names.push_back(buffer);
+ buffer.clear();
+ ++p;
+ state = column_state::sequence;
+ break;
+ default:
+ buffer.push_back(*p);
+ ++p;
+ break;
+ }
+ break;
+ }
+ }
+ }
+ if (state == column_state::label)
+ {
+ column_names.push_back(buffer);
+ buffer.clear();
+ }
+ return column_names;
+ }
+
+ static std::vector<csv_type_info,csv_type_info_allocator_type> parse_column_types(const string_type& types)
+ {
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<std::pair<const string_type,csv_column_type>> pair_allocator_type;
+
+ const std::unordered_map<string_type,csv_column_type, std::hash<string_type>,std::equal_to<string_type>,pair_allocator_type> type_dictionary =
+ {
+
+ {detail::string_literal<char_type>(),csv_column_type::string_t},
+ {detail::integer_literal<char_type>(),csv_column_type::integer_t},
+ {detail::float_literal<char_type>(),csv_column_type::float_t},
+ {detail::boolean_literal<char_type>(),csv_column_type::boolean_t}
+ };
+
+ std::vector<csv_type_info,csv_type_info_allocator_type> column_types;
+
+ column_state state = column_state::sequence;
+ int depth = 0;
+ string_type buffer;
+
+ auto p = types.begin();
+ while (p != types.end())
+ {
+ switch (state)
+ {
+ case column_state::sequence:
+ {
+ switch (*p)
+ {
+ case ' ': case '\t':case '\r': case '\n':
+ ++p;
+ break;
+ case '[':
+ ++depth;
+ ++p;
+ break;
+ case ']':
+ JSONCONS_ASSERT(depth > 0);
+ --depth;
+ ++p;
+ break;
+ case '*':
+ {
+ JSONCONS_ASSERT(column_types.size() != 0);
+ size_t offset = 0;
+ size_t level = column_types.size() > 0 ? column_types.back().level: 0;
+ if (level > 0)
+ {
+ for (auto it = column_types.rbegin();
+ it != column_types.rend() && level == it->level;
+ ++it)
+ {
+ ++offset;
+ }
+ }
+ else
+ {
+ offset = 1;
+ }
+ column_types.emplace_back(csv_column_type::repeat_t,depth,offset);
+ ++p;
+ break;
+ }
+ default:
+ buffer.clear();
+ state = column_state::label;
+ break;
+ }
+ break;
+ }
+ case column_state::label:
+ {
+ switch (*p)
+ {
+ case '*':
+ {
+ auto it = type_dictionary.find(buffer);
+ if (it != type_dictionary.end())
+ {
+ column_types.emplace_back(it->second,depth);
+ buffer.clear();
+ }
+ else
+ {
+ JSONCONS_ASSERT(false);
+ }
+ state = column_state::sequence;
+ }
+ break;
+ case ',':
+ {
+ auto it = type_dictionary.find(buffer);
+ if (it != type_dictionary.end())
+ {
+ column_types.emplace_back(it->second,depth);
+ buffer.clear();
+ }
+ else
+ {
+ JSONCONS_ASSERT(false);
+ }
+ ++p;
+ state = column_state::sequence;
+ }
+ break;
+ case ']':
+ {
+ JSONCONS_ASSERT(depth > 0);
+ auto it = type_dictionary.find(buffer);
+ if (it != type_dictionary.end())
+ {
+ column_types.emplace_back(it->second,depth);
+ buffer.clear();
+ }
+ else
+ {
+ JSONCONS_ASSERT(false);
+ }
+ --depth;
+ ++p;
+ state = column_state::sequence;
+ }
+ break;
+ default:
+ {
+ buffer.push_back(*p);
+ ++p;
+ }
+ break;
+ }
+ break;
+ }
+ }
+ }
+ if (state == column_state::label)
+ {
+ auto it = type_dictionary.find(buffer);
+ if (it != type_dictionary.end())
+ {
+ column_types.emplace_back(it->second,depth);
+ buffer.clear();
+ }
+ else
+ {
+ JSONCONS_ASSERT(false);
+ }
+ }
+ return column_types;
+ }
+
+};
+
+typedef basic_csv_parameters<char> csv_parameters;
+typedef basic_csv_parameters<wchar_t> wcsv_parameters;
+
+
+}}
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_parser.hpp b/vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_parser.hpp
new file mode 100644
index 00000000..c870c28b
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_parser.hpp
@@ -0,0 +1,1260 @@
+// Copyright 2015 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_CSV_CSV_PARSER_HPP
+#define JSONCONS_CSV_CSV_PARSER_HPP
+
+#include <memory>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <cstdlib>
+#include <stdexcept>
+#include <system_error>
+#include <cctype>
+#include <jsoncons/json_exception.hpp>
+#include <jsoncons/json_input_handler.hpp>
+#include <jsoncons/parse_error_handler.hpp>
+#include <jsoncons/json_reader.hpp>
+#include <jsoncons/json_filter.hpp>
+#include <jsoncons/json.hpp>
+#include <jsoncons/detail/number_parsers.hpp>
+#include <jsoncons_ext/csv/csv_error_category.hpp>
+#include <jsoncons_ext/csv/csv_parameters.hpp>
+
+namespace jsoncons { namespace csv {
+
+enum class csv_mode_type
+{
+ initial,
+ header,
+ data
+};
+
+enum class csv_state_type
+{
+ start,
+ comment,
+ expect_value,
+ between_fields,
+ quoted_string,
+ unquoted_string,
+ escaped_value,
+ minus,
+ zero,
+ integer,
+ fraction,
+ exp1,
+ exp2,
+ exp3,
+ done
+};
+
+template<class CharT,class Allocator=std::allocator<CharT>>
+class basic_csv_parser : private parsing_context
+{
+ typedef basic_string_view_ext<CharT> string_view_type;
+ typedef CharT char_type;
+ typedef Allocator allocator_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<CharT> char_allocator_type;
+ typedef std::basic_string<CharT,std::char_traits<CharT>,char_allocator_type> string_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<string_type> string_allocator_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<csv_mode_type> csv_mode_allocator_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<csv_type_info> csv_type_info_allocator_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<std::vector<string_type,string_allocator_type>> string_vector_allocator_type;
+ typedef basic_json<CharT,preserve_order_policy,Allocator> json_type;
+
+ static const int default_depth = 3;
+
+ default_parse_error_handler default_err_handler_;
+ csv_state_type state_;
+ int top_;
+ std::vector<csv_mode_type,csv_mode_allocator_type> stack_;
+ basic_json_input_handler<CharT>& handler_;
+ parse_error_handler& err_handler_;
+ size_t index_;
+ unsigned long column_;
+ unsigned long line_;
+ CharT curr_char_;
+ CharT prev_char_;
+ string_type value_buffer_;
+ int depth_;
+ basic_csv_parameters<CharT,Allocator> parameters_;
+ std::vector<string_type,string_allocator_type> column_names_;
+ std::vector<std::vector<string_type,string_allocator_type>,string_vector_allocator_type> column_values_;
+ std::vector<csv_type_info,csv_type_info_allocator_type> column_types_;
+ std::vector<string_type,string_allocator_type> column_defaults_;
+ size_t column_index_;
+ basic_json_fragment_filter<CharT> filter_;
+ size_t level_;
+ size_t offset_;
+ jsoncons::detail::string_to_double to_double_;
+ std::vector<json_decoder<json_type>> decoders_;
+
+public:
+ basic_csv_parser(basic_json_input_handler<CharT>& handler)
+ : top_(-1),
+ stack_(default_depth),
+ handler_(handler),
+ err_handler_(default_err_handler_),
+ index_(0),
+ filter_(handler),
+ level_(0),
+ offset_(0)
+ {
+ depth_ = default_depth;
+ state_ = csv_state_type::start;
+ top_ = -1;
+ line_ = 1;
+ column_ = 0;
+ column_index_ = 0;
+ }
+
+ basic_csv_parser(basic_json_input_handler<CharT>& handler,
+ basic_csv_parameters<CharT,Allocator> params)
+ : top_(-1),
+ stack_(default_depth),
+ handler_(handler),
+ err_handler_(default_err_handler_),
+ index_(0),
+ parameters_(params),
+ filter_(handler),
+ level_(0),
+ offset_(0)
+ {
+ depth_ = default_depth;
+ state_ = csv_state_type::start;
+ top_ = -1;
+ line_ = 1;
+ column_ = 0;
+ column_index_ = 0;
+ }
+
+ basic_csv_parser(basic_json_input_handler<CharT>& handler,
+ parse_error_handler& err_handler)
+ : top_(-1),
+ stack_(default_depth),
+ handler_(handler),
+ err_handler_(err_handler),
+ index_(0),
+ filter_(handler),
+ level_(0),
+ offset_(0)
+ {
+ depth_ = default_depth;
+ state_ = csv_state_type::start;
+ top_ = -1;
+ line_ = 1;
+ column_ = 0;
+ column_index_ = 0;
+ }
+
+ basic_csv_parser(basic_json_input_handler<CharT>& handler,
+ parse_error_handler& err_handler,
+ basic_csv_parameters<CharT,Allocator> params)
+ : top_(-1),
+ stack_(default_depth),
+ handler_(handler),
+ err_handler_(err_handler),
+ index_(0),
+ parameters_(params),
+ filter_(handler),
+ level_(0),
+ offset_(0)
+ {
+ depth_ = default_depth;
+ state_ = csv_state_type::start;
+ top_ = -1;
+ line_ = 1;
+ column_ = 0;
+ column_index_ = 0;
+ }
+
+ ~basic_csv_parser()
+ {
+ }
+
+ const parsing_context& parsing_context() const
+ {
+ return *this;
+ }
+
+ bool done() const
+ {
+ return state_ == csv_state_type::done;
+ }
+
+ const std::vector<std::basic_string<CharT>>& column_labels() const
+ {
+ return column_names_;
+ }
+
+ void after_field()
+ {
+ ++column_index_;
+ }
+
+ void before_record()
+ {
+ offset_ = 0;
+ if (stack_[top_] == csv_mode_type::data)
+ {
+ switch (parameters_.mapping())
+ {
+ case mapping_type::n_rows:
+ handler_.begin_array(*this);
+ break;
+ case mapping_type::n_objects:
+ handler_.begin_object(*this);
+ break;
+ case mapping_type::m_columns:
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ void after_record()
+ {
+ if (column_types_.size() > 0)
+ {
+ if (level_ > 0)
+ {
+ handler_.end_array(*this);
+ level_ = 0;
+ }
+ }
+ if (stack_[top_] == csv_mode_type::header)
+ {
+ if (line_ >= parameters_.header_lines())
+ {
+ flip(csv_mode_type::header, csv_mode_type::data);
+ }
+ column_values_.resize(column_names_.size());
+ switch (parameters_.mapping())
+ {
+ case mapping_type::n_rows:
+ if (column_names_.size() > 0)
+ {
+ handler_.begin_array(*this);
+ for (const auto& name : column_names_)
+ {
+ handler_.string_value(name, *this);
+ }
+ handler_.end_array(*this);
+ }
+ break;
+ case mapping_type::m_columns:
+ for (const auto& name : column_names_)
+ {
+ decoders_.push_back(json_decoder<json_type>());
+ decoders_.back().begin_json();
+ decoders_.back().begin_array(*this);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ else if (stack_[top_] == csv_mode_type::data)
+ {
+ switch (parameters_.mapping())
+ {
+ case mapping_type::n_rows:
+ handler_.end_array(*this);
+ break;
+ case mapping_type::n_objects:
+ handler_.end_object(*this);
+ break;
+ default:
+ break;
+ }
+ }
+ column_index_ = 0;
+ }
+
+ void reset()
+ {
+ push_mode(csv_mode_type::initial);
+ handler_.begin_json();
+
+ for (auto name : parameters_.column_names())
+ {
+ column_names_.emplace_back(name.data(),name.size());
+ }
+ for (auto name : parameters_.column_types())
+ {
+ column_types_.push_back(name);
+ }
+ for (auto name : parameters_.column_defaults())
+ {
+ column_defaults_.emplace_back(name.data(), name.size());
+ }
+ if (parameters_.header_lines() > 0)
+ {
+ push_mode(csv_mode_type::header);
+ }
+ else
+ {
+ push_mode(csv_mode_type::data);
+ }
+ if (parameters_.mapping() != mapping_type::m_columns)
+ {
+ handler_.begin_array(*this);
+ }
+ state_ = csv_state_type::expect_value;
+ column_index_ = 0;
+ prev_char_ = 0;
+ curr_char_ = 0;
+ column_ = 1;
+ level_ = 0;
+ }
+
+ void parse(const CharT* p, size_t start, size_t length)
+ {
+ std::error_code ec;
+ parse(p, start, length, ec);
+ if (ec)
+ {
+ throw parse_error(ec,line_,column_);
+ }
+ }
+
+ void parse(const CharT* p, size_t start, size_t length, std::error_code& ec)
+ {
+ index_ = start;
+ for (; index_ < length && state_ != csv_state_type::done; ++index_)
+ {
+ curr_char_ = p[index_];
+all_csv_states:
+ switch (state_)
+ {
+ case csv_state_type::comment:
+ if (curr_char_ == '\n')
+ {
+ state_ = csv_state_type::expect_value;
+ }
+ else if (prev_char_ == '\r')
+ {
+ state_ = csv_state_type::expect_value;
+ goto all_csv_states;
+ }
+ break;
+ case csv_state_type::expect_value:
+ if (column_ == 1 && curr_char_ == parameters_.comment_starter())
+ {
+ state_ = csv_state_type::comment;
+ }
+ else
+ {
+ state_ = csv_state_type::unquoted_string;
+ goto all_csv_states;
+ }
+ break;
+ case csv_state_type::between_fields:
+ if (curr_char_ == '\r' || (prev_char_ != '\r' && curr_char_ == '\n'))
+ {
+ after_record();
+ state_ = csv_state_type::expect_value;
+ }
+ else if (curr_char_ == parameters_.field_delimiter())
+ {
+ state_ = csv_state_type::expect_value;
+ }
+ break;
+ case csv_state_type::escaped_value:
+ {
+ if (curr_char_ == parameters_.quote_char())
+ {
+ value_buffer_.push_back(static_cast<CharT>(curr_char_));
+ state_ = csv_state_type::quoted_string;
+ }
+ else if (parameters_.quote_escape_char() == parameters_.quote_char())
+ {
+ if (column_index_ == 0)
+ {
+ before_record();
+ }
+ end_quoted_string_value(ec);
+ if (ec) return;
+ after_field();
+ state_ = csv_state_type::between_fields;
+ goto all_csv_states;
+ }
+ }
+ break;
+ case csv_state_type::quoted_string:
+ {
+ if (curr_char_ == parameters_.quote_escape_char())
+ {
+ state_ = csv_state_type::escaped_value;
+ }
+ else if (curr_char_ == parameters_.quote_char())
+ {
+ if (column_index_ == 0)
+ {
+ before_record();
+ }
+ end_quoted_string_value(ec);
+ if (ec) return;
+ after_field();
+ state_ = csv_state_type::between_fields;
+ }
+ else
+ {
+ value_buffer_.push_back(static_cast<CharT>(curr_char_));
+ }
+ }
+ break;
+ case csv_state_type::unquoted_string:
+ {
+ if (curr_char_ == '\r' || (prev_char_ != '\r' && curr_char_ == '\n'))
+ {
+ if (parameters_.trim_leading() || parameters_.trim_trailing())
+ {
+ trim_string_buffer(parameters_.trim_leading(),parameters_.trim_trailing());
+ }
+ if (!parameters_.ignore_empty_lines() || (column_index_ > 0 || value_buffer_.length() > 0))
+ {
+ if (column_index_ == 0)
+ {
+ before_record();
+ }
+ end_unquoted_string_value();
+ after_field();
+ after_record();
+ }
+ state_ = csv_state_type::expect_value;
+ }
+ else if (curr_char_ == '\n')
+ {
+ if (prev_char_ != '\r')
+ {
+ if (parameters_.trim_leading() || parameters_.trim_trailing())
+ {
+ trim_string_buffer(parameters_.trim_leading(),parameters_.trim_trailing());
+ }
+ if (!parameters_.ignore_empty_lines() || (column_index_ > 0 || value_buffer_.length() > 0))
+ {
+ if (column_index_ == 0)
+ {
+ before_record();
+ }
+ end_unquoted_string_value();
+ after_field();
+ after_record();
+ }
+ state_ = csv_state_type::expect_value;
+ }
+ }
+ else if (curr_char_ == parameters_.field_delimiter())
+ {
+ if (parameters_.trim_leading() || parameters_.trim_trailing())
+ {
+ trim_string_buffer(parameters_.trim_leading(),parameters_.trim_trailing());
+ }
+ if (column_index_ == 0)
+ {
+ before_record();
+ }
+ end_unquoted_string_value();
+ after_field();
+ state_ = csv_state_type::expect_value;
+ }
+ else if (curr_char_ == parameters_.quote_char())
+ {
+ value_buffer_.clear();
+ state_ = csv_state_type::quoted_string;
+ }
+ else
+ {
+ value_buffer_.push_back(static_cast<CharT>(curr_char_));
+ }
+ }
+ break;
+ default:
+ err_handler_.fatal_error(csv_parser_errc::invalid_state, *this);
+ ec = csv_parser_errc::invalid_state;
+ return;
+ }
+ if (line_ > parameters_.max_lines())
+ {
+ state_ = csv_state_type::done;
+ }
+ switch (curr_char_)
+ {
+ case '\r':
+ ++line_;
+ column_ = 1;
+ break;
+ case '\n':
+ if (prev_char_ != '\r')
+ {
+ ++line_;
+ }
+ column_ = 1;
+ break;
+ default:
+ ++column_;
+ break;
+ }
+ prev_char_ = curr_char_;
+ }
+ }
+
+ void end_parse()
+ {
+ std::error_code ec;
+ end_parse(ec);
+ if (ec)
+ {
+ throw parse_error(ec,line_,column_);
+ }
+ }
+
+ void end_parse(std::error_code& ec)
+ {
+ switch (state_)
+ {
+ case csv_state_type::unquoted_string:
+ if (parameters_.trim_leading() || parameters_.trim_trailing())
+ {
+ trim_string_buffer(parameters_.trim_leading(),parameters_.trim_trailing());
+ }
+ if (!parameters_.ignore_empty_lines() || (column_index_ > 0 || value_buffer_.length() > 0))
+ {
+ if (column_index_ == 0)
+ {
+ before_record();
+ }
+ end_unquoted_string_value();
+ after_field();
+ }
+ break;
+ case csv_state_type::escaped_value:
+ if (parameters_.quote_escape_char() == parameters_.quote_char())
+ {
+ if (column_index_ == 0)
+ {
+ before_record();
+ }
+ end_quoted_string_value(ec);
+ if (ec) return;
+ after_field();
+ }
+ break;
+ default:
+ break;
+ }
+ if (column_index_ > 0)
+ {
+ after_record();
+ }
+ switch (stack_[top_])
+ {
+ case csv_mode_type::header:
+ pop_mode(csv_mode_type::header);
+ break;
+ case csv_mode_type::data:
+ pop_mode(csv_mode_type::data);
+ break;
+ default:
+ break;
+ }
+ if (parameters_.mapping() == mapping_type::m_columns)
+ {
+ basic_json_fragment_filter<CharT> fragment_filter(handler_);
+ handler_.begin_object(*this);
+ for (size_t i = 0; i < column_names_.size(); ++i)
+ {
+ handler_.name(column_names_[i],*this);
+ decoders_[i].end_array(*this);
+ decoders_[i].end_json();
+ decoders_[i].get_result().dump_fragment(fragment_filter);
+ }
+ handler_.end_object(*this);
+ }
+ else
+ {
+ handler_.end_array(*this);
+ }
+ if (!pop_mode(csv_mode_type::initial))
+ {
+ err_handler_.fatal_error(csv_parser_errc::unexpected_eof, *this);
+ ec = csv_parser_errc::unexpected_eof;
+ return;
+ }
+ handler_.end_json();
+ }
+
+ csv_state_type state() const
+ {
+ return state_;
+ }
+
+ size_t index() const
+ {
+ return index_;
+ }
+private:
+
+ void trim_string_buffer(bool trim_leading, bool trim_trailing)
+ {
+ size_t start = 0;
+ size_t length = value_buffer_.length();
+ if (trim_leading)
+ {
+ bool done = false;
+ while (!done && start < value_buffer_.length())
+ {
+ if ((value_buffer_[start] < 256) && std::isspace(value_buffer_[start]))
+ {
+ ++start;
+ }
+ else
+ {
+ done = true;
+ }
+ }
+ }
+ if (trim_trailing)
+ {
+ bool done = false;
+ while (!done && length > 0)
+ {
+ if ((value_buffer_[length-1] < 256) && std::isspace(value_buffer_[length-1]))
+ {
+ --length;
+ }
+ else
+ {
+ done = true;
+ }
+ }
+ }
+ if (start != 0 || length != value_buffer_.size())
+ {
+ value_buffer_ = value_buffer_.substr(start,length-start);
+ }
+ }
+
+ void end_unquoted_string_value()
+ {
+ switch (stack_[top_])
+ {
+ case csv_mode_type::header:
+ if (parameters_.assume_header() && line_ == 1)
+ {
+ column_names_.push_back(value_buffer_);
+ }
+ break;
+ case csv_mode_type::data:
+ switch (parameters_.mapping())
+ {
+ case mapping_type::n_rows:
+ if (parameters_.unquoted_empty_value_is_null() && value_buffer_.length() == 0)
+ {
+ handler_.null_value(*this);
+ }
+ else
+ {
+ end_value(value_buffer_,column_index_,parameters_.infer_types(),handler_);
+ }
+ break;
+ case mapping_type::n_objects:
+ if (!(parameters_.ignore_empty_values() && value_buffer_.size() == 0))
+ {
+ if (column_index_ < column_names_.size() + offset_)
+ {
+ handler_.name(column_names_[column_index_ - offset_], *this);
+ if (parameters_.unquoted_empty_value_is_null() && value_buffer_.length() == 0)
+ {
+ handler_.null_value(*this);
+ }
+ else
+ {
+ end_value(value_buffer_,column_index_,parameters_.infer_types(),handler_);
+ }
+ }
+ else if (level_ > 0)
+ {
+ if (parameters_.unquoted_empty_value_is_null() && value_buffer_.length() == 0)
+ {
+ handler_.null_value(*this);
+ }
+ else
+ {
+ end_value(value_buffer_,column_index_,parameters_.infer_types(),handler_);
+ }
+ }
+ }
+ break;
+ case mapping_type::m_columns:
+ if (column_index_ < decoders_.size())
+ {
+ end_value(value_buffer_,column_index_,parameters_.infer_types(),decoders_[column_index_]);
+ }
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ state_ = csv_state_type::expect_value;
+ value_buffer_.clear();
+ }
+
+ void end_quoted_string_value(std::error_code& ec)
+ {
+ if (parameters_.trim_leading_inside_quotes() | parameters_.trim_trailing_inside_quotes())
+ {
+ trim_string_buffer(parameters_.trim_leading_inside_quotes(),parameters_.trim_trailing_inside_quotes());
+ }
+ switch (stack_[top_])
+ {
+ case csv_mode_type::header:
+ if (parameters_.assume_header() && line_ == 1)
+ {
+ column_names_.push_back(value_buffer_);
+ }
+ break;
+ case csv_mode_type::data:
+ switch (parameters_.mapping())
+ {
+ case mapping_type::n_rows:
+ end_value(value_buffer_,column_index_,false,handler_);
+ break;
+ case mapping_type::n_objects:
+ if (!(parameters_.ignore_empty_values() && value_buffer_.size() == 0))
+ {
+ if (column_index_ < column_names_.size() + offset_)
+ {
+ handler_.name(column_names_[column_index_ - offset_], *this);
+ if (parameters_.unquoted_empty_value_is_null() && value_buffer_.length() == 0)
+ {
+ handler_.null_value(*this);
+ }
+ else
+ {
+ end_value(value_buffer_,column_index_,false,handler_);
+ }
+ }
+ else if (level_ > 0)
+ {
+ if (parameters_.unquoted_empty_value_is_null() && value_buffer_.length() == 0)
+ {
+ handler_.null_value(*this);
+ }
+ else
+ {
+ end_value(value_buffer_,column_index_,false,handler_);
+ }
+ }
+ }
+ break;
+ case mapping_type::m_columns:
+ if (column_index_ < decoders_.size())
+ {
+ end_value(value_buffer_,column_index_,parameters_.infer_types(),decoders_[column_index_]);
+ }
+ break;
+ }
+ break;
+ default:
+ err_handler_.fatal_error(csv_parser_errc::invalid_csv_text, *this);
+ ec = csv_parser_errc::invalid_csv_text;
+ return;
+ }
+ state_ = csv_state_type::expect_value;
+ value_buffer_.clear();
+ }
+
+ void end_value(const string_view_type& value, size_t column_index, bool infer_types, basic_json_input_handler<CharT>& handler)
+ {
+ if (column_index < column_types_.size() + offset_)
+ {
+ if (column_types_[column_index - offset_].col_type == csv_column_type::repeat_t)
+ {
+ offset_ = offset_ + column_types_[column_index - offset_].rep_count;
+ if (column_index - offset_ + 1 < column_types_.size())
+ {
+ if (column_index == offset_ || level_ > column_types_[column_index-offset_].level)
+ {
+ handler.end_array(*this);
+ }
+ level_ = column_index == offset_ ? 0 : column_types_[column_index - offset_].level;
+ }
+ }
+ if (level_ < column_types_[column_index - offset_].level)
+ {
+ handler.begin_array(*this);
+ level_ = column_types_[column_index - offset_].level;
+ }
+ else if (level_ > column_types_[column_index - offset_].level)
+ {
+ handler.end_array(*this);
+ level_ = column_types_[column_index - offset_].level;
+ }
+ switch (column_types_[column_index - offset_].col_type)
+ {
+ case csv_column_type::integer_t:
+ {
+ std::istringstream iss{ std::string(value) };
+ int64_t val;
+ iss >> val;
+ if (!iss.fail())
+ {
+ handler.integer_value(val, *this);
+ }
+ else
+ {
+ if (column_index - offset_ < column_defaults_.size() && column_defaults_[column_index - offset_].length() > 0)
+ {
+ basic_json_parser<CharT> parser(filter_,err_handler_);
+ parser.set_source(column_defaults_[column_index - offset_].data(),column_defaults_[column_index - offset_].length());
+ parser.parse_some();
+ parser.end_parse();
+ }
+ else
+ {
+ handler.null_value(*this);
+ }
+ }
+ }
+ break;
+ case csv_column_type::float_t:
+ {
+ std::istringstream iss{ std::string(value) };
+ double val;
+ iss >> val;
+ if (!iss.fail())
+ {
+ handler.double_value(val, *this);
+ }
+ else
+ {
+ if (column_index - offset_ < column_defaults_.size() && column_defaults_[column_index - offset_].length() > 0)
+ {
+ basic_json_parser<CharT> parser(filter_,err_handler_);
+ parser.set_source(column_defaults_[column_index - offset_].data(),column_defaults_[column_index - offset_].length());
+ parser.parse_some();
+ parser.end_parse();
+ }
+ else
+ {
+ handler.null_value(*this);
+ }
+ }
+ }
+ break;
+ case csv_column_type::boolean_t:
+ {
+ if (value.length() == 1 && value[0] == '0')
+ {
+ handler.bool_value(false, *this);
+ }
+ else if (value.length() == 1 && value[0] == '1')
+ {
+ handler.bool_value(true, *this);
+ }
+ else if (value.length() == 5 && ((value[0] == 'f' || value[0] == 'F') && (value[1] == 'a' || value[1] == 'A') && (value[2] == 'l' || value[2] == 'L') && (value[3] == 's' || value[3] == 'S') && (value[4] == 'e' || value[4] == 'E')))
+ {
+ handler.bool_value(false, *this);
+ }
+ else if (value.length() == 4 && ((value[0] == 't' || value[0] == 'T') && (value[1] == 'r' || value[1] == 'R') && (value[2] == 'u' || value[2] == 'U') && (value[3] == 'e' || value[3] == 'E')))
+ {
+ handler.bool_value(true, *this);
+ }
+ else
+ {
+ if (column_index - offset_ < column_defaults_.size() && column_defaults_[column_index - offset_].length() > 0)
+ {
+ basic_json_parser<CharT> parser(filter_,err_handler_);
+ parser.set_source(column_defaults_[column_index - offset_].data(),column_defaults_[column_index - offset_].length());
+ parser.parse_some();
+ parser.end_parse();
+ }
+ else
+ {
+ handler.null_value(*this);
+ }
+ }
+ }
+ break;
+ default:
+ if (value.length() > 0)
+ {
+ handler.string_value(value, *this);
+ }
+ else
+ {
+ if (column_index < column_defaults_.size() + offset_ && column_defaults_[column_index - offset_].length() > 0)
+ {
+ basic_json_parser<CharT> parser(filter_,err_handler_);
+ parser.set_source(column_defaults_[column_index - offset_].data(),column_defaults_[column_index - offset_].length());
+ parser.parse_some();
+ parser.end_parse();
+ }
+ else
+ {
+ handler.string_value(string_view_type(), *this);
+ }
+ }
+ break;
+ }
+ }
+ else
+ {
+ if (infer_types)
+ {
+ end_value_with_numeric_check(value, handler);
+ }
+ else
+ {
+ handler.string_value(value, *this);
+ }
+ }
+ }
+
+ enum class numeric_check_state
+ {
+ initial,
+ null,
+ boolean_true,
+ boolean_false,
+ minus,
+ zero,
+ integer,
+ fraction1,
+ fraction,
+ exp1,
+ exp,
+ done
+ };
+
+ void end_value_with_numeric_check(const string_view_type& value, basic_json_input_handler<CharT>& handler)
+ {
+ numeric_check_state state = numeric_check_state::initial;
+ bool is_negative = false;
+ uint8_t precision = 0;
+ uint8_t decimal_places = 0;
+ chars_format format = chars_format::general;
+
+ auto last = value.end();
+
+ std::string buffer;
+ for (auto p = value.begin(); state != numeric_check_state::done && p != last; ++p)
+ {
+ switch (state)
+ {
+ case numeric_check_state::initial:
+ {
+ switch (*p)
+ {
+ case 'n':case 'N':
+ if ((last-p) == 4 && (p[1] == 'u' || p[1] == 'U') && (p[2] == 'l' || p[2] == 'L') && (p[3] == 'l' || p[3] == 'L'))
+ {
+ state = numeric_check_state::null;
+ }
+ else
+ {
+ state = numeric_check_state::done;
+ }
+ break;
+ case 't':case 'T':
+ if ((last-p) == 4 && (p[1] == 'r' || p[1] == 'R') && (p[2] == 'u' || p[2] == 'U') && (p[3] == 'e' || p[3] == 'U'))
+ {
+ state = numeric_check_state::boolean_true;
+ }
+ else
+ {
+ state = numeric_check_state::done;
+ }
+ break;
+ case 'f':case 'F':
+ if ((last-p) == 5 && (p[1] == 'a' || p[1] == 'A') && (p[2] == 'l' || p[2] == 'L') && (p[3] == 's' || p[3] == 'S') && (p[4] == 'e' || p[4] == 'E'))
+ {
+ state = numeric_check_state::boolean_false;
+ }
+ else
+ {
+ state = numeric_check_state::done;
+ }
+ break;
+ case '-':
+ is_negative = true;
+ buffer.push_back(*p);
+ state = numeric_check_state::minus;
+ break;
+ case '0':
+ ++precision;
+ buffer.push_back(*p);
+ state = numeric_check_state::zero;
+ break;
+ case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
+ ++precision;
+ buffer.push_back(*p);
+ state = numeric_check_state::integer;
+ break;
+ default:
+ state = numeric_check_state::done;
+ break;
+ }
+ break;
+ }
+ case numeric_check_state::zero:
+ {
+ switch (*p)
+ {
+ case '.':
+ buffer.push_back(to_double_.get_decimal_point());
+ state = numeric_check_state::fraction1;
+ break;
+ case 'e':case 'E':
+ buffer.push_back(*p);
+ state = numeric_check_state::exp1;
+ break;
+ default:
+ state = numeric_check_state::done;
+ break;
+ }
+ break;
+ }
+ case numeric_check_state::integer:
+ {
+ switch (*p)
+ {
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
+ ++precision;
+ buffer.push_back(*p);
+ break;
+ case '.':
+ buffer.push_back(to_double_.get_decimal_point());
+ state = numeric_check_state::fraction1;
+ break;
+ case 'e':case 'E':
+ buffer.push_back(*p);
+ state = numeric_check_state::exp1;
+ break;
+ default:
+ state = numeric_check_state::done;
+ break;
+ }
+ break;
+ }
+ case numeric_check_state::minus:
+ {
+ switch (*p)
+ {
+ case '0':
+ ++precision;
+ buffer.push_back(*p);
+ state = numeric_check_state::zero;
+ break;
+ case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
+ ++precision;
+ buffer.push_back(*p);
+ state = numeric_check_state::integer;
+ break;
+ case 'e':case 'E':
+ buffer.push_back(*p);
+ state = numeric_check_state::exp1;
+ break;
+ default:
+ state = numeric_check_state::done;
+ break;
+ }
+ break;
+ }
+ case numeric_check_state::fraction1:
+ {
+ format = chars_format::fixed;
+ switch (*p)
+ {
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
+ ++precision;
+ ++decimal_places;
+ buffer.push_back(*p);
+ state = numeric_check_state::fraction;
+ break;
+ default:
+ state = numeric_check_state::done;
+ break;
+ }
+ break;
+ }
+ case numeric_check_state::fraction:
+ {
+ switch (*p)
+ {
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
+ ++precision;
+ ++decimal_places;
+ buffer.push_back(*p);
+ break;
+ case 'e':case 'E':
+ buffer.push_back(*p);
+ state = numeric_check_state::exp1;
+ break;
+ default:
+ state = numeric_check_state::done;
+ break;
+ }
+ break;
+ }
+ case numeric_check_state::exp1:
+ {
+ format = chars_format::scientific;
+ switch (*p)
+ {
+ case '-':
+ buffer.push_back(*p);
+ state = numeric_check_state::exp;
+ break;
+ case '+':
+ state = numeric_check_state::exp;
+ break;
+ case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
+ buffer.push_back(*p);
+ state = numeric_check_state::integer;
+ break;
+ default:
+ state = numeric_check_state::done;
+ break;
+ }
+ break;
+ }
+ case numeric_check_state::exp:
+ {
+ switch (*p)
+ {
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
+ buffer.push_back(*p);
+ break;
+ default:
+ state = numeric_check_state::done;
+ break;
+ }
+ break;
+ }
+ }
+ }
+
+ switch (state)
+ {
+ case numeric_check_state::null:
+ handler.null_value(*this);
+ break;
+ case numeric_check_state::boolean_true:
+ handler.bool_value(true,*this);
+ break;
+ case numeric_check_state::boolean_false:
+ handler.bool_value(false,*this);
+ break;
+ case numeric_check_state::zero:
+ case numeric_check_state::integer:
+ {
+ if (is_negative)
+ {
+ jsoncons::detail::to_integer_result result = jsoncons::detail::to_integer(value.data(), value.length());
+ if (!result.overflow)
+ {
+ handler.integer_value(result.value,*this);
+ }
+ else
+ {
+ double d = to_double_(buffer.data(), buffer.length());
+ handler.double_value(d, number_format(format), *this);
+ }
+ }
+ else
+ {
+ jsoncons::detail::to_uinteger_result result = jsoncons::detail::to_uinteger(value.data(), value.length());
+ if (!result.overflow)
+ {
+ handler.uinteger_value(result.value,*this);
+ }
+ else
+ {
+ double d = to_double_(buffer.data(), buffer.length());
+ handler.double_value(d, number_format(format), *this);
+ }
+ }
+ break;
+ }
+ case numeric_check_state::fraction:
+ case numeric_check_state::exp:
+ {
+ double d = to_double_(buffer.data(), buffer.length());
+ handler.double_value(d, number_format(format, precision, decimal_places), *this);
+ break;
+ }
+ default:
+ handler.string_value(value, *this);
+ }
+ }
+
+ size_t do_line_number() const override
+ {
+ return line_;
+ }
+
+ size_t do_column_number() const override
+ {
+ return column_;
+ }
+
+ void push_mode(csv_mode_type mode)
+ {
+ ++top_;
+ if (top_ >= depth_)
+ {
+ depth_ *= 2;
+ stack_.resize(depth_);
+ }
+ stack_[top_] = mode;
+ }
+
+ int peek()
+ {
+ return stack_[top_];
+ }
+
+ bool peek(csv_mode_type mode)
+ {
+ return stack_[top_] == mode;
+ }
+
+ bool flip(csv_mode_type mode1, csv_mode_type mode2)
+ {
+ if (top_ < 0 || stack_[top_] != mode1)
+ {
+ return false;
+ }
+ stack_[top_] = mode2;
+ return true;
+ }
+
+ bool pop_mode(csv_mode_type mode)
+ {
+ if (top_ < 0 || stack_[top_] != mode)
+ {
+ return false;
+ }
+ --top_;
+ return true;
+ }
+};
+
+typedef basic_csv_parser<char> csv_parser;
+typedef basic_csv_parser<wchar_t> wcsv_parser;
+
+}}
+
+#endif
+
diff --git a/vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_reader.hpp b/vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_reader.hpp
new file mode 100644
index 00000000..5834b1a0
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_reader.hpp
@@ -0,0 +1,235 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_CSV_CSV_READER_HPP
+#define JSONCONS_CSV_CSV_READER_HPP
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <cstdlib>
+#include <stdexcept>
+#include <jsoncons/json_exception.hpp>
+#include <jsoncons/json_input_handler.hpp>
+#include <jsoncons/parse_error_handler.hpp>
+#include <jsoncons_ext/csv/csv_error_category.hpp>
+#include <jsoncons_ext/csv/csv_parser.hpp>
+#include <jsoncons/json.hpp>
+#include <jsoncons/json_reader.hpp>
+#include <jsoncons/json_decoder.hpp>
+#include <jsoncons_ext/csv/csv_parameters.hpp>
+
+namespace jsoncons { namespace csv {
+
+template<class CharT,class Allocator=std::allocator<char>>
+class basic_csv_reader
+{
+ struct stack_item
+ {
+ stack_item()
+ : array_begun_(false)
+ {
+ }
+
+ bool array_begun_;
+ };
+ typedef CharT char_type;
+ typedef Allocator allocator_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<CharT> char_allocator_type;
+
+ basic_csv_reader(const basic_csv_reader&) = delete;
+ basic_csv_reader& operator = (const basic_csv_reader&) = delete;
+
+ basic_csv_parser<CharT,Allocator> parser_;
+ std::basic_istream<CharT>& is_;
+ std::vector<CharT,char_allocator_type> buffer_;
+ size_t buffer_length_;
+ size_t buffer_position_;
+ bool eof_;
+ size_t index_;
+public:
+ // Structural characters
+ static const size_t default_max_buffer_length = 16384;
+ //! Parse an input stream of CSV text into a json object
+ /*!
+ \param is The input stream to read from
+ */
+
+ basic_csv_reader(std::basic_istream<CharT>& is,
+ basic_json_input_handler<CharT>& handler)
+
+ : parser_(handler),
+ is_(is),
+ buffer_length_(default_max_buffer_length),
+ buffer_position_(0),
+ eof_(false),
+ index_(0)
+ {
+ buffer_.reserve(buffer_length_);
+ }
+
+ basic_csv_reader(std::basic_istream<CharT>& is,
+ basic_json_input_handler<CharT>& handler,
+ basic_csv_parameters<CharT,Allocator> params)
+
+ : parser_(handler,params),
+ is_(is),
+ buffer_length_(default_max_buffer_length),
+ buffer_position_(0),
+ eof_(false),
+ index_(0)
+ {
+ buffer_.reserve(buffer_length_);
+ }
+
+ basic_csv_reader(std::basic_istream<CharT>& is,
+ basic_json_input_handler<CharT>& handler,
+ parse_error_handler& err_handler)
+ :
+ parser_(handler,err_handler),
+ is_(is),
+ buffer_length_(default_max_buffer_length),
+ buffer_position_(0),
+ eof_(false),
+ index_(0)
+ {
+ buffer_.reserve(buffer_length_);
+ }
+
+ basic_csv_reader(std::basic_istream<CharT>& is,
+ basic_json_input_handler<CharT>& handler,
+ parse_error_handler& err_handler,
+ basic_csv_parameters<CharT,Allocator> params)
+ :
+ parser_(handler,err_handler,params),
+ is_(is),
+ buffer_length_(default_max_buffer_length),
+ buffer_position_(0),
+ eof_(false),
+ index_(0)
+ {
+ buffer_.reserve(buffer_length_);
+ }
+
+ ~basic_csv_reader()
+ {
+ }
+
+ void read()
+ {
+ parser_.reset();
+ while (!eof_ && !parser_.done())
+ {
+ if (!(index_ < buffer_.size()))
+ {
+ if (!is_.eof())
+ {
+ buffer_.clear();
+ buffer_.resize(buffer_length_);
+ is_.read(buffer_.data(), buffer_length_);
+ buffer_.resize(static_cast<size_t>(is_.gcount()));
+ if (buffer_.size() == 0)
+ {
+ eof_ = true;
+ }
+ index_ = 0;
+ }
+ else
+ {
+ eof_ = true;
+ }
+ }
+ if (!eof_)
+ {
+ parser_.parse(buffer_.data(),index_,buffer_.size());
+ index_ = parser_.index();
+ }
+ }
+ parser_.end_parse();
+ }
+
+ bool eof() const
+ {
+ return eof_;
+ }
+
+ size_t buffer_length() const
+ {
+ return buffer_length_;
+ }
+
+ void buffer_length(size_t length)
+ {
+ buffer_length_ = length;
+ buffer_.reserve(buffer_length_);
+ }
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+
+ size_t buffer_capacity() const
+ {
+ return buffer_length_;
+ }
+
+ void buffer_capacity(size_t length)
+ {
+ buffer_length_ = length;
+ buffer_.reserve(buffer_length_);
+ }
+#endif
+};
+
+template <class Json>
+Json decode_csv(typename Json::string_view_type s)
+{
+ json_decoder<Json> decoder;
+
+ basic_csv_parser<typename Json::char_type> parser(decoder);
+ parser.reset();
+ parser.parse(s.data(), 0, s.size());
+ parser.end_parse();
+ return decoder.get_result();
+}
+
+template <class Json,class Allocator>
+Json decode_csv(typename Json::string_view_type s, const basic_csv_parameters<typename Json::char_type,Allocator>& params)
+{
+ json_decoder<Json,Allocator> decoder;
+
+ basic_csv_parser<typename Json::char_type,Allocator> parser(decoder, params);
+ parser.reset();
+ parser.parse(s.data(), 0, s.size());
+ parser.end_parse();
+ return decoder.get_result();
+}
+
+template <class Json>
+Json decode_csv(std::basic_istream<typename Json::char_type>& is)
+{
+ json_decoder<Json> decoder;
+
+ basic_csv_reader<typename Json::char_type> reader(is,decoder);
+ reader.read();
+ return decoder.get_result();
+}
+
+template <class Json,class Allocator>
+Json decode_csv(std::basic_istream<typename Json::char_type>& is, const basic_csv_parameters<typename Json::char_type,Allocator>& params)
+{
+ json_decoder<Json,Allocator> decoder;
+
+ basic_csv_reader<typename Json::char_type,Allocator> reader(is,decoder,params);
+ reader.read();
+ return decoder.get_result();
+}
+
+typedef basic_csv_reader<char> csv_reader;
+typedef basic_csv_reader<wchar_t> wcsv_reader;
+
+}}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_serializer.hpp b/vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_serializer.hpp
new file mode 100644
index 00000000..54c8035d
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons_ext/csv/csv_serializer.hpp
@@ -0,0 +1,504 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_CSV_CSV_SERIALIZER_HPP
+#define JSONCONS_CSV_CSV_SERIALIZER_HPP
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <ostream>
+#include <cstdlib>
+#include <unordered_map>
+#include <memory>
+#include <limits> // std::numeric_limits
+#include <jsoncons/json_exception.hpp>
+#include <jsoncons/serialization_options.hpp>
+#include <jsoncons/json_output_handler.hpp>
+#include <jsoncons/detail/number_printers.hpp>
+#include <jsoncons/detail/obufferedstream.hpp>
+#include <jsoncons_ext/csv/csv_parameters.hpp>
+#include <jsoncons/detail/writer.hpp>
+
+namespace jsoncons { namespace csv {
+
+template<class CharT,class Writer=jsoncons::detail::ostream_buffered_writer<CharT>,class Allocator=std::allocator<CharT>>
+class basic_csv_serializer final : public basic_json_output_handler<CharT>
+{
+public:
+ typedef typename Writer::output_type output_type;
+
+ typedef Allocator allocator_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<CharT> char_allocator_type;
+ typedef std::basic_string<CharT, std::char_traits<CharT>, char_allocator_type> string_type;
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<string_type> string_allocator_type;
+
+ using typename basic_json_output_handler<CharT>::string_view_type ;
+private:
+ struct stack_item
+ {
+ stack_item(bool is_object)
+ : is_object_(is_object), count_(0)
+ {
+ }
+ bool is_object() const
+ {
+ return is_object_;
+ }
+
+ bool is_object_;
+ size_t count_;
+ string_type name_;
+ };
+ Writer writer_;
+ basic_csv_parameters<CharT,Allocator> parameters_;
+ basic_serialization_options<CharT> options_;
+ std::vector<stack_item> stack_;
+ jsoncons::detail::print_double fp_;
+ std::vector<string_type,string_allocator_type> column_names_;
+
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<std::pair<const string_type,string_type>> string_string_allocator_type;
+ std::unordered_map<string_type,string_type, std::hash<string_type>,std::equal_to<string_type>,string_string_allocator_type> buffered_line_;
+
+ // Noncopyable and nonmoveable
+ basic_csv_serializer(const basic_csv_serializer&) = delete;
+ basic_csv_serializer& operator=(const basic_csv_serializer&) = delete;
+public:
+ basic_csv_serializer(output_type& os)
+ :
+ writer_(os),
+ options_(),
+ stack_(),
+ fp_(options_.precision()),
+ column_names_(parameters_.column_names())
+ {
+ }
+
+ basic_csv_serializer(output_type& os,
+ const basic_csv_parameters<CharT,Allocator>& params)
+ :
+ writer_(os),
+ parameters_(params),
+ options_(),
+ stack_(),
+ fp_(options_.precision()),
+ column_names_(parameters_.column_names())
+ {
+ }
+
+private:
+
+ template<class AnyWriter>
+ void escape_string(const CharT* s,
+ size_t length,
+ CharT quote_char, CharT quote_escape_char,
+ AnyWriter& writer)
+ {
+ const CharT* begin = s;
+ const CharT* end = s + length;
+ for (const CharT* it = begin; it != end; ++it)
+ {
+ CharT c = *it;
+ if (c == quote_char)
+ {
+ writer.put(quote_escape_char);
+ writer.put(quote_char);
+ }
+ else
+ {
+ writer.put(c);
+ }
+ }
+ }
+
+ void do_begin_json() override
+ {
+ }
+
+ void do_end_json() override
+ {
+ writer_.flush();
+ }
+
+ void do_begin_object() override
+ {
+ stack_.push_back(stack_item(true));
+ }
+
+ void do_end_object() override
+ {
+ if (stack_.size() == 2)
+ {
+ if (stack_[0].count_ == 0)
+ {
+ for (size_t i = 0; i < column_names_.size(); ++i)
+ {
+ if (i > 0)
+ {
+ writer_.put(parameters_.field_delimiter());
+ }
+ writer_.write(column_names_[i]);
+ }
+ writer_.write(parameters_.line_delimiter());
+ }
+ for (size_t i = 0; i < column_names_.size(); ++i)
+ {
+ if (i > 0)
+ {
+ writer_.put(parameters_.field_delimiter());
+ }
+ auto it = buffered_line_.find(column_names_[i]);
+ if (it != buffered_line_.end())
+ {
+ writer_.write(it->second);
+ it->second.clear();
+ }
+ }
+ writer_.write(parameters_.line_delimiter());
+ }
+ stack_.pop_back();
+
+ end_value();
+ }
+
+ void do_begin_array() override
+ {
+ stack_.push_back(stack_item(false));
+ if (stack_.size() == 2)
+ {
+ if (stack_[0].count_ == 0)
+ {
+ for (size_t i = 0; i < column_names_.size(); ++i)
+ {
+ if (i > 0)
+ {
+ writer_.put(parameters_.field_delimiter());
+ }
+ writer_.write(column_names_[i]);
+ }
+ if (column_names_.size() > 0)
+ {
+ writer_.write(parameters_.line_delimiter());
+ }
+ }
+ }
+ }
+
+ void do_end_array() override
+ {
+ if (stack_.size() == 2)
+ {
+ writer_.write(parameters_.line_delimiter());
+ }
+ stack_.pop_back();
+
+ end_value();
+ }
+
+ void do_name(const string_view_type& name) override
+ {
+ if (stack_.size() == 2)
+ {
+ stack_.back().name_ = string_type(name);
+ buffered_line_[string_type(name)] = std::basic_string<CharT>();
+ if (stack_[0].count_ == 0 && parameters_.column_names().size() == 0)
+ {
+ column_names_.push_back(string_type(name));
+ }
+ }
+ }
+
+ template <class AnyWriter>
+ void write_string(const CharT* s, size_t length, AnyWriter& writer)
+ {
+ bool quote = false;
+ if (parameters_.quote_style() == quote_style_type::all || parameters_.quote_style() == quote_style_type::nonnumeric ||
+ (parameters_.quote_style() == quote_style_type::minimal &&
+ (std::char_traits<CharT>::find(s, length, parameters_.field_delimiter()) != nullptr || std::char_traits<CharT>::find(s, length, parameters_.quote_char()) != nullptr)))
+ {
+ quote = true;
+ writer.put(parameters_.quote_char());
+ }
+ escape_string(s, length, parameters_.quote_char(), parameters_.quote_escape_char(), writer);
+ if (quote)
+ {
+ writer.put(parameters_.quote_char());
+ }
+
+ }
+
+ void do_null_value() override
+ {
+ if (stack_.size() == 2)
+ {
+ if (stack_.back().is_object())
+ {
+ auto it = buffered_line_.find(stack_.back().name_);
+ if (it != buffered_line_.end())
+ {
+ std::basic_string<CharT> s;
+ jsoncons::detail::string_writer<CharT> bo(s);
+ do_null_value(bo);
+ bo.flush();
+ it->second = s;
+ }
+ }
+ else
+ {
+ do_null_value(writer_);
+ }
+ }
+ }
+
+ void do_string_value(const string_view_type& val) override
+ {
+ if (stack_.size() == 2)
+ {
+ if (stack_.back().is_object())
+ {
+ auto it = buffered_line_.find(stack_.back().name_);
+ if (it != buffered_line_.end())
+ {
+ std::basic_string<CharT> s;
+ jsoncons::detail::string_writer<CharT> bo(s);
+ value(val,bo);
+ bo.flush();
+ it->second = s;
+ }
+ }
+ else
+ {
+ value(val,writer_);
+ }
+ }
+ }
+
+ void do_byte_string_value(const uint8_t*, size_t) override
+ {
+
+ }
+
+ void do_double_value(double val, const number_format&) override
+ {
+ if (stack_.size() == 2)
+ {
+ if (stack_.back().is_object())
+ {
+ auto it = buffered_line_.find(stack_.back().name_);
+ if (it != buffered_line_.end())
+ {
+ std::basic_string<CharT> s;
+ jsoncons::detail::string_writer<CharT> bo(s);
+ value(val,bo);
+ bo.flush();
+ it->second = s;
+ }
+ }
+ else
+ {
+ value(val,writer_);
+ }
+ }
+ }
+
+ void do_integer_value(int64_t val) override
+ {
+ if (stack_.size() == 2)
+ {
+ if (stack_.back().is_object())
+ {
+ auto it = buffered_line_.find(stack_.back().name_);
+ if (it != buffered_line_.end())
+ {
+ std::basic_string<CharT> s;
+ jsoncons::detail::string_writer<CharT> bo(s);
+ value(val,bo);
+ bo.flush();
+ it->second = s;
+ }
+ }
+ else
+ {
+ value(val,writer_);
+ }
+ }
+ }
+
+ void do_uinteger_value(uint64_t val) override
+ {
+ if (stack_.size() == 2)
+ {
+ if (stack_.back().is_object())
+ {
+ auto it = buffered_line_.find(stack_.back().name_);
+ if (it != buffered_line_.end())
+ {
+ std::basic_string<CharT> s;
+ jsoncons::detail::string_writer<CharT> bo(s);
+ value(val,bo);
+ bo.flush();
+ it->second = s;
+ }
+ }
+ else
+ {
+ value(val,writer_);
+ }
+ }
+ }
+
+ void do_bool_value(bool val) override
+ {
+ if (stack_.size() == 2)
+ {
+ if (stack_.back().is_object())
+ {
+ auto it = buffered_line_.find(stack_.back().name_);
+ if (it != buffered_line_.end())
+ {
+ std::basic_string<CharT> s;
+ jsoncons::detail::string_writer<CharT> bo(s);
+ value(val,bo);
+ bo.flush();
+ it->second = s;
+ }
+ }
+ else
+ {
+ value(val,writer_);
+ }
+ }
+ }
+
+ template <class AnyWriter>
+ void value(const string_view_type& value, AnyWriter& writer)
+ {
+ begin_value(writer);
+ write_string(value.data(),value.length(),writer);
+ end_value();
+ }
+
+ template <class AnyWriter>
+ void value(double val, AnyWriter& writer)
+ {
+ begin_value(writer);
+
+ if ((std::isnan)(val))
+ {
+ writer.write(options_.nan_replacement());
+ }
+ else if (val == std::numeric_limits<double>::infinity())
+ {
+ writer.write(options_.pos_inf_replacement());
+ }
+ else if (!(std::isfinite)(val))
+ {
+ writer.write(options_.neg_inf_replacement());
+ }
+ else
+ {
+ fp_(val,options_.precision(),writer);
+ }
+
+ end_value();
+
+ }
+
+ template <class AnyWriter>
+ void value(int64_t val, AnyWriter& writer)
+ {
+ begin_value(writer);
+
+ std::basic_ostringstream<CharT> ss;
+ ss << val;
+ writer.write(ss.str());
+
+ end_value();
+ }
+
+ template <class AnyWriter>
+ void value(uint64_t val, AnyWriter& writer)
+ {
+ begin_value(writer);
+
+ std::basic_ostringstream<CharT> ss;
+ ss << val;
+ writer.write(ss.str());
+
+ end_value();
+ }
+
+ template <class AnyWriter>
+ void value(bool val, AnyWriter& writer)
+ {
+ begin_value(writer);
+
+ if (val)
+ {
+ auto buf = jsoncons::detail::true_literal<CharT>();
+ writer.write(buf,4);
+ }
+ else
+ {
+ auto buf = jsoncons::detail::false_literal<CharT>();
+ writer.write(buf,5);
+ }
+
+ end_value();
+ }
+
+ template <class AnyWriter>
+ void do_null_value(AnyWriter& writer)
+ {
+ begin_value(writer);
+ auto buf = jsoncons::detail::null_literal<CharT>();
+ writer.write(buf,4);
+ end_value();
+
+ }
+
+ template <class AnyWriter>
+ void begin_value(AnyWriter& writer)
+ {
+ if (!stack_.empty())
+ {
+ if (!stack_.back().is_object_ && stack_.back().count_ > 0)
+ {
+ writer.put(parameters_.field_delimiter());
+ }
+ }
+ }
+
+ void end_value()
+ {
+ if (!stack_.empty())
+ {
+ ++stack_.back().count_;
+ }
+ }
+};
+
+template <class Json>
+void encode_csv(const Json& j, std::basic_ostream<typename Json::char_type>& os)
+{
+ typedef typename Json::char_type char_type;
+ basic_csv_serializer<char_type> serializer(os);
+ j.dump(serializer);
+}
+
+template <class Json,class Allocator>
+void encode_csv(const Json& j, std::basic_ostream<typename Json::char_type>& os, const basic_csv_parameters<typename Json::char_type,Allocator>& params)
+{
+ typedef typename Json::char_type char_type;
+ basic_csv_serializer<char_type,jsoncons::detail::ostream_buffered_writer<char_type>,Allocator> serializer(os,params);
+ j.dump(serializer);
+}
+
+typedef basic_csv_serializer<char> csv_serializer;
+
+}}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpatch/jsonpatch.hpp b/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpatch/jsonpatch.hpp
new file mode 100644
index 00000000..f6997001
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpatch/jsonpatch.hpp
@@ -0,0 +1,530 @@
+// Copyright 2017 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSONPOINTER_JSONPATCH_HPP
+#define JSONCONS_JSONPOINTER_JSONPATCH_HPP
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <cstdlib>
+#include <memory>
+#include <jsoncons/json.hpp>
+#include <jsoncons_ext/jsonpointer/jsonpointer.hpp>
+#include <jsoncons_ext/jsonpatch/jsonpatch_error_category.hpp>
+
+namespace jsoncons { namespace jsonpatch {
+
+class jsonpatch_error : public std::exception, public virtual json_exception
+{
+public:
+ jsonpatch_error(const std::error_code& ec)
+ : error_code_(ec)
+ {
+ }
+ jsonpatch_error(const jsonpatch_error& other) = default;
+
+ jsonpatch_error(jsonpatch_error&& other) = default;
+
+ const char* what() const JSONCONS_NOEXCEPT override
+ {
+ try
+ {
+ const_cast<std::string&>(buffer_) = error_code_.message();
+ return buffer_.c_str();
+ }
+ catch (...)
+ {
+ return "";
+ }
+ }
+
+ const std::error_code code() const
+ {
+ return error_code_;
+ }
+
+ jsonpatch_error& operator=(const jsonpatch_error& e) = default;
+ jsonpatch_error& operator=(jsonpatch_error&& e) = default;
+private:
+ std::string buffer_;
+ std::error_code error_code_;
+};
+
+namespace detail {
+
+ JSONCONS_DEFINE_LITERAL(test_literal,"test")
+ JSONCONS_DEFINE_LITERAL(add_literal,"add")
+ JSONCONS_DEFINE_LITERAL(remove_literal,"remove")
+ JSONCONS_DEFINE_LITERAL(replace_literal,"replace")
+ JSONCONS_DEFINE_LITERAL(move_literal,"move")
+ JSONCONS_DEFINE_LITERAL(copy_literal,"copy")
+ JSONCONS_DEFINE_LITERAL(op_literal,"op")
+ JSONCONS_DEFINE_LITERAL(path_literal,"path")
+ JSONCONS_DEFINE_LITERAL(from_literal,"from")
+ JSONCONS_DEFINE_LITERAL(value_literal,"value")
+
+ enum class op_type {add,remove,replace};
+ enum class state_type {begin,abort,commit};
+
+ template <class Json>
+ struct operation_unwinder
+ {
+ typedef typename Json::string_type string_type;
+ typedef typename Json::string_view_type string_view_type;
+
+ struct entry
+ {
+ op_type op;
+ string_type path;
+ Json value;
+ };
+
+ Json& target;
+ state_type state;
+ std::vector<entry> stack;
+
+ operation_unwinder(Json& j)
+ : target(j), state(state_type::begin)
+ {
+ }
+
+ ~operation_unwinder()
+ {
+ std::error_code ec;
+ //std::cout << "state: " << std::boolalpha << (state == state_type::commit) << ", stack size: " << stack.size() << std::endl;
+ if (state != state_type::commit)
+ {
+ for (auto it = stack.rbegin(); it != stack.rend(); ++it)
+ {
+ if (it->op == op_type::add)
+ {
+ jsonpointer::insert_or_assign(target,it->path,it->value,ec);
+ if (ec)
+ {
+ //std::cout << "add: " << it->path << std::endl;
+ break;
+ }
+ }
+ else if (it->op == op_type::remove)
+ {
+ jsonpointer::remove(target,it->path,ec);
+ if (ec)
+ {
+ //std::cout << "remove: " << it->path << std::endl;
+ break;
+ }
+ }
+ else if (it->op == op_type::replace)
+ {
+ jsonpointer::replace(target,it->path,it->value,ec);
+ if (ec)
+ {
+ //std::cout << "replace: " << it->path << std::endl;
+ break;
+ }
+ }
+ }
+ }
+ }
+ };
+
+ template <class Json>
+ Json from_diff(const Json& source, const Json& target, const typename Json::string_type& path)
+ {
+ typedef typename Json::char_type char_type;
+ typedef typename Json::string_type string_type;
+ typedef typename Json::string_view_type string_view_type;
+
+ Json result = typename Json::array();
+
+ if (source == target)
+ {
+ return result;
+ }
+
+ if (source.is_array() && target.is_array())
+ {
+ size_t common = (std::min)(source.size(),target.size());
+ for (size_t i = 0; i < common; ++i)
+ {
+ std::basic_ostringstream<char_type> ss;
+ ss << path << '/' << i;
+ auto temp_diff = from_diff(source[i],target[i],ss.str());
+ result.insert(result.array_range().end(),temp_diff.array_range().begin(),temp_diff.array_range().end());
+ }
+ // Element in source, not in target - remove
+ for (size_t i = target.size(); i < source.size(); ++i)
+ {
+ std::basic_ostringstream<char_type> ss;
+ ss << path << '/' << i;
+ Json val = typename Json::object();
+ val.insert_or_assign(op_literal<char_type>(), remove_literal<char_type>());
+ val.insert_or_assign(path_literal<char_type>(), ss.str());
+ result.push_back(std::move(val));
+ }
+ // Element in target, not in source - add,
+ // Fix contributed by Alexander rog13
+ for (size_t i = source.size(); i < target.size(); ++i)
+ {
+ const auto& a = target[i];
+ std::basic_ostringstream<char_type> ss;
+ ss << path << '/' << i;
+ Json val = typename Json::object();
+ val.insert_or_assign(op_literal<char_type>(), add_literal<char_type>());
+ val.insert_or_assign(path_literal<char_type>(), ss.str());
+ val.insert_or_assign(value_literal<char_type>(), a);
+ result.push_back(std::move(val));
+ }
+ }
+ else if (source.is_object() && target.is_object())
+ {
+ for (const auto& a : source.object_range())
+ {
+ std::basic_ostringstream<char_type> ss;
+ ss << path << '/';
+ jsonpointer::escape(a.key(),ss);
+ auto it = target.find(a.key());
+ if (it != target.object_range().end())
+ {
+ auto temp_diff = from_diff(a.value(),it->value(),ss.str());
+ result.insert(result.array_range().end(),temp_diff.array_range().begin(),temp_diff.array_range().end());
+ }
+ else
+ {
+ Json val = typename Json::object();
+ val.insert_or_assign(op_literal<char_type>(), remove_literal<char_type>());
+ val.insert_or_assign(path_literal<char_type>(), ss.str());
+ result.push_back(std::move(val));
+ }
+ }
+ for (const auto& a : target.object_range())
+ {
+ auto it = source.find(a.key());
+ if (it == source.object_range().end())
+ {
+ std::basic_ostringstream<char_type> ss;
+ ss << path << '/';
+ jsonpointer::escape(a.key(),ss);
+ Json val = typename Json::object();
+ val.insert_or_assign(op_literal<char_type>(), add_literal<char_type>());
+ val.insert_or_assign(path_literal<char_type>(), ss.str());
+ val.insert_or_assign(value_literal<char_type>(), a.value());
+ result.push_back(std::move(val));
+ }
+ }
+ }
+ else
+ {
+ Json val = typename Json::object();
+ val.insert_or_assign(op_literal<char_type>(), replace_literal<char_type>());
+ val.insert_or_assign(path_literal<char_type>(), path);
+ val.insert_or_assign(value_literal<char_type>(), target);
+ result.push_back(std::move(val));
+ }
+
+ return result;
+ }
+}
+
+template <class Json>
+void apply_patch(Json& target, const Json& patch, std::error_code& patch_ec)
+{
+ typedef typename Json::char_type char_type;
+ typedef typename Json::string_type string_type;
+ typedef typename Json::string_view_type string_view_type;
+
+ detail::operation_unwinder<Json> unwinder(target);
+
+ // Validate
+
+ string_type bad_path;
+ for (const auto& operation : patch.array_range())
+ {
+ unwinder.state = detail::state_type::begin;
+
+ if (operation.count(detail::op_literal<char_type>()) != 1 || operation.count(detail::path_literal<char_type>()) != 1)
+ {
+ patch_ec = jsonpatch_errc::invalid_patch;
+ unwinder.state = detail::state_type::abort;
+ }
+ else
+ {
+ const string_view_type op = operation.at(detail::op_literal<char_type>()).as_string_view();
+ const string_view_type path = operation.at(detail::path_literal<char_type>()).as_string_view();
+
+ if (op == detail::test_literal<char_type>())
+ {
+ std::error_code ec;
+ Json val = jsonpointer::get(target,path,ec);
+ if (ec)
+ {
+ patch_ec = jsonpatch_errc::test_failed;
+ unwinder.state = detail::state_type::abort;
+ }
+ else if (operation.count(detail::value_literal<char_type>()) != 1)
+ {
+ patch_ec = jsonpatch_errc::invalid_patch;
+ unwinder.state = detail::state_type::abort;
+ }
+ else if (val != operation.at(detail::value_literal<char_type>()))
+ {
+ patch_ec = jsonpatch_errc::test_failed;
+ unwinder.state = detail::state_type::abort;
+ }
+ }
+ else if (op == detail::add_literal<char_type>())
+ {
+ if (operation.count(detail::value_literal<char_type>()) != 1)
+ {
+ patch_ec = jsonpatch_errc::invalid_patch;
+ unwinder.state = detail::state_type::abort;
+ }
+ else
+ {
+ std::error_code insert_ec;
+ Json val = operation.at(detail::value_literal<char_type>());
+ auto npath = jsonpointer::normalized_path(target,path);
+ jsonpointer::insert(target,npath,val,insert_ec); // try insert without replace
+ if (insert_ec) // try a replace
+ {
+ std::error_code select_ec;
+ Json orig_val = jsonpointer::get(target,npath,select_ec);
+ if (select_ec) // shouldn't happen
+ {
+ patch_ec = jsonpatch_errc::add_failed;
+ unwinder.state = detail::state_type::abort;
+ }
+ else
+ {
+ std::error_code replace_ec;
+ jsonpointer::replace(target,npath,val,replace_ec);
+ if (replace_ec)
+ {
+ patch_ec = jsonpatch_errc::add_failed;
+ unwinder.state = detail::state_type::abort;
+ }
+ else
+ {
+ unwinder.stack.push_back({detail::op_type::replace,npath,orig_val});
+ }
+ }
+ }
+ else // insert without replace succeeded
+ {
+ unwinder.stack.push_back({detail::op_type::remove,npath,Json::null()});
+ }
+ }
+ }
+ else if (op == detail::remove_literal<char_type>())
+ {
+ std::error_code ec;
+ Json val = jsonpointer::get(target,path,ec);
+ if (ec)
+ {
+ patch_ec = jsonpatch_errc::remove_failed;
+ unwinder.state = detail::state_type::abort;
+ }
+ else
+ {
+ jsonpointer::remove(target,path,ec);
+ if (ec)
+ {
+ patch_ec = jsonpatch_errc::remove_failed;
+ unwinder.state = detail::state_type::abort;
+ }
+ else
+ {
+ unwinder.stack.push_back({detail::op_type::add,string_type(path),val});
+ }
+ }
+ }
+ else if (op == detail::replace_literal<char_type>())
+ {
+ std::error_code ec;
+ Json val = jsonpointer::get(target,path,ec);
+ if (ec)
+ {
+ patch_ec = jsonpatch_errc::replace_failed;
+ unwinder.state = detail::state_type::abort;
+ }
+ else if (operation.count(detail::value_literal<char_type>()) != 1)
+ {
+ patch_ec = jsonpatch_errc::invalid_patch;
+ unwinder.state = detail::state_type::abort;
+ }
+ else
+ {
+ jsonpointer::replace(target,path,operation.at(detail::value_literal<char_type>()),ec);
+ if (ec)
+ {
+ patch_ec = jsonpatch_errc::replace_failed;
+ unwinder.state = detail::state_type::abort;
+ }
+ else
+ {
+ unwinder.stack.push_back({detail::op_type::replace,string_type(path),val});
+ }
+ }
+ }
+ else if (op == detail::move_literal<char_type>())
+ {
+ if (operation.count(detail::from_literal<char_type>()) != 1)
+ {
+ patch_ec = jsonpatch_errc::invalid_patch;
+ unwinder.state = detail::state_type::abort;
+ }
+ else
+ {
+ string_view_type from = operation.at(detail::from_literal<char_type>()).as_string_view();
+ std::error_code ec;
+ Json val = jsonpointer::get(target,from,ec);
+ if (ec)
+ {
+ patch_ec = jsonpatch_errc::move_failed;
+ unwinder.state = detail::state_type::abort;
+ }
+ else
+ {
+ jsonpointer::remove(target,from,ec);
+ if (ec)
+ {
+ patch_ec = jsonpatch_errc::move_failed;
+ unwinder.state = detail::state_type::abort;
+ }
+ else
+ {
+ unwinder.stack.push_back({detail::op_type::add,string_type(from),val});
+ // add
+ std::error_code insert_ec;
+ auto npath = jsonpointer::normalized_path(target,path);
+ jsonpointer::insert(target,npath,val,insert_ec); // try insert without replace
+ if (insert_ec) // try a replace
+ {
+ std::error_code select_ec;
+ Json orig_val = jsonpointer::get(target,npath,select_ec);
+ if (select_ec) // shouldn't happen
+ {
+ patch_ec = jsonpatch_errc::copy_failed;
+ unwinder.state = detail::state_type::abort;
+ }
+ else
+ {
+ std::error_code replace_ec;
+ jsonpointer::replace(target, npath, val, replace_ec);
+ if (replace_ec)
+ {
+ patch_ec = jsonpatch_errc::copy_failed;
+ unwinder.state = detail::state_type::abort;
+
+ }
+ else
+ {
+ unwinder.stack.push_back({ detail::op_type::replace,npath,orig_val });
+ }
+
+ }
+ }
+ else
+ {
+ unwinder.stack.push_back({detail::op_type::remove,npath,Json::null()});
+ }
+ }
+ }
+ }
+ }
+ else if (op == detail::copy_literal<char_type>())
+ {
+ if (operation.count(detail::from_literal<char_type>()) != 1)
+ {
+ patch_ec = jsonpatch_errc::invalid_patch;
+ unwinder.state = detail::state_type::abort;
+ }
+ else
+ {
+ std::error_code ec;
+ string_view_type from = operation.at(detail::from_literal<char_type>()).as_string_view();
+ Json val = jsonpointer::get(target,from,ec);
+ if (ec)
+ {
+ patch_ec = jsonpatch_errc::copy_failed;
+ unwinder.state = detail::state_type::abort;
+ }
+ else
+ {
+ // add
+ auto npath = jsonpointer::normalized_path(target,path);
+ std::error_code insert_ec;
+ jsonpointer::insert(target,npath,val,insert_ec); // try insert without replace
+ if (insert_ec) // Failed, try a replace
+ {
+ std::error_code select_ec;
+ Json orig_val = jsonpointer::get(target,npath, select_ec);
+ if (select_ec) // shouldn't happen
+ {
+ patch_ec = jsonpatch_errc::copy_failed;
+ unwinder.state = detail::state_type::abort;
+ }
+ else
+ {
+ std::error_code replace_ec;
+ jsonpointer::replace(target, npath, val,replace_ec);
+ if (replace_ec)
+ {
+ patch_ec = jsonpatch_errc::copy_failed;
+ unwinder.state = detail::state_type::abort;
+ }
+ else
+ {
+ unwinder.stack.push_back({ detail::op_type::replace,npath,orig_val });
+ }
+ }
+ }
+ else
+ {
+ unwinder.stack.push_back({detail::op_type::remove,npath,Json::null()});
+ }
+ }
+ }
+ }
+ if (unwinder.state != detail::state_type::begin)
+ {
+ bad_path = string_type(path);
+ }
+ }
+ if (unwinder.state != detail::state_type::begin)
+ {
+ break;
+ }
+ }
+ if (unwinder.state == detail::state_type::begin)
+ {
+ unwinder.state = detail::state_type::commit;
+ }
+}
+
+template <class Json>
+Json from_diff(const Json& source, const Json& target)
+{
+ typename Json::string_type path;
+ return detail::from_diff(source, target, path);
+}
+
+template <class Json>
+void apply_patch(Json& target, const Json& patch)
+{
+ std::error_code ec;
+ apply_patch(target, patch, ec);
+ if (ec)
+ {
+ JSONCONS_THROW(jsonpatch_error(ec));
+ }
+}
+
+}}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpatch/jsonpatch_error_category.hpp b/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpatch/jsonpatch_error_category.hpp
new file mode 100644
index 00000000..6e566fc1
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpatch/jsonpatch_error_category.hpp
@@ -0,0 +1,82 @@
+/// Copyright 2017 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSONPATCH_JSONPATCH_ERROR_CATEGORY_HPP
+#define JSONCONS_JSONPATCH_JSONPATCH_ERROR_CATEGORY_HPP
+
+#include <jsoncons/json_exception.hpp>
+#include <system_error>
+
+namespace jsoncons { namespace jsonpatch {
+
+enum class jsonpatch_errc
+{
+ ok = 0,
+ invalid_patch = 1,
+ test_failed,
+ add_failed,
+ remove_failed,
+ replace_failed,
+ move_failed,
+ copy_failed
+
+};
+
+class jsonpatch_error_category_impl
+ : public std::error_category
+{
+public:
+ virtual const char* name() const JSONCONS_NOEXCEPT
+ {
+ return "jsonpatch";
+ }
+ virtual std::string message(int ev) const
+ {
+ switch (static_cast<jsonpatch_errc>(ev))
+ {
+ case jsonpatch_errc::invalid_patch:
+ return "Invalid JSON Patch document";
+ case jsonpatch_errc::test_failed:
+ return "JSON Patch test operation failed";
+ case jsonpatch_errc::add_failed:
+ return "JSON Patch add operation failed";
+ case jsonpatch_errc::remove_failed:
+ return "JSON Patch remove operation failed";
+ case jsonpatch_errc::replace_failed:
+ return "JSON Patch replace operation failed";
+ case jsonpatch_errc::move_failed:
+ return "JSON Patch move operation failed";
+ case jsonpatch_errc::copy_failed:
+ return "JSON Patch copy operation failed";
+ default:
+ return "Unknown JSON Patch error";
+ }
+ }
+};
+
+inline
+const std::error_category& jsonpatch_error_category()
+{
+ static jsonpatch_error_category_impl instance;
+ return instance;
+}
+
+inline
+std::error_code make_error_code(jsonpatch_errc result)
+{
+ return std::error_code(static_cast<int>(result),jsonpatch_error_category());
+}
+
+}}
+
+namespace std {
+ template<>
+ struct is_error_code_enum<jsoncons::jsonpatch::jsonpatch_errc> : public true_type
+ {
+ };
+}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpath/json_query.hpp b/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpath/json_query.hpp
new file mode 100644
index 00000000..b042bbbb
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpath/json_query.hpp
@@ -0,0 +1,1119 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSONPATH_JSONQUERY_HPP
+#define JSONCONS_JSONPATH_JSONQUERY_HPP
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <cstdlib>
+#include <memory>
+#include <jsoncons/json.hpp>
+#include "jsonpath_filter.hpp"
+#include "jsonpath_error_category.hpp"
+
+namespace jsoncons { namespace jsonpath {
+
+enum class result_type {value,path};
+
+template<class Json>
+Json json_query(const Json& root, const typename Json::string_view_type& path, result_type result_t = result_type::value)
+{
+ if (result_t == result_type::value)
+ {
+ detail::jsonpath_evaluator<Json,const Json&,detail::VoidPathConstructor<Json>> evaluator;
+ evaluator.evaluate(root,path.data(),path.length());
+ return evaluator.get_values();
+ }
+ else
+ {
+ detail::jsonpath_evaluator<Json,const Json&,detail::PathConstructor<Json>> evaluator;
+ evaluator.evaluate(root,path.data(),path.length());
+ return evaluator.get_normalized_paths();
+ }
+}
+
+template<class Json, class T>
+void json_replace(Json& root, const typename Json::string_view_type& path, T&& new_value)
+{
+ detail::jsonpath_evaluator<Json,Json&,detail::VoidPathConstructor<Json>> evaluator;
+ evaluator.evaluate(root,path.data(),path.length());
+ evaluator.replace(std::forward<T>(new_value));
+}
+
+namespace detail {
+
+template<class CharT>
+bool try_string_to_index(const CharT *s, size_t length, size_t* value, bool* positive)
+{
+ static const size_t max_value = (std::numeric_limits<size_t>::max)();
+ static const size_t max_value_div_10 = max_value / 10;
+
+ size_t start = 0;
+ size_t n = 0;
+ if (length > 0)
+ {
+ if (s[start] == '-')
+ {
+ *positive = false;
+ ++start;
+ }
+ else
+ {
+ *positive = true;
+ }
+ }
+ if (length > start)
+ {
+ for (size_t i = start; i < length; ++i)
+ {
+ CharT c = s[i];
+ switch (c)
+ {
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
+ {
+ size_t x = c - '0';
+ if (n > max_value_div_10)
+ {
+ return false;
+ }
+ n = n * 10;
+ if (n > max_value - x)
+ {
+ return false;
+ }
+
+ n += x;
+ }
+ break;
+ default:
+ return false;
+ break;
+ }
+ }
+ *value = n;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+enum class path_state
+{
+ start,
+ cr,
+ lf,
+ expect_dot_or_left_bracket,
+ expect_unquoted_name_or_left_bracket,
+ unquoted_name,
+ left_bracket_single_quoted_string,
+ left_bracket_double_quoted_string,
+ left_bracket,
+ left_bracket_start,
+ left_bracket_end,
+ left_bracket_end2,
+ left_bracket_step,
+ left_bracket_step2,
+ expect_comma_or_right_bracket,
+ dot
+};
+
+template<class Json,
+ class JsonReference=const Json&,
+ class PathCons=PathConstructor<Json>>
+class jsonpath_evaluator : private parsing_context
+{
+private:
+ typedef typename Json::char_type char_type;
+ typedef typename Json::char_traits_type char_traits_type;
+ typedef std::basic_string<char_type,char_traits_type> string_type;
+ typedef typename Json::string_view_type string_view_type;
+ typedef JsonReference reference;
+ using pointer = typename std::conditional<std::is_const<typename std::remove_reference<JsonReference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
+ struct node_type
+ {
+ node_type() = default;
+ node_type(const string_type& p, const pointer& valp)
+ : skip_contained_object(false),path(p),val_ptr(valp)
+ {
+ }
+ node_type(string_type&& p, pointer&& valp)
+ : skip_contained_object(false),path(std::move(p)),val_ptr(valp)
+ {
+ }
+ node_type(const node_type&) = default;
+ node_type(node_type&&) = default;
+
+ bool skip_contained_object;
+ string_type path;
+ pointer val_ptr;
+ };
+ typedef std::vector<node_type> node_set;
+
+ static string_view_type length_literal()
+ {
+ static const char_type data[] = {'l','e','n','g','t','h'};
+ return string_view_type{data,sizeof(data)/sizeof(char_type)};
+ }
+
+ class selector
+ {
+ public:
+ virtual ~selector()
+ {
+ }
+ virtual void select(node_type& node, const string_type& path, reference val,
+ node_set& nodes, std::vector<std::shared_ptr<Json>>& temp_json_values) = 0;
+ };
+
+ class expr_selector final : public selector
+ {
+ private:
+ jsonpath_filter_expr<Json> result_;
+ public:
+ expr_selector(const jsonpath_filter_expr<Json>& result)
+ : result_(result)
+ {
+ }
+
+ void select(node_type& node, const string_type& path, reference val,
+ node_set& nodes, std::vector<std::shared_ptr<Json>>& temp_json_values) override
+ {
+ auto index = result_.eval(val);
+ if (index.template is<size_t>())
+ {
+ size_t start = index. template as<size_t>();
+ if (val.is_array() && start < val.size())
+ {
+ nodes.emplace_back(PathCons()(path,start),std::addressof(val[start]));
+ }
+ }
+ else if (index.is_string())
+ {
+ name_selector selector(index.as_string_view(),true);
+ selector.select(node, path, val, nodes, temp_json_values);
+ }
+ }
+ };
+
+ class filter_selector final : public selector
+ {
+ private:
+ jsonpath_filter_expr<Json> result_;
+ public:
+ filter_selector(const jsonpath_filter_expr<Json>& result)
+ : result_(result)
+ {
+ }
+
+ void select(node_type& node, const string_type& path, reference val,
+ node_set& nodes, std::vector<std::shared_ptr<Json>>&) override
+ {
+ if (val.is_array())
+ {
+ node.skip_contained_object =true;
+ for (size_t i = 0; i < val.size(); ++i)
+ {
+ if (result_.exists(val[i]))
+ {
+ nodes.emplace_back(PathCons()(path,i),std::addressof(val[i]));
+ }
+ }
+ }
+ else if (val.is_object())
+ {
+ if (!node.skip_contained_object)
+ {
+ if (result_.exists(val))
+ {
+ nodes.emplace_back(path, std::addressof(val));
+ }
+ }
+ else
+ {
+ node.skip_contained_object = false;
+ }
+ }
+ }
+ };
+
+ class name_selector final : public selector
+ {
+ private:
+ string_type name_;
+ bool positive_start_;
+ public:
+ name_selector(const string_view_type& name, bool positive_start)
+ : name_(name), positive_start_(positive_start)
+ {
+ }
+
+ void select(node_type& node, const string_type& path, reference val,
+ node_set& nodes,
+ std::vector<std::shared_ptr<Json>>& temp_json_values) override
+ {
+ if (val.is_object() && val.count(name_) > 0)
+ {
+ nodes.emplace_back(PathCons()(path,name_),std::addressof(val.at(name_)));
+ }
+ else if (val.is_array())
+ {
+ size_t pos = 0;
+ if (try_string_to_index(name_.data(), name_.size(), &pos, &positive_start_))
+ {
+ size_t index = positive_start_ ? pos : val.size() - pos;
+ if (index < val.size())
+ {
+ nodes.emplace_back(PathCons()(path,index),std::addressof(val[index]));
+ }
+ }
+ else if (name_ == length_literal() && val.size() > 0)
+ {
+ auto temp = std::make_shared<Json>(val.size());
+ temp_json_values.push_back(temp);
+ nodes.emplace_back(PathCons()(path,name_),temp.get());
+ }
+ }
+ else if (val.is_string())
+ {
+ size_t pos = 0;
+ string_view_type sv = val.as_string_view();
+ if (try_string_to_index(name_.data(), name_.size(), &pos, &positive_start_))
+ {
+ size_t index = positive_start_ ? pos : sv.size() - pos;
+ auto sequence = unicons::sequence_at(sv.data(), sv.data() + sv.size(), index);
+ if (sequence.length() > 0)
+ {
+ auto temp = std::make_shared<Json>(sequence.begin(),sequence.length());
+ temp_json_values.push_back(temp);
+ nodes.emplace_back(PathCons()(path,index),temp.get());
+ }
+ }
+ else if (name_ == length_literal() && sv.size() > 0)
+ {
+ size_t count = unicons::u32_length(sv.begin(),sv.end());
+ auto temp = std::make_shared<Json>(count);
+ temp_json_values.push_back(temp);
+ nodes.emplace_back(PathCons()(path,name_),temp.get());
+ }
+ }
+ }
+ };
+
+ class array_slice_selector final : public selector
+ {
+ private:
+ size_t start_;
+ bool positive_start_;
+ size_t end_;
+ bool positive_end_;
+ bool undefined_end_;
+ size_t step_;
+ bool positive_step_;
+ public:
+ array_slice_selector(size_t start, bool positive_start,
+ size_t end, bool positive_end,
+ size_t step, bool positive_step,
+ bool undefined_end)
+ : start_(start), positive_start_(positive_start),
+ end_(end), positive_end_(positive_end),undefined_end_(undefined_end),
+ step_(step), positive_step_(positive_step)
+ {
+ }
+
+ void select(node_type& node, const string_type& path, reference val,
+ node_set& nodes,
+ std::vector<std::shared_ptr<Json>>&) override
+ {
+ if (positive_step_)
+ {
+ end_array_slice1(path, val, nodes);
+ }
+ else
+ {
+ end_array_slice2(path, val, nodes);
+ }
+ }
+
+ void end_array_slice1(const string_type& path, reference val, node_set& nodes)
+ {
+ if (val.is_array())
+ {
+ size_t start = positive_start_ ? start_ : val.size() - start_;
+ size_t end;
+ if (!undefined_end_)
+ {
+ end = positive_end_ ? end_ : val.size() - end_;
+ }
+ else
+ {
+ end = val.size();
+ }
+ for (size_t j = start; j < end; j += step_)
+ {
+ if (j < val.size())
+ {
+ nodes.emplace_back(PathCons()(path,j),std::addressof(val[j]));
+ }
+ }
+ }
+ }
+
+ void end_array_slice2(const string_type& path, reference val, node_set& nodes)
+ {
+ if (val.is_array())
+ {
+ size_t start = positive_start_ ? start_ : val.size() - start_;
+ size_t end;
+ if (!undefined_end_)
+ {
+ end = positive_end_ ? end_ : val.size() - end_;
+ }
+ else
+ {
+ end = val.size();
+ }
+
+ size_t j = end + step_ - 1;
+ while (j > (start+step_-1))
+ {
+ j -= step_;
+ if (j < val.size())
+ {
+ nodes.emplace_back(PathCons()(path,j),std::addressof(val[j]));
+ }
+ }
+ }
+ }
+ };
+
+ default_parse_error_handler default_err_handler_;
+ parse_error_handler *err_handler_;
+ path_state state_;
+ string_type buffer_;
+ size_t start_;
+ bool positive_start_;
+ size_t end_;
+ bool positive_end_;
+ bool undefined_end_;
+ size_t step_;
+ bool positive_step_;
+ bool recursive_descent_;
+ node_set nodes_;
+ std::vector<node_set> stack_;
+ std::vector<std::shared_ptr<Json>> temp_json_values_;
+ size_t line_;
+ size_t column_;
+ const char_type* begin_input_;
+ const char_type* end_input_;
+ const char_type* p_;
+ std::vector<std::shared_ptr<selector>> selectors_;
+
+public:
+ jsonpath_evaluator()
+ : err_handler_(&default_err_handler_),
+ state_(path_state::start),
+ start_(0), positive_start_(true),
+ end_(0), positive_end_(true), undefined_end_(false),
+ step_(0), positive_step_(true),
+ recursive_descent_(false),
+ line_(0), column_(0),
+ begin_input_(nullptr), end_input_(nullptr),
+ p_(nullptr)
+ {
+ }
+
+ Json get_values() const
+ {
+ Json result = typename Json::array();
+
+ if (stack_.size() > 0)
+ {
+ result.reserve(stack_.back().size());
+ for (const auto& p : stack_.back())
+ {
+ result.push_back(*(p.val_ptr));
+ }
+ }
+ return result;
+ }
+
+ Json get_normalized_paths() const
+ {
+ Json result = typename Json::array();
+ if (stack_.size() > 0)
+ {
+ result.reserve(stack_.back().size());
+ for (const auto& p : stack_.back())
+ {
+ result.push_back(p.path);
+ }
+ }
+ return result;
+ }
+
+ template <class T>
+ void replace(T&& new_value)
+ {
+ if (stack_.size() > 0)
+ {
+ for (size_t i = 0; i < stack_.back().size(); ++i)
+ {
+ *(stack_.back()[i].val_ptr) = new_value;
+ }
+ }
+ }
+
+ void evaluate(reference root, const string_view_type& path)
+ {
+ evaluate(root,path.data(),path.length());
+ }
+ void evaluate(reference root, const char_type* path)
+ {
+ evaluate(root,path,char_traits_type::length(path));
+ }
+
+ void evaluate(reference root,
+ const char_type* path,
+ size_t length)
+ {
+ std::error_code ec;
+ evaluate(root, path, length, ec);
+ if (ec)
+ {
+ throw parse_error(ec,line_,column_);
+ }
+ }
+
+ void evaluate(reference root,
+ const char_type* path,
+ size_t length,
+ std::error_code& ec)
+ {
+ path_state pre_line_break_state = path_state::start;
+
+ begin_input_ = path;
+ end_input_ = path + length;
+ p_ = begin_input_;
+
+ line_ = 1;
+ column_ = 1;
+ state_ = path_state::start;
+
+ recursive_descent_ = false;
+
+ clear_index();
+
+ while (p_ < end_input_)
+ {
+ switch (state_)
+ {
+ case path_state::cr:
+ ++line_;
+ column_ = 1;
+ switch (*p_)
+ {
+ case '\n':
+ state_ = pre_line_break_state;
+ ++p_;
+ ++column_;
+ break;
+ default:
+ state_ = pre_line_break_state;
+ break;
+ }
+ break;
+ case path_state::lf:
+ ++line_;
+ column_ = 1;
+ state_ = pre_line_break_state;
+ break;
+ case path_state::start:
+ switch (*p_)
+ {
+ case ' ':case '\t':
+ break;
+ case '$':
+ case '@':
+ {
+ string_type s;
+ s.push_back('$');
+ node_set v;
+ v.emplace_back(std::move(s),std::addressof(root));
+ stack_.push_back(v);
+
+ state_ = path_state::expect_dot_or_left_bracket;
+ }
+ break;
+ default:
+ err_handler_->fatal_error(jsonpath_parser_errc::expected_root, *this);
+ ec = jsonpath_parser_errc::expected_root;
+ return;
+ };
+ ++p_;
+ ++column_;
+ break;
+ case path_state::dot:
+ switch (*p_)
+ {
+ case '.':
+ recursive_descent_ = true;
+ ++p_;
+ ++column_;
+ state_ = path_state::expect_unquoted_name_or_left_bracket;
+ break;
+ default:
+ state_ = path_state::expect_unquoted_name_or_left_bracket;
+ break;
+ }
+ break;
+ case path_state::expect_unquoted_name_or_left_bracket:
+ switch (*p_)
+ {
+ case '.':
+ err_handler_->fatal_error(jsonpath_parser_errc::expected_name, *this);
+ ec = jsonpath_parser_errc::expected_name;
+ return;
+ case '*':
+ end_all();
+ transfer_nodes();
+ state_ = path_state::expect_dot_or_left_bracket;
+ ++p_;
+ ++column_;
+ break;
+ case '[':
+ state_ = path_state::left_bracket;
+ ++p_;
+ ++column_;
+ break;
+ default:
+ buffer_.clear();
+ state_ = path_state::unquoted_name;
+ break;
+ }
+ break;
+ case path_state::expect_dot_or_left_bracket:
+ switch (*p_)
+ {
+ case ' ':case '\t':
+ break;
+ case '.':
+ state_ = path_state::dot;
+ break;
+ case '[':
+ state_ = path_state::left_bracket;
+ break;
+ default:
+ err_handler_->fatal_error(jsonpath_parser_errc::expected_separator, *this);
+ ec = jsonpath_parser_errc::expected_separator;
+ return;
+ };
+ ++p_;
+ ++column_;
+ break;
+ case path_state::expect_comma_or_right_bracket:
+ switch (*p_)
+ {
+ case ',':
+ state_ = path_state::left_bracket;
+ break;
+ case ']':
+ apply_selectors();
+ state_ = path_state::expect_dot_or_left_bracket;
+ break;
+ case ' ':case '\t':
+ break;
+ default:
+ err_handler_->fatal_error(jsonpath_parser_errc::expected_right_bracket, *this);
+ ec = jsonpath_parser_errc::expected_right_bracket;
+ return;
+ }
+ ++p_;
+ ++column_;
+ break;
+ case path_state::left_bracket:
+ switch (*p_)
+ {
+ case ' ':case '\t':
+ ++p_;
+ ++column_;
+ break;
+ case '(':
+ {
+ jsonpath_filter_parser<Json> parser(line_,column_);
+ auto result = parser.parse(root, p_,end_input_,&p_);
+ line_ = parser.line();
+ column_ = parser.column();
+ selectors_.push_back(std::make_shared<expr_selector>(result));
+ state_ = path_state::expect_comma_or_right_bracket;
+ }
+ break;
+ case '?':
+ {
+ jsonpath_filter_parser<Json> parser(line_,column_);
+ auto result = parser.parse(root,p_,end_input_,&p_);
+ line_ = parser.line();
+ column_ = parser.column();
+ selectors_.push_back(std::make_shared<filter_selector>(result));
+ state_ = path_state::expect_comma_or_right_bracket;
+ }
+ break;
+ case ':':
+ clear_index();
+ state_ = path_state::left_bracket_end;
+ ++p_;
+ ++column_;
+ break;
+ case '*':
+ end_all();
+ state_ = path_state::expect_comma_or_right_bracket;
+ ++p_;
+ ++column_;
+ break;
+ case '\'':
+ state_ = path_state::left_bracket_single_quoted_string;
+ ++p_;
+ ++column_;
+ break;
+ case '\"':
+ state_ = path_state::left_bracket_double_quoted_string;
+ ++p_;
+ ++column_;
+ break;
+ default:
+ clear_index();
+ buffer_.push_back(*p_);
+ state_ = path_state::left_bracket_start;
+ ++p_;
+ ++column_;
+ break;
+ }
+ break;
+ case path_state::left_bracket_start:
+ switch (*p_)
+ {
+ case ':':
+ if (!try_string_to_index(buffer_.data(), buffer_.size(), &start_, &positive_start_))
+ {
+ err_handler_->fatal_error(jsonpath_parser_errc::expected_index, *this);
+ ec = jsonpath_parser_errc::expected_index;
+ return;
+ }
+ state_ = path_state::left_bracket_end;
+ break;
+ case ',':
+ selectors_.push_back(std::make_shared<name_selector>(buffer_,positive_start_));
+ buffer_.clear();
+ state_ = path_state::left_bracket;
+ break;
+ case ']':
+ selectors_.push_back(std::make_shared<name_selector>(buffer_,positive_start_));
+ buffer_.clear();
+ apply_selectors();
+ state_ = path_state::expect_dot_or_left_bracket;
+ break;
+ default:
+ buffer_.push_back(*p_);
+ break;
+ }
+ ++p_;
+ ++column_;
+ break;
+ case path_state::left_bracket_end:
+ switch (*p_)
+ {
+ case '-':
+ positive_end_ = false;
+ state_ = path_state::left_bracket_end2;
+ break;
+ case ':':
+ step_ = 0;
+ state_ = path_state::left_bracket_step;
+ break;
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
+ undefined_end_ = false;
+ end_ = static_cast<size_t>(*p_-'0');
+ state_ = path_state::left_bracket_end2;
+ break;
+ case ',':
+ selectors_.push_back(std::make_shared<array_slice_selector>(start_,positive_start_,end_,positive_end_,step_,positive_step_,undefined_end_));
+ state_ = path_state::left_bracket;
+ break;
+ case ']':
+ selectors_.push_back(std::make_shared<array_slice_selector>(start_,positive_start_,end_,positive_end_,step_,positive_step_,undefined_end_));
+ apply_selectors();
+ state_ = path_state::expect_dot_or_left_bracket;
+ break;
+ }
+ ++p_;
+ ++column_;
+ break;
+ case path_state::left_bracket_end2:
+ switch (*p_)
+ {
+ case ':':
+ step_ = 0;
+ state_ = path_state::left_bracket_step;
+ break;
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
+ undefined_end_ = false;
+ end_ = end_*10 + static_cast<size_t>(*p_-'0');
+ break;
+ case ',':
+ selectors_.push_back(std::make_shared<array_slice_selector>(start_,positive_start_,end_,positive_end_,step_,positive_step_,undefined_end_));
+ state_ = path_state::left_bracket;
+ break;
+ case ']':
+ selectors_.push_back(std::make_shared<array_slice_selector>(start_,positive_start_,end_,positive_end_,step_,positive_step_,undefined_end_));
+ apply_selectors();
+ state_ = path_state::expect_dot_or_left_bracket;
+ break;
+ }
+ ++p_;
+ ++column_;
+ break;
+ case path_state::left_bracket_step:
+ switch (*p_)
+ {
+ case '-':
+ positive_step_ = false;
+ state_ = path_state::left_bracket_step2;
+ break;
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
+ step_ = static_cast<size_t>(*p_-'0');
+ state_ = path_state::left_bracket_step2;
+ break;
+ case ',':
+ selectors_.push_back(std::make_shared<array_slice_selector>(start_,positive_start_,end_,positive_end_,step_,positive_step_,undefined_end_));
+ state_ = path_state::left_bracket;
+ break;
+ case ']':
+ selectors_.push_back(std::make_shared<array_slice_selector>(start_,positive_start_,end_,positive_end_,step_,positive_step_,undefined_end_));
+ apply_selectors();
+ state_ = path_state::expect_dot_or_left_bracket;
+ break;
+ }
+ ++p_;
+ ++column_;
+ break;
+ case path_state::left_bracket_step2:
+ switch (*p_)
+ {
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
+ step_ = step_*10 + static_cast<size_t>(*p_-'0');
+ break;
+ case ',':
+ selectors_.push_back(std::make_shared<array_slice_selector>(start_,positive_start_,end_,positive_end_,step_,positive_step_,undefined_end_));
+ state_ = path_state::left_bracket;
+ break;
+ case ']':
+ selectors_.push_back(std::make_shared<array_slice_selector>(start_,positive_start_,end_,positive_end_,step_,positive_step_,undefined_end_));
+ apply_selectors();
+ state_ = path_state::expect_dot_or_left_bracket;
+ break;
+ }
+ ++p_;
+ ++column_;
+ break;
+ case path_state::unquoted_name:
+ switch (*p_)
+ {
+ case '[':
+ apply_unquoted_string(buffer_);
+ transfer_nodes();
+ start_ = 0;
+ state_ = path_state::left_bracket;
+ break;
+ case '.':
+ apply_unquoted_string(buffer_);
+ transfer_nodes();
+ state_ = path_state::dot;
+ break;
+ case ' ':case '\t':
+ apply_unquoted_string(buffer_);
+ transfer_nodes();
+ state_ = path_state::expect_dot_or_left_bracket;
+ break;
+ case '\r':
+ apply_unquoted_string(buffer_);
+ transfer_nodes();
+ pre_line_break_state = path_state::expect_dot_or_left_bracket;
+ state_= path_state::cr;
+ break;
+ case '\n':
+ apply_unquoted_string(buffer_);
+ transfer_nodes();
+ pre_line_break_state = path_state::expect_dot_or_left_bracket;
+ state_= path_state::lf;
+ break;
+ default:
+ buffer_.push_back(*p_);
+ break;
+ };
+ ++p_;
+ ++column_;
+ break;
+ case path_state::left_bracket_single_quoted_string:
+ switch (*p_)
+ {
+ case '\'':
+ selectors_.push_back(std::make_shared<name_selector>(buffer_,positive_start_));
+ buffer_.clear();
+ state_ = path_state::expect_comma_or_right_bracket;
+ break;
+ case '\\':
+ buffer_.push_back(*p_);
+ if (p_+1 < end_input_)
+ {
+ ++p_;
+ ++column_;
+ buffer_.push_back(*p_);
+ }
+ break;
+ default:
+ buffer_.push_back(*p_);
+ break;
+ };
+ ++p_;
+ ++column_;
+ break;
+ case path_state::left_bracket_double_quoted_string:
+ switch (*p_)
+ {
+ case '\"':
+ selectors_.push_back(std::make_shared<name_selector>(buffer_,positive_start_));
+ buffer_.clear();
+ state_ = path_state::expect_comma_or_right_bracket;
+ break;
+ case '\\':
+ buffer_.push_back(*p_);
+ if (p_+1 < end_input_)
+ {
+ ++p_;
+ ++column_;
+ buffer_.push_back(*p_);
+ }
+ break;
+ default:
+ buffer_.push_back(*p_);
+ break;
+ };
+ ++p_;
+ ++column_;
+ break;
+ default:
+ ++p_;
+ ++column_;
+ break;
+ }
+ }
+ switch (state_)
+ {
+ case path_state::unquoted_name:
+ {
+ apply_unquoted_string(buffer_);
+ transfer_nodes();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ void clear_index()
+ {
+ buffer_.clear();
+ start_ = 0;
+ positive_start_ = true;
+ end_ = 0;
+ positive_end_ = true;
+ undefined_end_ = true;
+ step_ = 1;
+ positive_step_ = true;
+ }
+
+ void end_all()
+ {
+ for (size_t i = 0; i < stack_.back().size(); ++i)
+ {
+ const auto& path = stack_.back()[i].path;
+ pointer p = stack_.back()[i].val_ptr;
+
+ if (p->is_array())
+ {
+ for (auto it = p->array_range().begin(); it != p->array_range().end(); ++it)
+ {
+ nodes_.emplace_back(PathCons()(path,it - p->array_range().begin()),std::addressof(*it));
+ }
+ }
+ else if (p->is_object())
+ {
+ for (auto it = p->object_range().begin(); it != p->object_range().end(); ++it)
+ {
+ nodes_.emplace_back(PathCons()(path,it->key()),std::addressof(it->value()));
+ }
+ }
+
+ }
+ start_ = 0;
+ }
+
+ void apply_unquoted_string(const string_view_type& name)
+ {
+ if (name.length() > 0)
+ {
+ for (size_t i = 0; i < stack_.back().size(); ++i)
+ {
+ apply_unquoted_string(stack_.back()[i].path, *(stack_.back()[i].val_ptr), name);
+ }
+ }
+ buffer_.clear();
+ }
+
+ void apply_unquoted_string(const string_type& path, reference val, const string_view_type& name)
+ {
+ if (val.is_object())
+ {
+ if (val.count(name) > 0)
+ {
+ nodes_.emplace_back(PathCons()(path,name),std::addressof(val.at(name)));
+ }
+ if (recursive_descent_)
+ {
+ for (auto it = val.object_range().begin(); it != val.object_range().end(); ++it)
+ {
+ if (it->value().is_object() || it->value().is_array())
+ {
+ apply_unquoted_string(path, it->value(), name);
+ }
+ }
+ }
+ }
+ else if (val.is_array())
+ {
+ size_t pos = 0;
+ if (try_string_to_index(name.data(),name.size(),&pos, &positive_start_))
+ {
+ size_t index = positive_start_ ? pos : val.size() - pos;
+ if (index < val.size())
+ {
+ nodes_.emplace_back(PathCons()(path,index),std::addressof(val[index]));
+ }
+ }
+ else if (name == length_literal() && val.size() > 0)
+ {
+ auto temp = std::make_shared<Json>(val.size());
+ temp_json_values_.push_back(temp);
+ nodes_.emplace_back(PathCons()(path,name),temp.get());
+ }
+ if (recursive_descent_)
+ {
+ for (auto it = val.array_range().begin(); it != val.array_range().end(); ++it)
+ {
+ if (it->is_object() || it->is_array())
+ {
+ apply_unquoted_string(path, *it, name);
+ }
+ }
+ }
+ }
+ else if (val.is_string())
+ {
+ string_view_type sv = val.as_string_view();
+ size_t pos = 0;
+ if (try_string_to_index(name.data(),name.size(),&pos, &positive_start_))
+ {
+ auto sequence = unicons::sequence_at(sv.data(), sv.data() + sv.size(), pos);
+ if (sequence.length() > 0)
+ {
+ auto temp = std::make_shared<Json>(sequence.begin(),sequence.length());
+ temp_json_values_.push_back(temp);
+ nodes_.emplace_back(PathCons()(path,pos),temp.get());
+ }
+ }
+ else if (name == length_literal() && sv.size() > 0)
+ {
+ size_t count = unicons::u32_length(sv.begin(),sv.end());
+ auto temp = std::make_shared<Json>(count);
+ temp_json_values_.push_back(temp);
+ nodes_.emplace_back(PathCons()(path,name),temp.get());
+ }
+ }
+ }
+
+ void apply_selectors()
+ {
+ if (selectors_.size() > 0)
+ {
+ for (size_t i = 0; i < stack_.back().size(); ++i)
+ {
+ node_type& node = stack_.back()[i];
+ apply_selectors(node, node.path, *(node.val_ptr));
+ }
+ selectors_.clear();
+ }
+ transfer_nodes();
+ }
+
+ void apply_selectors(node_type& node, const string_type& path, reference val)
+ {
+ for (const auto& selector : selectors_)
+ {
+ selector->select(node, path, val, nodes_, temp_json_values_);
+ }
+ if (recursive_descent_)
+ {
+ if (val.is_object())
+ {
+ for (auto& nvp : val.object_range())
+ {
+ if (nvp.value().is_object() || nvp.value().is_array())
+ {
+ apply_selectors(node,PathCons()(path,nvp.key()),nvp.value());
+ }
+ }
+ }
+ else if (val.is_array())
+ {
+ for (auto& elem : val.array_range())
+ {
+ if (elem.is_object() || elem.is_array())
+ {
+ apply_selectors(node,path, elem);
+ }
+ }
+ }
+ }
+ }
+
+ void transfer_nodes()
+ {
+ stack_.push_back(nodes_);
+ nodes_.clear();
+ recursive_descent_ = false;
+ }
+
+ size_t do_line_number() const override
+ {
+ return line_;
+ }
+
+ size_t do_column_number() const override
+ {
+ return column_;
+ }
+
+};
+
+}
+
+}}
+
+#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons_ext/jsonpath/jsonpath_error_category.hpp b/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpath/jsonpath_error_category.hpp
index 7f6b6a12..62aa5889 100644
--- a/vendor/jsoncons-0.99.2/jsoncons_ext/jsonpath/jsonpath_error_category.hpp
+++ b/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpath/jsonpath_error_category.hpp
@@ -7,24 +7,28 @@
#ifndef JSONCONS_JSONPATH_JSONPATH_ERROR_CATEGORY_HPP
#define JSONCONS_JSONPATH_JSONPATH_ERROR_CATEGORY_HPP
-#include "jsoncons/jsoncons.hpp"
+#include <jsoncons/json_exception.hpp>
#include <system_error>
namespace jsoncons { namespace jsonpath {
-namespace jsonpath_parser_errc
+enum class jsonpath_parser_errc
{
- const int expected_root = 1;
- const int expected_right_bracket = 2;
- const int expected_name = 3;
- const int expected_separator = 4;
- const int invalid_filter = 5;
- const int invalid_filter_expected_slash = 6;
- const int invalid_filter_unbalanced_paren = 7;
- const int invalid_filter_unsupported_operator = 8;
- const int invalid_filter_expected_right_brace = 9;
- const int invalid_filter_expected_primary = 10;
-}
+ ok = 0,
+ expected_root = 1,
+ expected_right_bracket = 2,
+ expected_name = 3,
+ expected_separator = 4,
+ invalid_filter = 5,
+ invalid_filter_expected_slash = 6,
+ invalid_filter_unbalanced_paren = 7,
+ invalid_filter_unsupported_operator = 8,
+ invalid_filter_expected_right_brace = 9,
+ invalid_filter_expected_primary = 10,
+ expected_index = 11,
+ expected_left_bracket_token = 12,
+ unexpected_operator = 13
+};
class jsonpath_error_category_impl
: public std::error_category
@@ -36,7 +40,7 @@ public:
}
virtual std::string message(int ev) const
{
- switch (ev)
+ switch (static_cast<jsonpath_parser_errc>(ev))
{
case jsonpath_parser_errc::expected_root:
return "Expected $";
@@ -44,6 +48,8 @@ public:
return "Expected ]";
case jsonpath_parser_errc::expected_name:
return "Expected a name following a dot";
+ case jsonpath_parser_errc::expected_index:
+ return "Expected index";
case jsonpath_parser_errc::expected_separator:
return "Expected dot or left bracket separator";
case jsonpath_parser_errc::invalid_filter:
@@ -58,6 +64,8 @@ public:
return "Invalid path filter, expected right brace }";
case jsonpath_parser_errc::invalid_filter_expected_primary:
return "Invalid path filter, expected primary expression.";
+ case jsonpath_parser_errc::expected_left_bracket_token:
+ return "Expected ?,',\",0-9,*";
default:
return "Unknown jsonpath parser error";
}
@@ -71,5 +79,19 @@ const std::error_category& jsonpath_error_category()
return instance;
}
+inline
+std::error_code make_error_code(jsonpath_parser_errc result)
+{
+ return std::error_code(static_cast<int>(result),jsonpath_error_category());
+}
+
}}
+
+namespace std {
+ template<>
+ struct is_error_code_enum<jsoncons::jsonpath::jsonpath_parser_errc> : public true_type
+ {
+ };
+}
+
#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpath/jsonpath_filter.hpp b/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpath/jsonpath_filter.hpp
new file mode 100644
index 00000000..c3af2edd
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpath/jsonpath_filter.hpp
@@ -0,0 +1,1874 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSONPATH_FILTER_HPP
+#define JSONCONS_JSONPATH_FILTER_HPP
+
+#include <string>
+#include <map>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <cstdlib>
+#include <memory>
+#include <regex>
+#include <functional>
+#include <cmath>
+#include <jsoncons/json.hpp>
+#include "jsonpath_error_category.hpp"
+
+namespace jsoncons { namespace jsonpath { namespace detail {
+
+JSONCONS_DEFINE_LITERAL(eqtilde_literal,"=~")
+JSONCONS_DEFINE_LITERAL(star_literal,"*")
+JSONCONS_DEFINE_LITERAL(forwardslash_literal,"/")
+JSONCONS_DEFINE_LITERAL(plus_literal,"+")
+JSONCONS_DEFINE_LITERAL(minus_literal,"-")
+JSONCONS_DEFINE_LITERAL(lt_literal,"<")
+JSONCONS_DEFINE_LITERAL(lte_literal,"<=")
+JSONCONS_DEFINE_LITERAL(gt_literal,">")
+JSONCONS_DEFINE_LITERAL(gte_literal,">=")
+JSONCONS_DEFINE_LITERAL(eq_literal,"==")
+JSONCONS_DEFINE_LITERAL(ne_literal,"!=")
+JSONCONS_DEFINE_LITERAL(ampamp_literal,"&&")
+JSONCONS_DEFINE_LITERAL(pipepipe_literal,"||")
+JSONCONS_DEFINE_LITERAL(max_literal,"max")
+JSONCONS_DEFINE_LITERAL(min_literal,"min")
+
+template<class Json>
+struct PathConstructor
+{
+ typedef typename Json::char_type char_type;
+ typedef typename Json::string_view_type string_view_type;
+ typedef typename Json::string_type string_type;
+
+ string_type operator()(const string_type& path, size_t index) const
+ {
+ char_type buf[255];
+ char_type* p = buf;
+ do
+ {
+ *p++ = static_cast<char_type>(48 + index % 10);
+ } while (index /= 10);
+
+ string_type s;
+ s.append(path);
+ s.push_back('[');
+ while (--p >= buf)
+ {
+ s.push_back(*p);
+ }
+ s.push_back(']');
+ return s;
+ }
+
+ string_type operator()(const string_type& path, const string_view_type& sv) const
+ {
+ string_type s;
+ s.append(path);
+ s.push_back('[');
+ s.push_back('\'');
+ s.append(sv.data(),sv.length());
+ s.push_back('\'');
+ s.push_back(']');
+ return s;
+ }
+};
+
+template<class Json>
+struct VoidPathConstructor
+{
+ typedef typename Json::char_type char_type;
+ typedef typename Json::string_view_type string_view_type;
+ typedef typename Json::string_type string_type;
+
+ string_type operator()(const string_type&, size_t) const
+ {
+ return string_type{};
+ }
+
+ string_type operator()(const string_type&, string_view_type) const
+ {
+ return string_type{};
+ }
+};
+
+template <class Json,
+ class JsonReference,
+ class PathCons>
+class jsonpath_evaluator;
+
+enum class filter_state
+{
+ start,
+ cr,
+ lf,
+ expect_right_round_bracket,
+ expect_oper_or_right_round_bracket,
+ expect_path_or_value_or_unary_op,
+ expect_regex,
+ regex,
+ single_quoted_text,
+ double_quoted_text,
+ unquoted_text,
+ path,
+ value,
+ oper,
+ function_argument,
+ done
+};
+
+enum class token_type
+{
+ operand,
+ unary_operator,
+ binary_operator,
+ lparen,
+ rparen
+};
+
+template <class Json>
+class term
+{
+public:
+ typedef typename Json::string_type string_type;
+ typedef typename Json::char_type char_type;
+
+ virtual ~term() {}
+
+ virtual void initialize(const Json&)
+ {
+ }
+ virtual bool accept_single_node() const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual Json evaluate_single_node() const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual bool exclaim() const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual bool eq_term(const term&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual bool eq(const Json&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual bool ne_term(const term&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual bool ne(const Json&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual bool regex_term(const term&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual bool regex2(const string_type&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual bool ampamp_term(const term&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual bool ampamp(const Json&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual bool pipepipe_term(const term&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual bool pipepipe(const Json&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual bool lt_term(const term&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual bool lt(const Json&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual bool gt_term(const term&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual bool gt(const Json&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+
+ virtual Json minus_term(const term&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual Json minus(const Json&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+
+ virtual Json left_minus(const Json&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+
+ virtual Json unary_minus() const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual Json plus_term(const term&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual Json plus(const Json&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual Json mult_term(const term&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual Json mult(const Json&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+
+ virtual Json div_term(const term&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+ virtual Json div(const Json&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+
+ virtual Json left_div(const Json&) const
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1);
+ }
+};
+
+template <class Json>
+struct operator_properties
+{
+ typedef std::function<Json(const term<Json>&, const term<Json>&)> operator_type;
+
+ size_t precedence_level;
+ bool is_right_associative;
+ operator_type op;
+};
+
+template <class Json>
+struct function_properties
+{
+ typedef std::function<Json(const term<Json>&)> function_type;
+
+ size_t precedence_level;
+ bool is_right_associative;
+ bool is_aggregate;
+ function_type op;
+};
+
+template <class Json>
+class token
+{
+ token_type type_;
+ size_t precedence_level_;
+ bool is_right_associative_;
+ bool is_aggregate_;
+ std::shared_ptr<term<Json>> operand_ptr_;
+ std::function<Json(const term<Json>&)> unary_operator_;
+ std::function<Json(const term<Json>&, const term<Json>&)> operator_;
+public:
+ typedef std::function<Json(const term<Json>&)> unary_operator_type;
+ typedef std::function<Json(const term<Json>&, const term<Json>&)> operator_type;
+
+ Json operator()(const term<Json>& a)
+ {
+ return unary_operator_(a);
+ }
+
+ Json operator()(const term<Json>& a, const term<Json>& b)
+ {
+ return operator_(a,b);
+ }
+
+ token(token_type type)
+ : type_(type),precedence_level_(0),is_right_associative_(false),is_aggregate_(false)
+ {
+ }
+ token(token_type type, std::shared_ptr<term<Json>> term_ptr)
+ : type_(type),precedence_level_(0),is_right_associative_(false),is_aggregate_(false),operand_ptr_(term_ptr)
+ {
+ }
+ token(size_t precedence_level,
+ bool is_right_associative,
+ std::function<Json(const term<Json>&)> unary_operator)
+ : type_(token_type::unary_operator),
+ precedence_level_(precedence_level),
+ is_right_associative_(is_right_associative),
+ is_aggregate_(false),
+ unary_operator_(unary_operator)
+ {
+ }
+ token(const operator_properties<Json>& properties)
+ : type_(token_type::binary_operator),
+ precedence_level_(properties.precedence_level),
+ is_right_associative_(properties.is_right_associative),
+ is_aggregate_(false),
+ operator_(properties.op)
+ {
+ }
+ token(const function_properties<Json>& properties)
+ : type_(token_type::unary_operator),
+ precedence_level_(properties.precedence_level),
+ is_right_associative_(properties.is_right_associative),
+ is_aggregate_(properties.is_aggregate),
+ unary_operator_(properties.op)
+ {
+ }
+ token(const token& t) = default;
+ //token(token&& t) = default;
+
+ token<Json>& operator=(const token<Json>& val) = default;
+ //token<Json>& operator=(token<Json>&& val) = default;
+
+ bool is_operator() const
+ {
+ return is_unary_operator() || is_binary_operator();
+ }
+
+ bool is_unary_operator() const
+ {
+ return type_ == token_type::unary_operator;
+ }
+
+ bool is_binary_operator() const
+ {
+ return type_ == token_type::binary_operator;
+ }
+
+ bool is_operand() const
+ {
+ return type_ == token_type::operand;
+ }
+
+ bool is_lparen() const
+ {
+ return type_ == token_type::lparen;
+ }
+
+ bool is_rparen() const
+ {
+ return type_ == token_type::rparen;
+ }
+
+ size_t precedence_level() const
+ {
+ return precedence_level_;
+ }
+
+ bool is_right_associative() const
+ {
+ return is_right_associative_;
+ }
+
+ bool is_aggregate() const
+ {
+ return is_aggregate_;
+ }
+
+ const term<Json>& operand()
+ {
+ JSONCONS_ASSERT(type_ == token_type::operand && operand_ptr_ != nullptr);
+ return *operand_ptr_;
+ }
+
+ void initialize(const Json& context_node)
+ {
+ if (operand_ptr_.get() != nullptr)
+ {
+ operand_ptr_->initialize(context_node);
+ }
+ }
+};
+
+template <class Json>
+bool ampamp(const Json& lhs, const Json& rhs)
+{
+ return lhs.as_bool() && rhs.as_bool();
+}
+
+template <class Json>
+bool pipepipe(const Json& lhs, const Json& rhs)
+{
+ return lhs.as_bool() || rhs.as_bool();
+}
+
+template <class Json>
+bool lt(const Json& lhs, const Json& rhs)
+{
+ bool result = false;
+ if (lhs. template is<unsigned long long>() && rhs. template is<unsigned long long>())
+ {
+ result = lhs. template as<unsigned long long>() < rhs. template as<unsigned long long>();
+ }
+ else if (lhs. template is<long long>() && rhs. template is<long long>())
+ {
+ result = lhs. template as<long long>() < rhs. template as<long long>();
+ }
+ else if ((lhs.is_number() && rhs.is_double()) || (lhs.is_double() && rhs.is_number()))
+ {
+ result = lhs.as_double() < rhs.as_double();
+ }
+ else if (lhs.is_string() && rhs.is_string())
+ {
+ result = lhs.as_string_view() < rhs.as_string_view();
+ }
+ return result;
+}
+
+template <class Json>
+bool gt(const Json& lhs, const Json& rhs)
+{
+ return lt(rhs,lhs);
+}
+
+template <class Json>
+Json plus(const Json& lhs, const Json& rhs)
+{
+ Json result = Json(jsoncons::null_type());
+ if (lhs.is_integer() && rhs.is_integer())
+ {
+ result = Json(((lhs.as_integer() + rhs.as_integer())));
+ }
+ else if ((lhs.is_number() && rhs.is_double()) || (lhs.is_double() && rhs.is_number()))
+ {
+ result = Json((lhs.as_double() + rhs.as_double()));
+ }
+ else if (lhs.is_uinteger() && rhs.is_uinteger())
+ {
+ result = Json((lhs.as_uinteger() + rhs.as_uinteger()));
+ }
+ return result;
+}
+
+template <class Json>
+Json mult(const Json& lhs, const Json& rhs)
+{
+ Json result = Json(jsoncons::null_type());
+ if (lhs.is_integer() && rhs.is_integer())
+ {
+ result = Json(((lhs.as_integer() * rhs.as_integer())));
+ }
+ else if ((lhs.is_number() && rhs.is_double()) || (lhs.is_double() && rhs.is_number()))
+ {
+ result = Json((lhs.as_double() * rhs.as_double()));
+ }
+ else if (lhs.is_uinteger() && rhs.is_uinteger())
+ {
+ result = Json((lhs.as_uinteger() * rhs.as_uinteger()));
+ }
+ return result;
+}
+
+template <class Json>
+Json div(const Json& lhs, const Json& rhs)
+{
+ Json result = Json(jsoncons::null_type());
+ if (lhs.is_integer() && rhs.is_integer())
+ {
+ result = Json((double)(lhs.as_integer() / (double)rhs.as_integer()));
+ }
+ else if ((lhs.is_number() && rhs.is_double()) || (lhs.is_double() && rhs.is_number()))
+ {
+ result = Json((lhs.as_double() / rhs.as_double()));
+ }
+ else if (lhs.is_uinteger() && rhs.is_uinteger())
+ {
+ result = Json((double)(lhs.as_uinteger() / (double)rhs.as_uinteger()));
+ }
+ return result;
+}
+
+template <class Json>
+Json unary_minus(const Json& lhs)
+{
+ Json result = Json::null();
+ if (lhs.is_integer())
+ {
+ result = -lhs.as_integer();
+ }
+ else if (lhs.is_double())
+ {
+ result = -lhs.as_double();
+ }
+ return result;
+}
+
+template <class Json>
+Json minus(const Json& lhs, const Json& rhs)
+{
+ Json result = Json::null();
+ if (lhs.is_integer() && rhs.is_integer())
+ {
+ result = ((lhs.as_integer() - rhs.as_integer()));
+ }
+ else if ((lhs.is_number() && rhs.is_double()) || (lhs.is_double() && rhs.is_number()))
+ {
+ result = (lhs.as_double() - rhs.as_double());
+ }
+ else if (lhs.is_uinteger() && rhs.is_uinteger() && lt(rhs,lhs))
+ {
+ result = (lhs.as_uinteger() - rhs.as_uinteger());
+ }
+ return result;
+}
+
+template <class Json>
+class value_term final : public term<Json>
+{
+ Json value_;
+public:
+ template <class T>
+ value_term(const T& val)
+ : value_(val)
+ {
+ }
+
+ bool accept_single_node() const override
+ {
+ return value_.as_bool();
+ }
+
+ Json evaluate_single_node() const override
+ {
+ return value_;
+ }
+
+ bool exclaim() const override
+ {
+ return !value_.as_bool();
+ }
+
+ bool eq_term(const term<Json>& rhs) const override
+ {
+ return rhs.eq(value_);
+ }
+
+ bool eq(const Json& rhs) const override
+ {
+ return value_ == rhs;
+ }
+
+ bool ne_term(const term<Json>& rhs) const override
+ {
+ return rhs.ne(value_);
+ }
+ bool ne(const Json& rhs) const override
+ {
+ return value_ != rhs;
+ }
+ bool regex_term(const term<Json>& rhs) const override
+ {
+ return rhs.regex2(value_.as_string());
+ }
+ bool ampamp_term(const term<Json>& rhs) const override
+ {
+ return rhs.ampamp(value_);
+ }
+ bool ampamp(const Json& rhs) const override
+ {
+ return jsoncons::jsonpath::detail::ampamp(value_,rhs);
+ }
+ bool pipepipe_term(const term<Json>& rhs) const override
+ {
+ return rhs.pipepipe(value_);
+ }
+ bool pipepipe(const Json& rhs) const override
+ {
+ return jsoncons::jsonpath::detail::pipepipe(value_,rhs);
+ }
+
+ bool lt_term(const term<Json>& rhs) const override
+ {
+ return rhs.gt(value_);
+ }
+ bool lt(const Json& rhs) const override
+ {
+ return jsoncons::jsonpath::detail::lt(value_,rhs);
+ }
+
+ bool gt_term(const term<Json>& rhs) const override
+ {
+ return rhs.lt(value_);
+ }
+ bool gt(const Json& rhs) const override
+ {
+ return jsoncons::jsonpath::detail::gt(value_,rhs);
+ }
+
+ Json minus_term(const term<Json>& rhs) const override
+ {
+ return rhs.left_minus(value_);
+ }
+ Json minus(const Json& rhs) const override
+ {
+ return jsoncons::jsonpath::detail::minus(value_,rhs);
+ }
+
+ Json left_minus(const Json& lhs) const override
+ {
+ return jsoncons::jsonpath::detail::minus(lhs,value_);
+ }
+
+ Json unary_minus() const override
+ {
+ return jsoncons::jsonpath::detail::unary_minus(value_);
+ }
+
+ Json plus_term(const term<Json>& rhs) const override
+ {
+ return rhs.plus(value_);
+ }
+
+ Json plus(const Json& rhs) const override
+ {
+ return jsoncons::jsonpath::detail::plus(value_,rhs);
+ }
+ Json mult_term(const term<Json>& rhs) const override
+ {
+ return rhs.mult(value_);
+ }
+
+ Json mult(const Json& rhs) const override
+ {
+ return jsoncons::jsonpath::detail::mult(value_,rhs);
+ }
+
+ Json div_term(const term<Json>& rhs) const override
+ {
+ return rhs.left_div(value_);
+ }
+ Json div(const Json& rhs) const override
+ {
+ return jsoncons::jsonpath::detail::div(value_,rhs);
+ }
+
+ Json left_div(const Json& lhs) const override
+ {
+ return jsoncons::jsonpath::detail::div(lhs,value_);
+ }
+};
+
+template <class Json>
+class regex_term final : public term<Json>
+{
+ typedef typename Json::char_type char_type;
+ typedef typename Json::string_type string_type;
+ const std::basic_regex<char_type> pattern_;
+public:
+ regex_term(const string_type& pattern, std::regex::flag_type flags)
+ : pattern_(pattern,flags)
+ {
+ }
+
+ bool regex2(const string_type& subject) const override
+ {
+ return std::regex_match(subject, pattern_);
+ }
+};
+
+template <class Json>
+class path_term final : public term<Json>
+{
+ typedef typename Json::string_type string_type;
+
+ string_type path_;
+ Json nodes_;
+public:
+ path_term(const string_type& path)
+ : path_(path)
+ {
+ }
+
+ void initialize(const Json& context_node) override
+ {
+ jsonpath_evaluator<Json,const Json&,VoidPathConstructor<Json>> evaluator;
+ evaluator.evaluate(context_node,path_);
+ nodes_ = evaluator.get_values();
+ }
+
+ bool accept_single_node() const override
+ {
+ return nodes_.size() != 0;
+ }
+
+ Json evaluate_single_node() const override
+ {
+ return nodes_.size() == 1 ? nodes_[0] : nodes_;
+ }
+
+ bool exclaim() const override
+ {
+ return nodes_.size() == 0;
+ }
+
+ bool eq_term(const term<Json>& rhs) const override
+ {
+ bool result = false;
+ if (nodes_.size() > 0)
+ {
+ result = true;
+ for (size_t i = 0; result && i < nodes_.size(); ++i)
+ {
+ result = rhs.eq(nodes_[i]);
+ }
+ }
+ return result;
+ }
+
+ bool eq(const Json& rhs) const override
+ {
+ bool result = false;
+ if (nodes_.size() > 0)
+ {
+ result = true;
+ for (size_t i = 0; result && i < nodes_.size(); ++i)
+ {
+ result = nodes_[i] == rhs;
+ }
+ }
+ return result;
+ }
+
+ bool ne_term(const term<Json>& rhs) const override
+ {
+ bool result = false;
+ if (nodes_.size() > 0)
+ {
+ result = true;
+ for (size_t i = 0; result && i < nodes_.size(); ++i)
+ {
+ result = rhs.ne(nodes_[i]);
+ }
+ }
+ return result;
+
+ }
+ bool ne(const Json& rhs) const override
+ {
+ bool result = false;
+ if (nodes_.size() > 0)
+ {
+ result = true;
+ for (size_t i = 0; result && i < nodes_.size(); ++i)
+ {
+ result = nodes_[i] != rhs;
+ }
+ }
+ return result;
+ }
+ bool regex_term(const term<Json>& rhs) const override
+ {
+ bool result = false;
+ if (nodes_.size() > 0)
+ {
+ result = true;
+ for (size_t i = 0; result && i < nodes_.size(); ++i)
+ {
+ result = rhs.regex2(nodes_[i].as_string());
+ }
+ }
+ return result;
+ }
+ bool ampamp_term(const term<Json>& rhs) const override
+ {
+ bool result = false;
+ if (nodes_.size() > 0)
+ {
+ result = true;
+ for (size_t i = 0; result && i < nodes_.size(); ++i)
+ {
+ result = rhs.ampamp(nodes_[i]);
+ }
+ }
+ return result;
+ }
+ bool ampamp(const Json& rhs) const override
+ {
+ bool result = false;
+ if (nodes_.size() > 0)
+ {
+ result = true;
+ for (size_t i = 0; result && i < nodes_.size(); ++i)
+ {
+ result = jsoncons::jsonpath::detail::ampamp(nodes_[i],rhs);
+ }
+ }
+ return result;
+ }
+ bool pipepipe_term(const term<Json>& rhs) const override
+ {
+ bool result = false;
+ if (nodes_.size() > 0)
+ {
+ result = true;
+ for (size_t i = 0; result && i < nodes_.size(); ++i)
+ {
+ result = rhs.pipepipe(nodes_[i]);
+ }
+ }
+ return result;
+ }
+ bool pipepipe(const Json& rhs) const override
+ {
+ bool result = false;
+ if (nodes_.size() > 0)
+ {
+ result = true;
+ for (size_t i = 0; result && i < nodes_.size(); ++i)
+ {
+ result = jsoncons::jsonpath::detail::pipepipe(nodes_[i],rhs);
+ }
+ }
+ return result;
+ }
+
+ bool lt(const Json& rhs) const override
+ {
+ bool result = false;
+ if (nodes_.size() > 0)
+ {
+ result = true;
+ for (size_t i = 0; result && i < nodes_.size(); ++i)
+ {
+ result = jsoncons::jsonpath::detail::lt(nodes_[i],rhs);
+ }
+ }
+ return result;
+ }
+
+ bool lt_term(const term<Json>& rhs) const override
+ {
+ bool result = false;
+ if (nodes_.size() > 0)
+ {
+ result = true;
+ for (size_t i = 0; result && i < nodes_.size(); ++i)
+ {
+ result = rhs.gt(nodes_[i]);
+ }
+ }
+ return result;
+ }
+
+ bool gt(const Json& rhs) const override
+ {
+ bool result = false;
+ if (nodes_.size() > 0)
+ {
+ result = true;
+ for (size_t i = 0; result && i < nodes_.size(); ++i)
+ {
+ result = jsoncons::jsonpath::detail::gt(nodes_[i],rhs);
+ }
+ }
+ return result;
+ }
+
+ bool gt_term(const term<Json>& rhs) const override
+ {
+ bool result = false;
+ if (nodes_.size() > 0)
+ {
+ result = true;
+ for (size_t i = 0; result && i < nodes_.size(); ++i)
+ {
+ result = rhs.lt(nodes_[i]);
+ }
+ }
+ return result;
+ }
+
+ Json minus_term(const term<Json>& rhs) const override
+ {
+ static auto a_null = Json(jsoncons::null_type());
+ return nodes_.size() == 1 ? rhs.left_minus(nodes_[0]) : a_null;
+ }
+ Json minus(const Json& rhs) const override
+ {
+ return nodes_.size() == 1 ? jsoncons::jsonpath::detail::minus(nodes_[0],rhs) : Json(jsoncons::null_type());
+ }
+
+ Json left_minus(const Json& lhs) const override
+ {
+ static auto a_null = Json(jsoncons::null_type());
+ return nodes_.size() == 1 ? jsoncons::jsonpath::detail::minus(lhs,nodes_[0]) : a_null;
+ }
+
+ Json unary_minus() const override
+ {
+ return nodes_.size() == 1 ? jsoncons::jsonpath::detail::unary_minus(nodes_[0]) : Json::null();
+ }
+
+ Json plus_term(const term<Json>& rhs) const override
+ {
+ static auto a_null = Json(jsoncons::null_type());
+ return nodes_.size() == 1 ? rhs.plus(nodes_[0]) : a_null;
+ }
+ Json plus(const Json& rhs) const override
+ {
+ static auto a_null = Json(jsoncons::null_type());
+ return nodes_.size() == 1 ? jsoncons::jsonpath::detail::plus(nodes_[0],rhs) : a_null;
+ }
+
+ Json mult_term(const term<Json>& rhs) const override
+ {
+ static auto a_null = Json(jsoncons::null_type());
+ return nodes_.size() == 1 ? rhs.mult(nodes_[0]) : a_null;
+ }
+ Json mult(const Json& rhs) const override
+ {
+ static auto a_null = Json(jsoncons::null_type());
+ return nodes_.size() == 1 ? jsoncons::jsonpath::detail::mult(nodes_[0],rhs) : a_null;
+ }
+
+ Json div_term(const term<Json>& rhs) const override
+ {
+ static auto a_null = Json(jsoncons::null_type());
+ return nodes_.size() == 1 ? rhs.left_div(nodes_[0]) : a_null;
+ }
+ Json div(const Json& rhs) const override
+ {
+ static auto a_null = Json(jsoncons::null_type());
+ return nodes_.size() == 1 ? jsoncons::jsonpath::detail::div(nodes_[0],rhs) : a_null;
+ }
+
+ Json left_div(const Json& lhs) const override
+ {
+ static auto a_null = Json(jsoncons::null_type());
+ return nodes_.size() == 1 ? jsoncons::jsonpath::detail::div(lhs, nodes_[0]) : a_null;
+ }
+};
+
+template <class Json>
+token<Json> evaluate(const Json& context, std::vector<token<Json>>& tokens)
+{
+ for (auto it= tokens.begin(); it != tokens.end(); ++it)
+ {
+ it->initialize(context);
+ }
+ std::vector<token<Json>> stack;
+ for (auto t : tokens)
+ {
+ if (t.is_operand())
+ {
+ stack.push_back(t);
+ }
+ else if (t.is_unary_operator())
+ {
+ auto rhs = stack.back();
+ stack.pop_back();
+ Json val = t(rhs.operand());
+ stack.push_back(token<Json>(token_type::operand,std::make_shared<value_term<Json>>(val)));
+ }
+ else if (t.is_binary_operator())
+ {
+ auto rhs = stack.back();
+ stack.pop_back();
+ auto lhs = stack.back();
+ stack.pop_back();
+ Json val = t(lhs.operand(), rhs.operand());
+ stack.push_back(token<Json>(token_type::operand,std::make_shared<value_term<Json>>(val)));
+ }
+ }
+ if (stack.size() != 1)
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Invalid state"));
+ }
+
+ return stack.back();
+}
+
+template <class Json>
+class jsonpath_filter_expr
+{
+public:
+ std::vector<token<Json>> tokens_;
+ size_t line_;
+ size_t column_;
+public:
+
+ jsonpath_filter_expr(const std::vector<token<Json>>& tokens, size_t line, size_t column)
+ : tokens_(tokens), line_(line), column_(column)
+ {
+ }
+
+ Json eval(const Json& context_node)
+ {
+ try
+ {
+ auto t = evaluate(context_node,tokens_);
+
+ return t.operand().evaluate_single_node();
+
+ }
+ catch (const parse_error& e)
+ {
+ throw parse_error(e.code(),line_,column_);
+ }
+ }
+
+ bool exists(const Json& context_node)
+ {
+ try
+ {
+ auto t = evaluate(context_node,tokens_);
+ return t.operand().accept_single_node();
+ }
+ catch (const parse_error& e)
+ {
+ throw parse_error(e.code(),line_,column_);
+ }
+ }
+};
+
+template <class Json>
+class jsonpath_filter_parser
+{
+ typedef typename Json::string_type string_type;
+ typedef typename Json::string_view_type string_view_type;
+ typedef typename Json::char_type char_type;
+
+ std::vector<token<Json>> output_stack_;
+ std::vector<token<Json>> operator_stack_;
+ std::vector<filter_state> state_stack_;
+
+ size_t line_;
+ size_t column_;
+
+ static const operator_properties<Json> op_properties_[];
+
+ class function_table
+ {
+ typedef std::map<string_type,function_properties<Json>> function_dictionary;
+
+ const function_dictionary functions_ =
+ {
+ {
+ max_literal<char_type>(),{1,true,true,[](const term<Json>& term)
+ {
+ Json a = term.evaluate_single_node();
+
+ double v = std::numeric_limits<double>::lowest();
+ for (const auto& elem : a.array_range())
+ {
+ double x = elem. template as<double>();
+ if (x > v)
+ {
+ v = x;
+ }
+ }
+ return v;
+ }
+ }
+ },
+ {
+ min_literal<char_type>(),{1,true,true,[](const term<Json>& term)
+ {
+ Json a = term.evaluate_single_node();
+
+ double v = (std::numeric_limits<double>::max)();
+ for (const auto& elem : a.array_range())
+ {
+ double x = elem. template as<double>();
+ if (x < v)
+ {
+ v = x;
+ }
+ }
+ return v;
+ }
+ }
+ }
+ };
+
+ public:
+
+ typename function_dictionary::const_iterator find(const string_type& key) const
+ {
+ return functions_.find(key);
+ }
+ typename function_dictionary::const_iterator end() const
+ {
+ return functions_.end();
+ }
+ };
+
+ class binary_operator_table
+ {
+ typedef std::map<string_type,operator_properties<Json>> binary_operator_map;
+
+ const binary_operator_map operators =
+ {
+ {eqtilde_literal<char_type>(),{2,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.regex_term(b)); }}},
+ {star_literal<char_type>(),{3,false,[](const term<Json>& a, const term<Json>& b) {return a.mult_term(b); }}},
+ {forwardslash_literal<char_type>(),{3,false,[](const term<Json>& a, const term<Json>& b) {return a.div_term(b); }}},
+ {plus_literal<char_type>(),{4,false,[](const term<Json>& a, const term<Json>& b) {return a.plus_term(b); }}},
+ {minus_literal<char_type>(),{4,false,[](const term<Json>& a, const term<Json>& b) {return a.minus_term(b); }}},
+ {lt_literal<char_type>(),{5,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.lt_term(b)); }}},
+ {lte_literal<char_type>(),{5,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.lt_term(b) || a.eq_term(b)); }}},
+ {gt_literal<char_type>(),{5,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.gt_term(b)); }}},
+ {gte_literal<char_type>(),{5,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.gt_term(b) || a.eq_term(b)); }}},
+ {eq_literal<char_type>(),{6,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.eq_term(b)); }}},
+ {ne_literal<char_type>(),{6,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.ne_term(b)); }}},
+ {ampamp_literal<char_type>(),{7,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.ampamp_term(b)); }}},
+ {pipepipe_literal<char_type>(),{8,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.pipepipe_term(b)); }}}
+ };
+
+ public:
+ typename binary_operator_map::const_iterator find(const string_type& key) const
+ {
+ return operators.find(key);
+ }
+ typename binary_operator_map::const_iterator end() const
+ {
+ return operators.end();
+ }
+ };
+
+ function_table functions_;
+ binary_operator_table binary_operators_;
+
+public:
+ jsonpath_filter_parser()
+ : line_(1), column_(1)
+ {
+ }
+ jsonpath_filter_parser(size_t line, size_t column)
+ : line_(line), column_(column)
+ {
+ }
+
+ size_t line() const
+ {
+ return line_;
+ }
+
+ size_t column() const
+ {
+ return column_;
+ }
+
+ jsonpath_filter_expr<Json> parse(const Json& root, const char_type* p, size_t length, const char_type** end_ptr)
+ {
+ return parse(root, p,p+length, end_ptr);
+ }
+
+ void push_state(filter_state state)
+ {
+ state_stack_.push_back(state);
+ }
+
+ filter_state pop_state()
+ {
+ if (state_stack_.empty())
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Invalid state"));
+ }
+ filter_state state = state_stack_.back();
+ state_stack_.pop_back();
+ return state;
+ }
+
+ void add_token(token<Json> token)
+ {
+ if (token.is_operand())
+ {
+ output_stack_.push_back(token);
+ }
+ else if (token.is_lparen())
+ {
+ operator_stack_.push_back(token);
+ }
+ else if (token.is_rparen())
+ {
+ auto it = operator_stack_.rbegin();
+ while (it != operator_stack_.rend() && !it->is_lparen())
+ {
+ output_stack_.push_back(*it);
+ ++it;
+ }
+ if (it == operator_stack_.rend())
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Unbalanced parenthesis"));
+ }
+ operator_stack_.erase(it.base(),operator_stack_.end());
+ operator_stack_.pop_back();
+ }
+ else if (token.is_operator())
+ {
+ if (operator_stack_.empty() || operator_stack_.back().is_lparen())
+ {
+ operator_stack_.push_back(token);
+ }
+ else if (token.precedence_level() < operator_stack_.back().precedence_level()
+ || (token.precedence_level() == operator_stack_.back().precedence_level() && token.is_right_associative()))
+ {
+ operator_stack_.push_back(token);
+ }
+ else
+ {
+ auto it = operator_stack_.rbegin();
+ while (it != operator_stack_.rend() && it->is_operator()
+ && (token.precedence_level() > it->precedence_level()
+ || (token.precedence_level() == it->precedence_level() && token.is_right_associative())))
+ {
+ output_stack_.push_back(*it);
+ ++it;
+ }
+
+ operator_stack_.erase(it.base(),operator_stack_.end());
+ operator_stack_.push_back(token);
+ }
+ }
+ }
+
+ jsonpath_filter_expr<Json> parse(const Json& root, const char_type* p, const char_type* end_expr, const char_type** end_ptr)
+ {
+ output_stack_.clear();
+ operator_stack_.clear();
+ state_stack_.clear();
+
+ string_type buffer;
+
+ int depth = 0;
+ filter_state state = filter_state::start;
+ while (p < end_expr && state != filter_state::done)
+ {
+ switch (state)
+ {
+ case filter_state::cr:
+ ++line_;
+ column_ = 1;
+ switch (*p)
+ {
+ case '\n':
+ state = pop_state();
+ ++p;
+ ++column_;
+ break;
+ default:
+ state = pop_state();
+ break;
+ }
+ break;
+ case filter_state::lf:
+ ++line_;
+ column_ = 1;
+ state = pop_state();
+ break;
+ case filter_state::start:
+ switch (*p)
+ {
+ case '\r':
+ push_state(state);
+ state = filter_state::cr;
+ break;
+ case '\n':
+ push_state(state);
+ state = filter_state::lf;
+ break;
+ case '(':
+ state = filter_state::expect_path_or_value_or_unary_op;
+ ++depth;
+ add_token(token<Json>(token_type::lparen));
+ break;
+ case ')':
+ state = filter_state::expect_path_or_value_or_unary_op;
+ add_token(token<Json>(token_type::rparen));
+ if (--depth == 0)
+ {
+ state = filter_state::done;
+ }
+ break;
+ }
+ ++p;
+ ++column_;
+ break;
+ case filter_state::function_argument:
+ {
+ switch (*p)
+ {
+ case '\r':
+ push_state(state);
+ state = filter_state::cr;
+ break;
+ case '\n':
+ push_state(state);
+ state = filter_state::lf;
+ break;
+ case ' ':case '\t':
+ break;
+ case ')':
+ if (buffer.length() > 0)
+ {
+ if (operator_stack_.back().is_aggregate())
+ {
+ try
+ {
+ // path, parse against root, get value
+ jsonpath_evaluator<Json,const Json&,detail::VoidPathConstructor<Json>> evaluator;
+ evaluator.evaluate(root,buffer.data(),buffer.length());
+ auto result = evaluator.get_values();
+ add_token(token<Json>(token_type::operand,std::make_shared<value_term<Json>>(result)));
+ }
+ catch (const parse_error& e)
+ {
+ throw parse_error(e.code(),line_,column_);
+ }
+ }
+ else
+ {
+ add_token(token<Json>(token_type::operand,std::make_shared<path_term<Json>>(buffer)));
+ }
+ buffer.clear();
+ state = filter_state::expect_oper_or_right_round_bracket;
+ }
+ break;
+ default:
+ buffer.push_back(*p);
+ break;
+ }
+ ++p;
+ ++column_;
+ }
+ break;
+ case filter_state::oper:
+ switch (*p)
+ {
+ case '~':
+ {
+ buffer.push_back(*p);
+ ++p;
+ ++column_;
+ auto it = binary_operators_.find(buffer);
+ if (it == binary_operators_.end())
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator, line_, column_);
+ }
+ buffer.clear();
+ add_token(token<Json>(it->second));
+ state = filter_state::expect_regex;
+ }
+ break;
+ case '=':
+ case '&':
+ case '|':
+ {
+ buffer.push_back(*p);
+ ++p;
+ ++column_;
+ auto it = binary_operators_.find(buffer);
+ if (it == binary_operators_.end())
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator, line_, column_);
+ }
+ buffer.clear();
+ add_token(token<Json>(it->second));
+ state = filter_state::expect_path_or_value_or_unary_op;
+ }
+ break;
+ default:
+ {
+ auto it = binary_operators_.find(buffer);
+ if (it == binary_operators_.end())
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator, line_, column_);
+ }
+ buffer.clear();
+ add_token(token<Json>(it->second));
+ state = filter_state::expect_path_or_value_or_unary_op;
+ }
+ break;
+ }
+ break;
+ case filter_state::unquoted_text:
+ {
+ switch (*p)
+ {
+ case ' ':case '\t':
+ if (buffer.length() > 0)
+ {
+ try
+ {
+ auto val = Json::parse(buffer);
+ add_token(token<Json>(token_type::operand,std::make_shared<value_term<Json>>(val)));
+ }
+ catch (const parse_error& e)
+ {
+ throw parse_error(e.code(),line_,column_);
+ }
+ buffer.clear();
+ }
+ ++p;
+ ++column_;
+ break;
+ case '(':
+ {
+ auto it = functions_.find(buffer);
+ if (it == functions_.end())
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,line_,column_);
+ }
+ add_token(token<Json>(it->second));
+ state = filter_state::function_argument;
+ buffer.clear();
+ ++p;
+ ++column_;
+ break;
+ }
+ case '<':
+ case '>':
+ case '!':
+ case '=':
+ case '&':
+ case '|':
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ {
+ if (buffer.length() > 0)
+ {
+ try
+ {
+ auto val = Json::parse(buffer);
+ add_token(token<Json>(token_type::operand,std::make_shared<value_term<Json>>(val)));
+ }
+ catch (const parse_error& e)
+ {
+ throw parse_error(e.code(),line_,column_);
+ }
+ buffer.clear();
+ }
+ buffer.push_back(*p);
+ state = filter_state::oper;
+ ++p;
+ ++column_;
+ }
+ break;
+ case ')':
+ if (buffer.length() > 0)
+ {
+ try
+ {
+ auto val = Json::parse(buffer);
+ add_token(token<Json>(token_type::operand,std::make_shared<value_term<Json>>(val)));
+ }
+ catch (const parse_error& e)
+ {
+ throw parse_error(e.code(),line_,column_);
+ }
+ buffer.clear();
+ }
+ add_token(token<Json>(token_type::rparen));
+ if (--depth == 0)
+ {
+ state = filter_state::done;
+ }
+ else
+ {
+ state = filter_state::expect_path_or_value_or_unary_op;
+ }
+ ++p;
+ ++column_;
+ break;
+ default:
+ buffer.push_back(*p);
+ ++p;
+ ++column_;
+ break;
+ }
+ }
+ break;
+ case filter_state::single_quoted_text:
+ {
+ switch (*p)
+ {
+ case '\\':
+ buffer.push_back(*p);
+ if (p+1 < end_expr)
+ {
+ ++p;
+ ++column_;
+ buffer.push_back(*p);
+ }
+ break;
+ case '\'':
+ buffer.push_back('\"');
+ //if (buffer.length() > 0)
+ {
+ try
+ {
+ auto val = Json::parse(buffer);
+ add_token(token<Json>(token_type::operand,std::make_shared<value_term<Json>>(val)));
+ }
+ catch (const parse_error& e)
+ {
+ throw parse_error(e.code(),line_,column_);
+ }
+ buffer.clear();
+ }
+ state = filter_state::expect_path_or_value_or_unary_op;
+ break;
+
+ default:
+ buffer.push_back(*p);
+ break;
+ }
+ }
+ ++p;
+ ++column_;
+ break;
+ case filter_state::double_quoted_text:
+ {
+ switch (*p)
+ {
+ case '\\':
+ buffer.push_back(*p);
+ if (p+1 < end_expr)
+ {
+ ++p;
+ ++column_;
+ buffer.push_back(*p);
+ }
+ break;
+ case '\"':
+ buffer.push_back(*p);
+ //if (buffer.length() > 0)
+ {
+ try
+ {
+ auto val = Json::parse(buffer);
+ add_token(token<Json>(token_type::operand,std::make_shared<value_term<Json>>(val)));
+ }
+ catch (const parse_error& e)
+ {
+ throw parse_error(e.code(),line_,column_);
+ }
+ buffer.clear();
+ }
+ state = filter_state::expect_path_or_value_or_unary_op;
+ break;
+
+ default:
+ buffer.push_back(*p);
+ break;
+ }
+ }
+ ++p;
+ ++column_;
+ break;
+ case filter_state::expect_path_or_value_or_unary_op:
+ switch (*p)
+ {
+ case '\r':
+ push_state(state);
+ state = filter_state::cr;
+ ++p;
+ break;
+ case '\n':
+ push_state(state);
+ state = filter_state::lf;
+ ++p;
+ break;
+ case ' ':case '\t':
+ ++p;
+ ++column_;
+ break;
+ case '!':
+ {
+ std::function<Json(const term<Json>&)> f = [](const term<Json>& b) {return Json(b.exclaim());};
+ add_token(token<Json>(1, true, f));
+ ++p;
+ ++column_;
+ break;
+ }
+ case '-':
+ {
+ std::function<Json(const term<Json>&)> f = [](const term<Json>& b) {return b.unary_minus();};
+ add_token(token<Json>(1, true, f));
+ ++p;
+ ++column_;
+ break;
+ }
+ case '@':
+ buffer.push_back(*p);
+ state = filter_state::path;
+ ++p;
+ ++column_;
+ break;
+ case '\'':
+ buffer.push_back('\"');
+ state = filter_state::single_quoted_text;
+ ++p;
+ ++column_;
+ break;
+ case '\"':
+ buffer.push_back(*p);
+ state = filter_state::double_quoted_text;
+ ++p;
+ ++column_;
+ break;
+ case '(':
+ ++depth;
+ add_token(token<Json>(token_type::lparen));
+ ++p;
+ ++column_;
+ break;
+ case ')':
+ add_token(token<Json>(token_type::rparen));
+ if (--depth == 0)
+ {
+ state = filter_state::done;
+ }
+ ++p;
+ ++column_;
+ break;
+ default:
+ // don't increment
+ state = filter_state::unquoted_text;
+ break;
+ };
+ break;
+ case filter_state::expect_oper_or_right_round_bracket:
+ switch (*p)
+ {
+ case '\r':
+ push_state(state);
+ state = filter_state::cr;
+ ++p;
+ break;
+ case '\n':
+ push_state(state);
+ state = filter_state::lf;
+ ++p;
+ break;
+ case ' ':case '\t':
+ ++p;
+ ++column_;
+ break;
+ case ')':
+ add_token(token<Json>(token_type::rparen));
+ if (--depth == 0)
+ {
+ state = filter_state::done;
+ ++p; // fix
+ }
+ break;
+ case '<':
+ case '>':
+ case '!':
+ case '=':
+ case '&':
+ case '|':
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ {
+ buffer.push_back(*p);
+ state = filter_state::oper;
+ ++p;
+ ++column_;
+ }
+ break;
+ default:
+ throw parse_error(jsonpath_parser_errc::invalid_filter,line_,column_);
+ break;
+ };
+ break;
+ case filter_state::expect_right_round_bracket:
+ switch (*p)
+ {
+ case '\r':
+ push_state(state);
+ state = filter_state::cr;
+ break;
+ case '\n':
+ push_state(state);
+ state = filter_state::lf;
+ break;
+ case ' ':case '\t':
+ break;
+ case ')':
+ add_token(token<Json>(token_type::rparen));
+ if (--depth == 0)
+ {
+ state = filter_state::done;
+ }
+ else
+ {
+ state = filter_state::expect_oper_or_right_round_bracket;
+ }
+ break;
+ default:
+ throw parse_error(jsonpath_parser_errc::invalid_filter,line_,column_);
+ break;
+ };
+ ++p;
+ ++column_;
+ break;
+ case filter_state::path:
+ switch (*p)
+ {
+ case '<':
+ case '>':
+ case '!':
+ case '=':
+ case '&':
+ case '|':
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ {
+ if (buffer.length() > 0)
+ {
+ add_token(token<Json>(token_type::operand,std::make_shared<path_term<Json>>(buffer)));
+ buffer.clear();
+ }
+ buffer.push_back(*p);
+ ++p;
+ ++column_;
+ state = filter_state::oper;
+ }
+ break;
+ case ')':
+ if (buffer.length() > 0)
+ {
+ add_token(token<Json>(token_type::operand,std::make_shared<path_term<Json>>(buffer)));
+ add_token(token<Json>(token_type::rparen));
+ buffer.clear();
+ }
+ if (--depth == 0)
+ {
+ state = filter_state::done;
+ }
+ else
+ {
+ state = filter_state::expect_path_or_value_or_unary_op;
+ }
+ ++p;
+ ++column_;
+ break;
+ default:
+ buffer.push_back(*p);
+ ++p;
+ ++column_;
+ break;
+ };
+ break;
+ case filter_state::expect_regex:
+ switch (*p)
+ {
+ case '\r':
+ push_state(state);
+ state = filter_state::cr;
+ break;
+ case '\n':
+ push_state(state);
+ state = filter_state::lf;
+ break;
+ case ' ':case '\t':
+ break;
+ case '/':
+ state = filter_state::regex;
+ break;
+ default:
+ throw parse_error(jsonpath_parser_errc::invalid_filter_expected_slash,line_,column_);
+ break;
+ };
+ ++p;
+ ++column_;
+ break;
+ case filter_state::regex:
+ {
+ switch (*p)
+ {
+ case '/':
+ //if (buffer.length() > 0)
+ {
+ std::regex::flag_type flags = std::regex_constants::ECMAScript;
+ if (p+1 < end_expr && *(p+1) == 'i')
+ {
+ ++p;
+ ++column_;
+ flags |= std::regex_constants::icase;
+ }
+ add_token(token<Json>(token_type::operand,std::make_shared<regex_term<Json>>(buffer,flags)));
+ buffer.clear();
+ }
+ state = filter_state::expect_path_or_value_or_unary_op;
+ break;
+
+ default:
+ buffer.push_back(*p);
+ break;
+ }
+ }
+ ++p;
+ ++column_;
+ break;
+ default:
+ ++p;
+ ++column_;
+ break;
+ }
+ }
+ if (depth != 0)
+ {
+ throw parse_error(jsonpath_parser_errc::invalid_filter_unbalanced_paren,line_,column_);
+ }
+ *end_ptr = p;
+
+ return jsonpath_filter_expr<Json>(output_stack_,line_,column_);
+ }
+};
+
+template <class Json>
+const operator_properties<Json> jsonpath_filter_parser<Json>::op_properties_[] =
+{
+ {2,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.regex_term(b));}},
+ {3,false,[](const term<Json>& a, const term<Json>& b) {return a.mult_term(b);}},
+ {3,false,[](const term<Json>& a, const term<Json>& b) {return a.div_term(b);}},
+ {4,false,[](const term<Json>& a, const term<Json>& b) {return a.plus_term(b);}},
+ {4,false,[](const term<Json>& a, const term<Json>& b) {return a.minus_term(b);}},
+ {5,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.lt_term(b));}},
+ {5,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.lt_term(b) || a.eq_term(b));}},
+ {5,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.gt_term(b));}},
+ {5,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.gt_term(b) || a.eq_term(b));}},
+ {6,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.eq_term(b)); }},
+ {6,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.ne_term(b)); }},
+ {7,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.ampamp_term(b));}},
+ {8,false,[](const term<Json>& a, const term<Json>& b) {return Json(a.pipepipe_term(b));}}
+};
+
+}}}
+
+#endif \ No newline at end of file
diff --git a/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpointer/jsonpointer.hpp b/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpointer/jsonpointer.hpp
new file mode 100644
index 00000000..56b4efa2
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpointer/jsonpointer.hpp
@@ -0,0 +1,810 @@
+// Copyright 2017 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSONPOINTER_JSONPOINTER_HPP
+#define JSONCONS_JSONPOINTER_JSONPOINTER_HPP
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <cstdlib>
+#include <memory>
+#include <jsoncons/json.hpp>
+#include <jsoncons_ext/jsonpointer/jsonpointer_error_category.hpp>
+
+namespace jsoncons { namespace jsonpointer {
+
+class jsonpointer_error : public std::exception, public virtual json_exception
+{
+public:
+ jsonpointer_error(const std::error_code& ec)
+ : error_code_(ec)
+ {
+ }
+ jsonpointer_error(const jsonpointer_error& other) = default;
+
+ jsonpointer_error(jsonpointer_error&& other) = default;
+
+ const char* what() const JSONCONS_NOEXCEPT override
+ {
+ try
+ {
+ const_cast<std::string&>(buffer_) = error_code_.message();
+ return buffer_.c_str();
+ }
+ catch (...)
+ {
+ return "";
+ }
+ }
+
+ const std::error_code code() const
+ {
+ return error_code_;
+ }
+
+ jsonpointer_error& operator=(const jsonpointer_error& e) = default;
+ jsonpointer_error& operator=(jsonpointer_error&& e) = default;
+private:
+ std::string buffer_;
+ std::error_code error_code_;
+};
+
+namespace detail {
+
+enum class pointer_state
+{
+ start,
+ array_reference_token,
+ zero_array_reference_token,
+ nonzero_array_reference_token,
+ after_last_array_reference_token,
+ object_reference_token,
+ escaped
+};
+template <class Json,class JsonReference, class Enable = void>
+class json_wrapper
+{
+};
+
+template <class Json,class JsonReference>
+class json_wrapper<Json,JsonReference,typename std::enable_if<std::is_reference<decltype(std::declval<Json>().at(typename Json::string_view_type()))>::value>::type>
+{
+public:
+ using reference = JsonReference;
+ using pointer = typename std::conditional<std::is_const<typename std::remove_reference<JsonReference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
+
+ json_wrapper(reference ref) JSONCONS_NOEXCEPT
+ : ptr_(std::addressof(ref))
+ {
+ }
+
+ json_wrapper(const json_wrapper&) JSONCONS_NOEXCEPT = default;
+
+ json_wrapper& operator=(const json_wrapper&) JSONCONS_NOEXCEPT = default;
+
+ reference get() const JSONCONS_NOEXCEPT
+ {
+ return *ptr_;
+ }
+private:
+ pointer ptr_;
+};
+
+template <class Json,class JsonReference>
+class json_wrapper<Json,JsonReference,typename std::enable_if<!std::is_reference<decltype(std::declval<Json>().at(typename Json::string_view_type()))>::value>::type>
+{
+public:
+ using value_type = typename Json::value_type;
+ using reference = JsonReference;
+ using pointer = typename std::conditional<std::is_const<typename std::remove_reference<JsonReference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
+
+ json_wrapper(reference ref) JSONCONS_NOEXCEPT
+ : val_(ref)
+ {
+ }
+
+ json_wrapper(const json_wrapper& w) JSONCONS_NOEXCEPT
+ : val_(w.val_)
+ {
+ }
+
+ json_wrapper& operator=(const json_wrapper&) JSONCONS_NOEXCEPT = default;
+
+ value_type get() const JSONCONS_NOEXCEPT
+ {
+ return val_;
+ }
+private:
+ value_type val_;
+};
+
+template<class Json,class JsonReference>
+struct path_resolver
+{
+ typedef typename Json::string_type string_type;
+ typedef typename Json::string_view_type string_view_type;
+ using reference = JsonReference;
+ using pointer = typename std::conditional<std::is_const<typename std::remove_reference<JsonReference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
+
+ jsonpointer_errc operator()(std::vector<json_wrapper<Json,JsonReference>>& current,
+ size_t index) const
+ {
+ if (index >= current.back().get().size())
+ {
+ return jsonpointer_errc::index_exceeds_array_size;
+ }
+ current.push_back(current.back().get().at(index));
+ return jsonpointer_errc();
+ }
+
+ jsonpointer_errc operator()(std::vector<json_wrapper<Json,JsonReference>>& current,
+ const string_view_type& name) const
+ {
+ if (!current.back().get().has_key(name))
+ {
+ return jsonpointer_errc::name_not_found;
+ }
+ current.push_back(current.back().get().at(name));
+ return jsonpointer_errc();
+ }
+};
+
+template<class Json, class JsonReference>
+struct path_setter
+{
+ typedef typename Json::string_type string_type;
+ typedef typename Json::string_view_type string_view_type;
+ using reference = JsonReference;
+ using pointer = typename std::conditional<std::is_const<typename std::remove_reference<JsonReference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
+
+ jsonpointer_errc operator()(std::vector<json_wrapper<Json,JsonReference>>& current,
+ size_t index) const
+ {
+ if (index >= current.back().get().size())
+ {
+ return jsonpointer_errc::index_exceeds_array_size;
+ }
+ current.push_back(current.back().get().at(index));
+ return jsonpointer_errc();
+ }
+
+ jsonpointer_errc operator()(std::vector<json_wrapper<Json,JsonReference>>& current,
+ const string_view_type& name) const
+ {
+ jsonpointer_errc ec = jsonpointer_errc();
+ if (!current.back().get().has_key(name))
+ {
+ return jsonpointer_errc::name_not_found;
+ }
+ current.push_back(current.back().get().at(name));
+ return ec;
+ }
+};
+
+template<class Json,class JsonReference>
+class jsonpointer_evaluator : private parsing_context
+{
+ typedef typename Json::string_type string_type;
+ typedef typename string_type::value_type char_type;
+ typedef typename Json::string_view_type string_view_type;
+ using reference = JsonReference;
+ using pointer = typename std::conditional<std::is_const<typename std::remove_reference<JsonReference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
+
+ jsonpointer::detail::pointer_state state_;
+ size_t line_;
+ size_t column_;
+ const char_type* begin_input_;
+ const char_type* end_input_;
+ const char_type* p_;
+ string_type buffer_;
+ size_t index_;
+ std::vector<json_wrapper<Json,JsonReference>> current_;
+public:
+ Json get_result()
+ {
+ return std::move(current_.back().get());
+ }
+
+ size_t line_number() const
+ {
+ return line_;
+ }
+
+ size_t column_number() const
+ {
+ return column_;
+ }
+
+ jsonpointer_errc get(reference root, const string_view_type& path)
+ {
+ path_resolver<Json,reference> op;
+ jsonpointer_errc ec = evaluate(root,op,path);
+ if (ec != jsonpointer_errc())
+ {
+ return ec;
+ }
+
+ switch (state_)
+ {
+ case pointer_state::start:
+ break;
+ case pointer_state::zero_array_reference_token:
+ case pointer_state::nonzero_array_reference_token:
+ ec = op(current_,index_);
+ break;
+ case pointer_state::object_reference_token:
+ ec = op(current_,buffer_);
+ break;
+ default:
+ return jsonpointer_errc::end_of_input;
+ }
+ return ec;
+ }
+
+ string_type normalized_path(reference root, const string_view_type& path)
+ {
+ jsonpointer_errc ec = evaluate(root,path_setter<Json,reference>(),path);
+ if (ec != jsonpointer_errc())
+ {
+ return string_type(path);
+ }
+ if (state_ == jsonpointer::detail::pointer_state::after_last_array_reference_token)
+ {
+ string_type p = string_type(path.substr(0,path.length()-1));
+ std::string s = std::to_string(current_.back().get().size());
+ for (auto c : s)
+ {
+ p.push_back(c);
+ }
+ return p;
+ }
+ else
+ {
+ return string_type(path);
+ }
+ }
+
+ jsonpointer_errc insert_or_assign(reference root, const string_view_type& path, const Json& value)
+ {
+ jsonpointer_errc ec = evaluate(root,path_setter<Json,reference>(),path);
+ if (ec != jsonpointer_errc())
+ {
+ return ec;
+ }
+
+ switch (state_)
+ {
+ case jsonpointer::detail::pointer_state::start:
+ break;
+ case jsonpointer::detail::pointer_state::zero_array_reference_token:
+ case jsonpointer::detail::pointer_state::nonzero_array_reference_token:
+ if (index_ > current_.back().get().size())
+ {
+ return jsonpointer_errc::index_exceeds_array_size;
+ }
+ if (index_ == current_.back().get().size())
+ {
+ current_.back().get().push_back(value);
+ }
+ else
+ {
+ current_.back().get().insert(current_.back().get().array_range().begin()+index_,value);
+ }
+ break;
+ case jsonpointer::detail::pointer_state::after_last_array_reference_token:
+ current_.back().get().push_back(value);
+ break;
+ case jsonpointer::detail::pointer_state::object_reference_token:
+ current_.back().get().insert_or_assign(buffer_,value);
+ break;
+ default:
+ return jsonpointer_errc::end_of_input;
+ }
+ return ec;
+ }
+
+ jsonpointer_errc insert(reference root, const string_view_type& path, const Json& value)
+ {
+ jsonpointer_errc ec = evaluate(root,path_setter<Json,reference>(),path);
+ if (ec != jsonpointer_errc())
+ {
+ return ec;
+ }
+
+ switch (state_)
+ {
+ case jsonpointer::detail::pointer_state::start:
+ break;
+ case jsonpointer::detail::pointer_state::zero_array_reference_token:
+ case jsonpointer::detail::pointer_state::nonzero_array_reference_token:
+ if (index_ > current_.back().get().size())
+ {
+ return jsonpointer_errc::index_exceeds_array_size;
+ }
+ if (index_ == current_.back().get().size())
+ {
+ current_.back().get().push_back(value);
+ }
+ else
+ {
+ current_.back().get().insert(current_.back().get().array_range().begin()+index_,value);
+ }
+ break;
+ case jsonpointer::detail::pointer_state::after_last_array_reference_token:
+ current_.back().get().push_back(value);
+ break;
+ case jsonpointer::detail::pointer_state::object_reference_token:
+ if (current_.back().get().has_key(buffer_))
+ {
+ ec = jsonpointer_errc::key_already_exists;
+ }
+ else
+ {
+ current_.back().get().insert_or_assign(buffer_,value);
+ }
+ break;
+ default:
+ return jsonpointer_errc::end_of_input;
+ }
+ return ec;
+ }
+
+ jsonpointer_errc remove(reference root, const string_view_type& path)
+ {
+ jsonpointer_errc ec = evaluate(root,path_resolver<Json,reference>(),path);
+ if (ec != jsonpointer_errc())
+ {
+ return ec;
+ }
+
+ switch (state_)
+ {
+ case jsonpointer::detail::pointer_state::start:
+ break;
+ case jsonpointer::detail::pointer_state::zero_array_reference_token:
+ case jsonpointer::detail::pointer_state::nonzero_array_reference_token:
+ if (index_ >= current_.back().get().size())
+ {
+ return jsonpointer_errc::index_exceeds_array_size;
+ }
+ current_.back().get().erase(current_.back().get().array_range().begin()+index_);
+ break;
+ case jsonpointer::detail::pointer_state::after_last_array_reference_token:
+ return jsonpointer_errc::index_exceeds_array_size;
+ case jsonpointer::detail::pointer_state::object_reference_token:
+ if (!current_.back().get().has_key(buffer_))
+ {
+ return jsonpointer_errc::name_not_found;
+ }
+ current_.back().get().erase(buffer_);
+ break;
+ default:
+ return jsonpointer_errc::end_of_input;
+ }
+ return ec;
+ }
+
+ jsonpointer_errc replace(reference root, const string_view_type& path, const Json& value)
+ {
+ jsonpointer_errc ec = evaluate(root,path_resolver<Json,reference>(),path);
+ if (ec != jsonpointer_errc())
+ {
+ return ec;
+ }
+
+ switch (state_)
+ {
+ case jsonpointer::detail::pointer_state::start:
+ break;
+ case jsonpointer::detail::pointer_state::zero_array_reference_token:
+ case jsonpointer::detail::pointer_state::nonzero_array_reference_token:
+ if (index_ >= current_.back().get().size())
+ {
+ return jsonpointer_errc::index_exceeds_array_size;
+ }
+ (current_.back().get())[index_] = value;
+ break;
+ case jsonpointer::detail::pointer_state::after_last_array_reference_token:
+ return jsonpointer_errc::index_exceeds_array_size;
+ case jsonpointer::detail::pointer_state::object_reference_token:
+ if (!current_.back().get().has_key(buffer_))
+ {
+ return jsonpointer_errc::name_not_found;
+ }
+ current_.back().get().insert_or_assign(buffer_,value);
+ break;
+ default:
+ return jsonpointer_errc::end_of_input;
+ }
+ return jsonpointer_errc();
+ }
+
+ template <class Op>
+ jsonpointer_errc evaluate(reference root, Op op, const string_view_type& path)
+ {
+ jsonpointer_errc ec = jsonpointer_errc();
+
+ line_ = 1;
+ column_ = 1;
+ state_ = jsonpointer::detail::pointer_state::start;
+ begin_input_ = path.data();
+ end_input_ = path.data() + path.length();
+ p_ = begin_input_;
+
+ index_ = 0;
+
+ current_.push_back(root);
+
+ while (p_ < end_input_)
+ {
+ switch (state_)
+ {
+ case jsonpointer::detail::pointer_state::start:
+ switch (*p_)
+ {
+ case '/':
+ if (current_.back().get().is_array())
+ {
+ state_ = jsonpointer::detail::pointer_state::array_reference_token;
+ index_ = 0;
+ }
+ else if (current_.back().get().is_object())
+ {
+ state_ = jsonpointer::detail::pointer_state::object_reference_token;
+ buffer_.clear();
+ }
+ else
+ {
+ return jsonpointer_errc::expected_object_or_array;
+ }
+ break;
+ default:
+ return jsonpointer_errc::expected_slash;
+ };
+ ++p_;
+ ++column_;
+ break;
+ case jsonpointer::detail::pointer_state::array_reference_token:
+ switch (*p_)
+ {
+ case '0':
+ index_ = 0;
+ state_ = jsonpointer::detail::pointer_state::zero_array_reference_token;
+ break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ index_ = (*p_ - '0');
+ state_ = jsonpointer::detail::pointer_state::nonzero_array_reference_token;
+ break;
+ case '-':
+ state_ = jsonpointer::detail::pointer_state::after_last_array_reference_token;
+ break;
+ default:
+ return jsonpointer_errc::expected_digit_or_dash;
+ };
+ ++p_;
+ ++column_;
+ break;
+ case jsonpointer::detail::pointer_state::zero_array_reference_token:
+ switch (*p_)
+ {
+ case '/':
+ ec = op(current_,index_);
+ if (ec != jsonpointer_errc())
+ {
+ return ec;
+ }
+ if (current_.back().get().is_array())
+ {
+ state_ = jsonpointer::detail::pointer_state::array_reference_token;
+ index_ = 0;
+ }
+ else if (current_.back().get().is_object())
+ {
+ state_ = jsonpointer::detail::pointer_state::object_reference_token;
+ buffer_.clear();
+ }
+ else
+ {
+ return jsonpointer_errc::expected_object_or_array;
+ }
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return jsonpointer_errc::unexpected_leading_zero;
+ case '-':
+ return jsonpointer_errc::index_exceeds_array_size;
+ default:
+ return jsonpointer_errc::expected_digit_or_dash;
+ };
+ ++p_;
+ ++column_;
+ break;
+ case jsonpointer::detail::pointer_state::after_last_array_reference_token:
+ switch (*p_)
+ {
+ case '/':
+ return jsonpointer_errc::index_exceeds_array_size;
+ default:
+ return jsonpointer_errc::expected_slash;
+ };
+ ++p_;
+ ++column_;
+ break;
+ case jsonpointer::detail::pointer_state::nonzero_array_reference_token:
+ switch (*p_)
+ {
+ case '/':
+ ec = op(current_,index_);
+ if (ec != jsonpointer_errc())
+ {
+ return ec;
+ }
+ if (current_.back().get().is_array())
+ {
+ state_ = jsonpointer::detail::pointer_state::array_reference_token;
+ index_ = 0;
+ }
+ else if (current_.back().get().is_object())
+ {
+ state_ = jsonpointer::detail::pointer_state::object_reference_token;
+ buffer_.clear();
+ }
+ else
+ {
+ return jsonpointer_errc::expected_object_or_array;
+ }
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ index_ = index_ * 10 + (*p_ - '0');
+ break;
+ case '-':
+ return jsonpointer_errc::index_exceeds_array_size;
+ default:
+ return jsonpointer_errc::expected_digit_or_dash;
+ };
+ ++p_;
+ ++column_;
+ break;
+ case jsonpointer::detail::pointer_state::object_reference_token:
+ switch (*p_)
+ {
+ case '/':
+ ec = op(current_,buffer_);
+ if (ec != jsonpointer_errc())
+ {
+ return ec;
+ }
+ if (current_.back().get().is_array())
+ {
+ state_ = jsonpointer::detail::pointer_state::array_reference_token;
+ index_ = 0;
+ }
+ else if (current_.back().get().is_object())
+ {
+ state_ = jsonpointer::detail::pointer_state::object_reference_token;
+ buffer_.clear();
+ }
+ else
+ {
+ return jsonpointer_errc::expected_object_or_array;
+ }
+ break;
+ case '~':
+ state_ = jsonpointer::detail::pointer_state::escaped;
+ break;
+ default:
+ buffer_.push_back(*p_);
+ break;
+ };
+ ++p_;
+ ++column_;
+ break;
+ case jsonpointer::detail::pointer_state::escaped:
+ switch (*p_)
+ {
+ case '0':
+ buffer_.push_back('~');
+ state_ = jsonpointer::detail::pointer_state::object_reference_token;
+ break;
+ case '1':
+ buffer_.push_back('/');
+ state_ = jsonpointer::detail::pointer_state::object_reference_token;
+ break;
+ default:
+ return jsonpointer_errc::expected_0_or_1;
+ };
+ ++p_;
+ ++column_;
+ break;
+ }
+ }
+ return ec;
+ }
+
+private:
+
+ // parsing_context
+
+ size_t do_line_number() const override
+ {
+ return line_;
+ }
+
+ size_t do_column_number() const override
+ {
+ return column_;
+ }
+};
+
+}
+
+template<class Json>
+typename Json::string_type normalized_path(const Json& root, const typename Json::string_view_type& path)
+{
+ detail::jsonpointer_evaluator<Json,const Json&> evaluator;
+ return evaluator.normalized_path(root,path);
+}
+
+template<class Json>
+Json get(const Json& root, const typename Json::string_view_type& path)
+{
+ detail::jsonpointer_evaluator<Json,const Json&> evaluator;
+ jsonpointer_errc ec = evaluator.get(root,path);
+ if (ec != jsonpointer_errc())
+ {
+ JSONCONS_THROW(jsonpointer_error(ec));
+ }
+ return evaluator.get_result();
+}
+
+template<class Json>
+Json get(const Json& root, const typename Json::string_view_type& path, std::error_code& ec)
+{
+ detail::jsonpointer_evaluator<Json,const Json&> evaluator;
+ ec = evaluator.get(root,path);
+ return evaluator.get_result();
+}
+
+template<class Json>
+bool contains(const Json& root, const typename Json::string_view_type& path)
+{
+ detail::jsonpointer_evaluator<Json,const Json&> evaluator;
+ jsonpointer_errc ec = evaluator.get(root,path);
+ return ec == jsonpointer_errc() ? true : false;
+}
+
+template<class Json>
+void insert_or_assign(Json& root, const typename Json::string_view_type& path, const Json& value)
+{
+ detail::jsonpointer_evaluator<Json,Json&> evaluator;
+
+ jsonpointer_errc ec = evaluator.insert_or_assign(root,path,value);
+ if (ec != jsonpointer_errc())
+ {
+ JSONCONS_THROW(jsonpointer_error(ec));
+ }
+}
+
+template<class Json>
+void insert_or_assign(Json& root, const typename Json::string_view_type& path, const Json& value, std::error_code& ec)
+{
+ detail::jsonpointer_evaluator<Json,Json&> evaluator;
+
+ ec = evaluator.insert_or_assign(root,path,value);
+}
+
+template<class Json>
+void insert(Json& root, const typename Json::string_view_type& path, const Json& value)
+{
+ detail::jsonpointer_evaluator<Json,Json&> evaluator;
+
+ jsonpointer_errc ec = evaluator.insert(root,path,value);
+ if (ec != jsonpointer_errc())
+ {
+ JSONCONS_THROW(jsonpointer_error(ec));
+ }
+}
+
+template<class Json>
+void insert(Json& root, const typename Json::string_view_type& path, const Json& value, std::error_code& ec)
+{
+ detail::jsonpointer_evaluator<Json,Json&> evaluator;
+
+ ec = evaluator.insert(root,path,value);
+}
+
+template<class Json>
+void remove(Json& root, const typename Json::string_view_type& path)
+{
+ detail::jsonpointer_evaluator<Json,Json&> evaluator;
+
+ jsonpointer_errc ec = evaluator.remove(root,path);
+ if (ec != jsonpointer_errc())
+ {
+ JSONCONS_THROW(jsonpointer_error(ec));
+ }
+}
+
+template<class Json>
+void remove(Json& root, const typename Json::string_view_type& path, std::error_code& ec)
+{
+ detail::jsonpointer_evaluator<Json,Json&> evaluator;
+
+ ec = evaluator.remove(root,path);
+}
+
+template<class Json>
+void replace(Json& root, const typename Json::string_view_type& path, const Json& value)
+{
+ detail::jsonpointer_evaluator<Json,Json&> evaluator;
+
+ jsonpointer_errc ec = evaluator.replace(root,path,value);
+ if (ec != jsonpointer_errc())
+ {
+ JSONCONS_THROW(jsonpointer_error(ec));
+ }
+}
+
+template<class Json>
+void replace(Json& root, const typename Json::string_view_type& path, const Json& value, std::error_code& ec)
+{
+ detail::jsonpointer_evaluator<Json,Json&> evaluator;
+
+ ec = evaluator.replace(root,path,value);
+}
+
+template <class String>
+void escape(const String& s, std::basic_ostringstream<typename String::value_type>& os)
+{
+ for (auto c : s)
+ {
+ if (c == '~')
+ {
+ os.put('~');
+ os.put('0');
+ }
+ else if (c == '/')
+ {
+ os.put('~');
+ os.put('1');
+ }
+ else
+ {
+ os.put(c);
+ }
+ }
+}
+
+}}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpointer/jsonpointer_error_category.hpp b/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpointer/jsonpointer_error_category.hpp
new file mode 100644
index 00000000..01ddc9dc
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons_ext/jsonpointer/jsonpointer_error_category.hpp
@@ -0,0 +1,87 @@
+/// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_JSONPOINTER_JSONPOINTER_ERROR_CATEGORY_HPP
+#define JSONCONS_JSONPOINTER_JSONPOINTER_ERROR_CATEGORY_HPP
+
+#include <jsoncons/json_exception.hpp>
+#include <system_error>
+
+namespace jsoncons { namespace jsonpointer {
+
+enum class jsonpointer_errc
+{
+ ok = 0,
+ expected_slash = 1,
+ expected_digit_or_dash,
+ unexpected_leading_zero,
+ index_exceeds_array_size,
+ expected_0_or_1,
+ name_not_found,
+ key_already_exists,
+ expected_object_or_array,
+ end_of_input
+};
+
+class jsonpointer_error_category_impl
+ : public std::error_category
+{
+public:
+ virtual const char* name() const JSONCONS_NOEXCEPT
+ {
+ return "jsoncons.jsonpointer";
+ }
+ virtual std::string message(int ev) const
+ {
+ switch (static_cast<jsonpointer_errc>(ev))
+ {
+ case jsonpointer_errc::expected_slash:
+ return "Expected /";
+ case jsonpointer_errc::expected_digit_or_dash:
+ return "Expected digit or '-'";
+ case jsonpointer_errc::unexpected_leading_zero:
+ return "Unexpected leading zero";
+ case jsonpointer_errc::index_exceeds_array_size:
+ return "Index exceeds array size";
+ case jsonpointer_errc::expected_0_or_1:
+ return "Expected '0' or '1' after escape character '~'";
+ case jsonpointer_errc::name_not_found:
+ return "Name not found";
+ case jsonpointer_errc::key_already_exists:
+ return "Key already exists";
+ case jsonpointer_errc::expected_object_or_array:
+ return "Expected object or array";
+ case jsonpointer_errc::end_of_input:
+ return "Unexpected end of input";
+ default:
+ return "Unknown jsonpointer error";
+ }
+ }
+};
+
+inline
+const std::error_category& jsonpointer_error_category()
+{
+ static jsonpointer_error_category_impl instance;
+ return instance;
+}
+
+inline
+std::error_code make_error_code(jsonpointer_errc result)
+{
+ return std::error_code(static_cast<int>(result),jsonpointer_error_category());
+}
+
+}}
+
+namespace std {
+ template<>
+ struct is_error_code_enum<jsoncons::jsonpointer::jsonpointer_errc> : public true_type
+ {
+ };
+}
+
+#endif
diff --git a/vendor/jsoncons-0.104.0/jsoncons_ext/msgpack/msgpack.hpp b/vendor/jsoncons-0.104.0/jsoncons_ext/msgpack/msgpack.hpp
new file mode 100644
index 00000000..fd35dfe6
--- /dev/null
+++ b/vendor/jsoncons-0.104.0/jsoncons_ext/msgpack/msgpack.hpp
@@ -0,0 +1,795 @@
+// Copyright 2013 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_MSGPACK_MSGPACK_HPP
+#define JSONCONS_MSGPACK_MSGPACK_HPP
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <istream>
+#include <cstdlib>
+#include <memory>
+#include <limits>
+#include <cassert>
+#include <jsoncons/json.hpp>
+#include <jsoncons_ext/binary/binary_utilities.hpp>
+
+namespace jsoncons { namespace msgpack {
+
+class msgpack_decode_error : public std::invalid_argument, public virtual json_exception
+{
+public:
+ explicit msgpack_decode_error(size_t pos) JSONCONS_NOEXCEPT
+ : std::invalid_argument("")
+ {
+ buffer_.append("Error decoding a message pack at position ");
+ buffer_.append(std::to_string(pos));
+ }
+ ~msgpack_decode_error() JSONCONS_NOEXCEPT
+ {
+ }
+ const char* what() const JSONCONS_NOEXCEPT override
+ {
+ return buffer_.c_str();
+ }
+private:
+ std::string buffer_;
+};
+
+namespace msgpack_format
+{
+ const uint8_t nil_cd = 0xc0;
+ const uint8_t false_cd = 0xc2;
+ const uint8_t true_cd = 0xc3;
+ const uint8_t float32_cd = 0xca;
+ const uint8_t float64_cd = 0xcb;
+ const uint8_t uint8_cd = 0xcc;
+ const uint8_t uint16_cd = 0xcd;
+ const uint8_t uint32_cd = 0xce;
+ const uint8_t uint64_cd = 0xcf;
+ const uint8_t int8_cd = 0xd0;
+ const uint8_t int16_cd = 0xd1;
+ const uint8_t int32_cd = 0xd2;
+ const uint8_t int64_cd = 0xd3;
+ const uint8_t str8_cd = 0xd9;
+ const uint8_t str16_cd = 0xda;
+ const uint8_t str32_cd = 0xdb;
+ const uint8_t array16_cd = 0xdc;
+ const uint8_t array32_cd = 0xdd;
+ const uint8_t map16_cd = 0xde;
+ const uint8_t map32_cd = 0xdf;
+}
+
+struct Encode_msgpack_
+{
+ template <typename T>
+ void operator()(T val, std::vector<uint8_t>& v)
+ {
+ binary::to_big_endian(val,v);
+ }
+};
+
+struct Calculate_size_
+{
+ template <typename T>
+ void operator()(T, size_t& size)
+ {
+ size += sizeof(T);
+ }
+};
+
+template<class Json>
+class msgpack_Encoder_
+{
+public:
+ typedef typename Json::string_view_type string_view_type;
+
+ static size_t calculate_size(const Json& j)
+ {
+ size_t n = 0;
+ msgpack_Encoder_<Json>::encode(j,Calculate_size_(),n);
+ return n;
+ }
+
+ template <class Action, class Result>
+ static void encode(const Json& jval, Action action, Result& v)
+ {
+ switch (jval.type_id())
+ {
+ case json_type_tag::null_t:
+ {
+ // nil
+ action(static_cast<uint8_t>(msgpack_format::nil_cd), v);
+ break;
+ }
+
+ case json_type_tag::bool_t:
+ {
+ // true and false
+ action(static_cast<uint8_t>(jval.as_bool() ? msgpack_format::true_cd : msgpack_format::false_cd),v);
+ break;
+ }
+
+ case json_type_tag::integer_t:
+ {
+ int64_t val = jval.as_integer();
+ if (val >= 0)
+ {
+ if (val <= (std::numeric_limits<int8_t>::max)())
+ {
+ // positive fixnum stores 7-bit positive integer
+ action(static_cast<int8_t>(val),v);
+ }
+ else if (val <= (std::numeric_limits<uint8_t>::max)())
+ {
+ // uint 8 stores a 8-bit unsigned integer
+ action(static_cast<uint8_t>(msgpack_format::uint8_cd), v);
+ action(static_cast<uint8_t>(val),v);
+ }
+ else if (val <= (std::numeric_limits<uint16_t>::max)())
+ {
+ // uint 16 stores a 16-bit big-endian unsigned integer
+ action(static_cast<uint8_t>(msgpack_format::uint16_cd), v);
+ action(static_cast<uint16_t>(val),v);
+ }
+ else if (val <= (std::numeric_limits<uint32_t>::max)())
+ {
+ // uint 32 stores a 32-bit big-endian unsigned integer
+ action(static_cast<uint8_t>(msgpack_format::uint32_cd), v);
+ action(static_cast<uint32_t>(val),v);
+ }
+ else if (val <= (std::numeric_limits<int64_t>::max)())
+ {
+ // int 64 stores a 64-bit big-endian signed integer
+ action(static_cast<uint8_t>(msgpack_format::int64_cd), v);
+ action(static_cast<int64_t>(val),v);
+ }
+ }
+ else
+ {
+ if (val >= -32)
+ {
+ // negative fixnum stores 5-bit negative integer
+ action(static_cast<int8_t>(val), v);
+ }
+ else if (val >= (std::numeric_limits<int8_t>::min)())
+ {
+ // int 8 stores a 8-bit signed integer
+ action(static_cast<uint8_t>(msgpack_format::int8_cd), v);
+ action(static_cast<int8_t>(val),v);
+ }
+ else if (val >= (std::numeric_limits<int16_t>::min)())
+ {
+ // int 16 stores a 16-bit big-endian signed integer
+ action(static_cast<uint8_t>(msgpack_format::int16_cd), v);
+ action(static_cast<int16_t>(val),v);
+ }
+ else if (val >= (std::numeric_limits<int32_t>::min)())
+ {
+ // int 32 stores a 32-bit big-endian signed integer
+ action(static_cast<uint8_t>(msgpack_format::int32_cd), v);
+ action(static_cast<int32_t>(val),v);
+ }
+ else if (val >= (std::numeric_limits<int64_t>::min)())
+ {
+ // int 64 stores a 64-bit big-endian signed integer
+ action(static_cast<uint8_t>(msgpack_format::int64_cd), v);
+ action(static_cast<int64_t>(val),v);
+ }
+ }
+ break;
+ }
+
+ case json_type_tag::uinteger_t:
+ {
+ uint64_t val = jval.as_uinteger();
+ if (val <= (std::numeric_limits<int8_t>::max)())
+ {
+ // positive fixnum stores 7-bit positive integer
+ action(static_cast<uint8_t>(val), v);
+ }
+ else if (val <= (std::numeric_limits<uint8_t>::max)())
+ {
+ // uint 8 stores a 8-bit unsigned integer
+ action(static_cast<uint8_t>(msgpack_format::uint8_cd), v);
+ action(static_cast<uint8_t>(val), v);
+ }
+ else if (val <= (std::numeric_limits<uint16_t>::max)())
+ {
+ // uint 16 stores a 16-bit big-endian unsigned integer
+ action(static_cast<uint8_t>(msgpack_format::uint16_cd), v);
+ action(static_cast<uint16_t>(val),v);
+ }
+ else if (val <= (std::numeric_limits<uint32_t>::max)())
+ {
+ // uint 32 stores a 32-bit big-endian unsigned integer
+ action(static_cast<uint8_t>(msgpack_format::uint32_cd), v);
+ action(static_cast<uint32_t>(val),v);
+ }
+ else if (val <= (std::numeric_limits<uint64_t>::max)())
+ {
+ // uint 64 stores a 64-bit big-endian unsigned integer
+ action(static_cast<uint8_t>(msgpack_format::uint64_cd), v);
+ action(static_cast<uint64_t>(val),v);
+ }
+ break;
+ }
+
+ case json_type_tag::double_t:
+ {
+ // float 64
+ action(static_cast<uint8_t>(msgpack_format::float64_cd), v);
+ action(jval.as_double(),v);
+ break;
+ }
+
+ case json_type_tag::small_string_t:
+ case json_type_tag::string_t:
+ {
+ encode_string(jval.as_string_view(), action, v);
+ break;
+ }
+
+ case json_type_tag::array_t:
+ {
+ const auto length = jval.array_value().size();
+ if (length <= 15)
+ {
+ // fixarray
+ action(static_cast<uint8_t>(0x90 | length), v);
+ }
+ else if (length <= (std::numeric_limits<uint16_t>::max)())
+ {
+ // array 16
+ action(static_cast<uint8_t>(msgpack_format::array16_cd), v);
+ action(static_cast<uint16_t>(length),v);
+ }
+ else if (length <= (std::numeric_limits<uint32_t>::max)())
+ {
+ // array 32
+ action(static_cast<uint8_t>(msgpack_format::array32_cd), v);
+ action(static_cast<uint32_t>(length),v);
+ }
+
+ // append each element
+ for (const auto& el : jval.array_range())
+ {
+ encode(el, action, v);
+ }
+ break;
+ }
+
+ case json_type_tag::object_t:
+ {
+ const auto length = jval.object_value().size();
+ if (length <= 15)
+ {
+ // fixmap
+ action(static_cast<uint8_t>(0x80 | (length & 0xf)), v);
+ }
+ else if (length <= 65535)
+ {
+ // map 16
+ action(static_cast<uint8_t>(msgpack_format::map16_cd), v);
+ action(static_cast<uint16_t>(length), v);
+ }
+ else if (length <= 4294967295)
+ {
+ // map 32
+ action(static_cast<uint8_t>(msgpack_format::map32_cd), v);
+ action(static_cast<uint32_t>(length),v);
+ }
+
+ // append each element
+ for (const auto& kv: jval.object_range())
+ {
+ encode_string(kv.key(), action, v);
+ encode(kv.value(), action, v);
+ }
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ template <class Action, class Result>
+ static void encode_string(const string_view_type& sv, Action action, Result& v)
+ {
+ std::basic_string<uint8_t> target;
+ auto result = unicons::convert(
+ sv.begin(), sv.end(), std::back_inserter(target),
+ unicons::conv_flags::strict);
+ if (result.ec != unicons::conv_errc())
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Illegal unicode"));
+ }
+
+ const size_t length = target.length();
+ if (length <= 31)
+ {
+ // fixstr stores a byte array whose length is upto 31 bytes
+ action(static_cast<uint8_t>(0xa0 | length), v);
+ }
+ else if (length <= (std::numeric_limits<uint8_t>::max)())
+ {
+ // str 8 stores a byte array whose length is upto (2^8)-1 bytes
+ action(static_cast<uint8_t>(msgpack_format::str8_cd), v);
+ action(static_cast<uint8_t>(length), v);
+ }
+ else if (length <= (std::numeric_limits<uint16_t>::max)())
+ {
+ // str 16 stores a byte array whose length is upto (2^16)-1 bytes
+ action(static_cast<uint8_t>(msgpack_format::str16_cd), v);
+ action(static_cast<uint16_t>(length), v);
+ }
+ else if (length <= (std::numeric_limits<uint32_t>::max)())
+ {
+ // str 32 stores a byte array whose length is upto (2^32)-1 bytes
+ action(static_cast<uint8_t>(msgpack_format::str32_cd), v);
+ action(static_cast<uint32_t>(length),v);
+ }
+
+ for (size_t i = 0; i < length; ++i)
+ {
+ action(static_cast<uint8_t>(target.data()[i]), v);
+ }
+ }
+};
+
+// decode_msgpack
+
+template<class Json>
+class Decode_msgpack_
+{
+ const uint8_t* begin_;
+ const uint8_t* end_;
+ const uint8_t* it_;
+public:
+ typedef typename Json::char_type char_type;
+
+ Decode_msgpack_(const uint8_t* begin, const uint8_t* end)
+ : begin_(begin), end_(end), it_(begin)
+ {
+ }
+
+ Json decode()
+ {
+ // store && increment index
+ const uint8_t* pos = it_++;
+
+ if (*pos <= 0xbf)
+ {
+ if (*pos <= 0x7f)
+ {
+ // positive fixint
+ return Json(*pos);
+ }
+ else if (*pos <= 0x8f)
+ {
+ // fixmap
+ Json result;
+ const size_t len = *pos & 0x0f;
+ result.reserve(len);
+ for (size_t i = 0; i < len; ++i)
+ {
+ auto j = decode();
+ result.set(j.as_string_view(),decode());
+ }
+ return result;
+ }
+ else if (*pos <= 0x9f)
+ {
+ // fixarray
+ Json result = typename Json::array();
+ const size_t len = *pos & 0x0f;
+ result.reserve(len);
+ for (size_t i = 0; i < len; ++i)
+ {
+ result.push_back(decode());
+ }
+ return result;
+ }
+ else
+ {
+ // fixstr
+ const size_t len = *pos & 0x1f;
+ const uint8_t* first = &(*it_);
+ const uint8_t* last = first + len;
+ it_ += len;
+
+ std::basic_string<char_type> target;
+ auto result = unicons::convert(
+ first, last,std::back_inserter(target),unicons::conv_flags::strict);
+ if (result.ec != unicons::conv_errc())
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Illegal unicode"));
+ }
+ return Json(target);
+ }
+ }
+ else if (*pos >= 0xe0)
+ {
+ // negative fixint
+ return static_cast<int8_t>(*pos);
+ }
+ else
+ {
+ switch (*pos)
+ {
+ case msgpack_format::nil_cd:
+ {
+ return Json(null_type());
+ }
+ case msgpack_format::true_cd:
+ {
+ return Json(true);
+ }
+ case msgpack_format::false_cd:
+ {
+ return Json(false);
+ }
+ case msgpack_format::float32_cd:
+ {
+ const uint8_t* endp;
+ float res = binary::from_big_endian<float>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return res;
+ }
+
+ case msgpack_format::float64_cd:
+ {
+ const uint8_t* endp;
+ double res = binary::from_big_endian<double>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return res;
+ }
+
+ case msgpack_format::uint8_cd:
+ {
+ const uint8_t* endp;
+ auto x = binary::from_big_endian<uint8_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return Json(x);
+ }
+
+ case msgpack_format::uint16_cd:
+ {
+ const uint8_t* endp;
+ auto x = binary::from_big_endian<uint16_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return x;
+ }
+
+ case msgpack_format::uint32_cd:
+ {
+ const uint8_t* endp;
+ auto x = binary::from_big_endian<uint32_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return x;
+ }
+
+ case msgpack_format::uint64_cd:
+ {
+ const uint8_t* endp;
+ auto x = binary::from_big_endian<uint64_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return x;
+ }
+
+ case msgpack_format::int8_cd:
+ {
+ const uint8_t* endp;
+ auto x = binary::from_big_endian<int8_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return Json(x);
+ }
+
+ case msgpack_format::int16_cd:
+ {
+ const uint8_t* endp;
+ auto x = binary::from_big_endian<int16_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return x;
+ }
+
+ case msgpack_format::int32_cd:
+ {
+ const uint8_t* endp;
+ auto x = binary::from_big_endian<int32_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return x;
+ }
+
+ case msgpack_format::int64_cd:
+ {
+ const uint8_t* endp;
+ auto x = binary::from_big_endian<int64_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ return x;
+ }
+
+ case msgpack_format::str8_cd:
+ {
+ const uint8_t* endp;
+ const auto len = binary::from_big_endian<int8_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+
+ const uint8_t* first = &(*(pos + 2));
+ const uint8_t* last = first + len;
+ it_ += len;
+
+ std::basic_string<char_type> target;
+ auto result = unicons::convert(
+ first, last,std::back_inserter(target),unicons::conv_flags::strict);
+ if (result.ec != unicons::conv_errc())
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Illegal unicode"));
+ }
+ return target;
+ }
+
+ case msgpack_format::str16_cd:
+ {
+ const uint8_t* endp;
+ const auto len = binary::from_big_endian<int16_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+
+ const uint8_t* first = &(*(pos + 3));
+ const uint8_t* last = first + len;
+ it_ += len;
+
+ std::basic_string<char_type> target;
+ auto result = unicons::convert(
+ first, last,std::back_inserter(target),unicons::conv_flags::strict);
+ if (result.ec != unicons::conv_errc())
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Illegal unicode"));
+ }
+ return target;
+ }
+
+ case msgpack_format::str32_cd:
+ {
+ const uint8_t* endp;
+ const auto len = binary::from_big_endian<int32_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+
+ const uint8_t* first = &(*(pos + 5));
+ const uint8_t* last = first + len;
+ it_ += len;
+
+ std::basic_string<char_type> target;
+ auto result = unicons::convert(
+ first, last,std::back_inserter(target),unicons::conv_flags::strict);
+ if (result.ec != unicons::conv_errc())
+ {
+ JSONCONS_THROW(json_exception_impl<std::runtime_error>("Illegal unicode"));
+ }
+ return target;
+ }
+
+ case msgpack_format::array16_cd:
+ {
+ Json result = typename Json::array();
+ const uint8_t* endp;
+ const auto len = binary::from_big_endian<uint16_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ result.reserve(len);
+ for (size_t i = 0; i < len; ++i)
+ {
+ result.push_back(decode());
+ }
+ return result;
+ }
+
+ case msgpack_format::array32_cd:
+ {
+ Json result = typename Json::array();
+ const uint8_t* endp;
+ const auto len = binary::from_big_endian<uint32_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ result.reserve(len);
+ for (size_t i = 0; i < len; ++i)
+ {
+ result.push_back(decode());
+ }
+ return result;
+ }
+
+ case msgpack_format::map16_cd :
+ {
+ const uint8_t* endp;
+ const auto len = binary::from_big_endian<uint16_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ Json result = typename Json::object();
+ result.reserve(len);
+ for (size_t i = 0; i < len; ++i)
+ {
+ auto j = decode();
+ result.set(j.as_string_view(),decode());
+ }
+ return result;
+ }
+
+ case msgpack_format::map32_cd :
+ {
+ Json result = typename Json::object();
+ const uint8_t* endp;
+ const auto len = binary::from_big_endian<uint32_t>(it_,end_,&endp);
+ if (endp == it_)
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-it_));
+ }
+ else
+ {
+ it_ = endp;
+ }
+ result.reserve(len);
+ for (size_t i = 0; i < len; ++i)
+ {
+ auto key = decode().as_string_view();
+ result.set(key,decode());
+ }
+ return result;
+ }
+
+ default:
+ {
+ JSONCONS_THROW(msgpack_decode_error(end_-pos));
+ }
+ }
+ }
+ }
+};
+
+template<class Json>
+void encode_msgpack(const Json& j, std::vector<uint8_t>& v)
+{
+ size_t n = 0;
+ msgpack_Encoder_<Json>::encode(j,Calculate_size_(),n);
+ v.reserve(n);
+ //v.reserve(msgpack_Encoder_<Json>::calculate_size(j));
+
+ msgpack_Encoder_<Json>::encode(j,Encode_msgpack_(),v);
+}
+
+template<class Json>
+Json decode_msgpack(const std::vector<uint8_t>& v)
+{
+ Decode_msgpack_<Json> decoder(v.data(),v.data()+v.size());
+ return decoder.decode();
+}
+
+#if !defined(JSONCONS_NO_DEPRECATED)
+template<class Json>
+std::vector<uint8_t> encode_msgpack(const Json& j)
+{
+ std::vector<uint8_t> v;
+ encode_msgpack(j, v);
+ return v;
+}
+#endif
+
+}}
+
+#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons/json.hpp b/vendor/jsoncons-0.99.2/jsoncons/json.hpp
deleted file mode 100644
index b9058b59..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/json.hpp
+++ /dev/null
@@ -1,3574 +0,0 @@
-// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_JSON_HPP
-#define JSONCONS_JSON_HPP
-
-#include <limits>
-#include <string>
-#include <vector>
-#include <exception>
-#include <cstdlib>
-#include <cstring>
-#include <ostream>
-#include <memory>
-#include <typeinfo>
-#include "jsoncons/json_structures.hpp"
-#include "jsoncons/jsoncons.hpp"
-#include "jsoncons/json_output_handler.hpp"
-#include "jsoncons/output_format.hpp"
-#include "jsoncons/json_serializer.hpp"
-#include "jsoncons/json_deserializer.hpp"
-#include "jsoncons/json_reader.hpp"
-#include "jsoncons/json_type_traits.hpp"
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wswitch"
-#endif
-
-namespace jsoncons {
-
-template <class T, class Alloc, typename... Args>
-T* create_impl(const Alloc& allocator, Args&& ... args)
-{
- typename std::allocator_traits<Alloc>:: template rebind_alloc<T> alloc(allocator);
- T* storage = alloc.allocate(1);
- try
- {
- std::allocator_traits<Alloc>:: template rebind_traits<T>::construct(alloc, storage, std::forward<Args>(args)...);
- }
- catch (...)
- {
- alloc.deallocate(storage,1);
- throw;
- }
- return storage;
-}
-
-template <class T, class Alloc>
-void destroy_impl(const Alloc& allocator, T* p)
-{
- typename std::allocator_traits<Alloc>:: template rebind_alloc<T> alloc(allocator);
- std::allocator_traits<Alloc>:: template rebind_traits<T>::destroy(alloc, p);
- alloc.deallocate(p,1);
-}
-
-template <typename CharT, class Alloc>
-class serializable_any
-{
-public:
- typedef Alloc allocator_type;
-
- serializable_any(const Alloc& allocator = Alloc())
- : impl_(nullptr)
- {
- (void)allocator;
- }
- serializable_any(const serializable_any& val)
- : allocator_(std::allocator_traits<allocator_type>::select_on_container_copy_construction(val.get_allocator()))
- {
- impl_ = val.impl_ != nullptr ? val.impl_->clone(allocator_) : nullptr;
- }
- serializable_any(const serializable_any& val, const Alloc& allocator)
- {
- (void)allocator;
- impl_ = val.impl_ != nullptr ? val.impl_->clone(Alloc()) : nullptr;
- }
-
- serializable_any(serializable_any&& val)
- : impl_(std::move(val.impl_))
- {
- val.impl_ = nullptr;
- }
- serializable_any(serializable_any&& val, const Alloc& allocator)
- : impl_(std::move(val.impl_))
- {
- (void)allocator;
- val.impl_ = nullptr;
- }
- ~serializable_any()
- {
- if (impl_ != nullptr)
- {
- destroy_impl(allocator_,impl_);
- }
- }
-
- template<typename T>
- explicit serializable_any(T val)
- {
- impl_ = create_impl<any_handle_impl<typename type_wrapper<T>::value_type>>(allocator_,val);
- }
-
- Alloc get_allocator() const
- {
- return allocator_;
- }
-
- template <typename T>
- typename type_wrapper<T>::reference cast()
- {
- if (typeid(*impl_) != typeid(any_handle_impl<typename type_wrapper<T>::value_type>))
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad serializable_any cast");
- }
- return static_cast<any_handle_impl<typename type_wrapper<T>::value_type>&>(*impl_).value_;
- }
-
- template <typename T>
- typename type_wrapper<T>::const_reference cast() const
- {
- if (typeid(*impl_) != typeid(any_handle_impl<typename type_wrapper<T>::value_type>))
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad serializable_any cast");
- }
- return static_cast<any_handle_impl<typename type_wrapper<T>::value_type>&>(*impl_).value_;
- }
-
- serializable_any& operator=(serializable_any rhs)
- {
- std::swap(impl_,rhs.impl_);
- return *this;
- }
-
- void to_stream(basic_json_output_handler<CharT>& os) const
- {
- impl_->to_stream(os);
- }
-
- class any_handle
- {
- public:
- virtual ~any_handle()
- {
- }
-
- virtual any_handle* clone(const Alloc& allocator) const = 0;
-
- virtual void to_stream(basic_json_output_handler<CharT>& os) const = 0;
- };
-
- template <class T>
- class any_handle_impl : public any_handle
- {
- public:
- any_handle_impl(T value, const Alloc& allocator = Alloc())
- : value_(value)
- {
- (void)allocator;
- }
-
- virtual any_handle* clone(const Alloc& allocator) const
- {
- return create_impl<any_handle_impl<T>>(allocator, value_);
- }
-
- virtual void to_stream(basic_json_output_handler<CharT>& os) const
- {
- serialize(os,value_);
- }
-
- T value_;
- };
-
- Alloc allocator_;
- any_handle* impl_;
-};
-
-template <typename CharT,class T> inline
-void serialize(basic_json_output_handler<CharT>& os, const T&)
-{
- os.value(null_type());
-}
-
-template <typename CharT>
-class basic_parse_error_handler;
-
-enum class value_types : uint8_t
-{
- // Simple types
- empty_object_t,
- small_string_t,
- double_t,
- integer_t,
- uinteger_t,
- bool_t,
- null_t,
- // Non simple types
- string_t,
- object_t,
- array_t,
- any_t
-};
-
-inline
-bool is_simple(value_types type)
-{
- return type < value_types::string_t;
-}
-
-template <typename CharT, typename Alloc = std::allocator<CharT>>
-class basic_json
-{
-public:
-
- typedef Alloc allocator_type;
-
- typedef CharT char_type;
- typedef typename std::char_traits<CharT> char_traits_type;
-
- typedef typename std::allocator_traits<Alloc>:: template rebind_alloc<CharT> string_allocator;
- typedef std::basic_string<CharT,char_traits_type,string_allocator> string_type;
- typedef basic_json<CharT,Alloc> value_type;
- typedef name_value_pair<string_type,value_type> member_type;
-
- typedef typename std::allocator_traits<Alloc>:: template rebind_alloc<basic_json<CharT,Alloc>> array_allocator;
-
- typedef typename std::allocator_traits<Alloc>:: template rebind_alloc<member_type> object_allocator;
-
- typedef json_array<basic_json<CharT,Alloc>,array_allocator> array;
- typedef json_object<string_type,basic_json<CharT,Alloc>,object_allocator> object;
- typedef serializable_any<char_type,Alloc> any;
-
- typedef jsoncons::null_type null_type;
-
- typedef typename object::iterator object_iterator;
- typedef typename object::const_iterator const_object_iterator;
- typedef typename array::iterator array_iterator;
- typedef typename array::const_iterator const_array_iterator;
-
- template <typename IteratorT>
- class range
- {
- IteratorT first_;
- IteratorT last_;
- public:
- range(const IteratorT& first, const IteratorT& last)
- : first_(first), last_(last)
- {
- }
-
- public:
- friend class basic_json<CharT, Alloc>;
-
- IteratorT begin()
- {
- return first_;
- }
- IteratorT end()
- {
- return last_;
- }
- };
-
- typedef range<object_iterator> object_range;
- typedef range<const_object_iterator> const_object_range;
- typedef range<array_iterator> array_range;
- typedef range<const_array_iterator> const_array_range;
-
- struct variant
- {
- struct string_data : public string_allocator
- {
- const char_type* c_str() const { return p_; }
- const char_type* data() const { return p_; }
- size_t length() const { return length_; }
- string_allocator get_allocator() const
- {
- return *this;
- }
-
- bool operator==(const string_data& rhs) const
- {
- return length() == rhs.length() ? std::char_traits<char_type>::compare(data(), rhs.data(), length()) == 0 : false;
- }
-
- string_data(const string_allocator& allocator)
- : string_allocator(allocator), p_(nullptr), length_(0)
- {
- }
-
- char_type* p_;
- size_t length_;
- private:
- string_data(const string_data&);
- string_data& operator=(const string_data&);
- };
-
- struct string_dataA
- {
- string_data data;
- char_type c[1];
- };
- typedef typename std::aligned_storage<sizeof(string_dataA), JSONCONS_ALIGNOF(string_dataA)>::type storage_type;
-
- static size_t aligned_size(size_t n)
- {
- return sizeof(storage_type) + n;
- }
-
- string_data* create_string_data(const char_type* s, size_t length, const string_allocator& allocator)
- {
- size_t mem_size = aligned_size(length*sizeof(char_type));
-
- typename std::allocator_traits<string_allocator>:: template rebind_alloc<char> alloc(allocator);
-
- char* storage = alloc.allocate(mem_size);
- string_data* ps = new(storage)string_data(allocator);
- auto psa = reinterpret_cast<string_dataA*>(storage);
-
- ps->p_ = new(&psa->c)char_type[length + 1];
- memcpy(ps->p_, s, length*sizeof(char_type));
- ps->p_[length] = 0;
- ps->length_ = length;
- return ps;
- }
-
- void destroy_string_data(const string_allocator& allocator, string_data* p)
- {
- size_t mem_size = aligned_size(p->length_*sizeof(char_type));
- typename std::allocator_traits<string_allocator>:: template rebind_alloc<char> alloc(allocator);
- alloc.deallocate(reinterpret_cast<char*>(p),mem_size);
- }
-
- static const size_t small_string_capacity = (sizeof(int64_t)/sizeof(char_type)) - 1;
-
- variant()
- : type_(value_types::empty_object_t)
- {
- }
-
- variant(const Alloc& a)
- : type_(value_types::object_t)
- {
- value_.object_val_ = create_impl<object>(a, object_allocator(a));
- }
-
- variant(std::initializer_list<value_type> init,
- const Alloc& a)
- : type_(value_types::array_t)
- {
- value_.array_val_ = create_impl<array>(a, std::move(init), array_allocator(a));
- }
-
- explicit variant(variant&& var)
- : type_(value_types::null_t)
- {
- swap(var);
- }
-
- explicit variant(variant&& var, const Alloc& a)
- : type_(value_types::null_t)
- {
- swap(var);
- }
-
- explicit variant(const variant& var)
- {
- init_variant(var);
- }
- explicit variant(const variant& var, const Alloc& a)
- : type_(var.type_)
- {
- init_variant(var);
- }
-
- variant(const object & val)
- : type_(value_types::object_t)
- {
- value_.object_val_ = create_impl<object>(val.get_allocator(), val) ;
- }
-
- variant(const object & val, const Alloc& a)
- : type_(value_types::object_t)
- {
- value_.object_val_ = create_impl<object>(a, val, object_allocator(a)) ;
- }
-
- variant(object&& val)
- : type_(value_types::object_t)
- {
- value_.object_val_ = create_impl<object>(val.get_allocator(), std::move(val));
- }
-
- variant(object&& val, const Alloc& a)
- : type_(value_types::object_t)
- {
- value_.object_val_ = create_impl<object>(a, std::move(val), object_allocator(a));
- }
-
- variant(const array& val)
- : type_(value_types::array_t)
- {
- value_.array_val_ = create_impl<array>(val.get_allocator(), val);
- }
-
- variant(const array& val, const Alloc& a)
- : type_(value_types::array_t)
- {
- value_.array_val_ = create_impl<array>(a, val, array_allocator(a));
- }
-
- variant(array&& val)
- : type_(value_types::array_t)
- {
- value_.array_val_ = create_impl<array>(val.get_allocator(), std::move(val));
- }
-
- variant(array&& val, const Alloc& a)
- : type_(value_types::array_t)
- {
- value_.array_val_ = create_impl<array>(a, std::move(val), array_allocator(a));
- }
-
- explicit variant(const any& val, const Alloc& a)
- : type_(value_types::any_t)
- {
- value_.any_val_ = create_impl<any>(a, val);
- }
-
- explicit variant(null_type)
- : type_(value_types::null_t)
- {
- }
-
- explicit variant(bool val)
- : type_(value_types::bool_t)
- {
- value_.bool_val_ = val;
- }
-
- explicit variant(double val, uint8_t precision)
- : type_(value_types::double_t), length_or_precision_(precision)
- {
- value_.double_val_ = val;
- }
-
- explicit variant(int64_t val)
- : type_(value_types::integer_t)
- {
- value_.integer_val_ = val;
- }
-
- explicit variant(uint64_t val)
- : type_(value_types::uinteger_t)
- {
- value_.uinteger_val_ = val;
- }
-
- explicit variant(const string_type& s, const Alloc& a)
- {
- if (s.length() > variant::small_string_capacity)
- {
- type_ = value_types::string_t;
- //value_.string_val_ = create_impl<string_type>(a, s, string_allocator(a));
- value_.string_val_ = create_string_data(s.data(), s.length(), string_allocator(a));
- }
- else
- {
- type_ = value_types::small_string_t;
- length_or_precision_ = static_cast<uint8_t>(s.length());
- std::memcpy(value_.small_string_val_,s.data(),s.length()*sizeof(char_type));
- value_.small_string_val_[length_or_precision_] = 0;
- }
- }
-
- explicit variant(const char_type* s, const Alloc& a)
- {
- size_t length = std::char_traits<char_type>::length(s);
- if (length > variant::small_string_capacity)
- {
- type_ = value_types::string_t;
- //value_.string_val_ = create_impl<string_type>(a, s, string_allocator(a));
- value_.string_val_ = create_string_data(s, length, string_allocator(a));
- }
- else
- {
- type_ = value_types::small_string_t;
- length_or_precision_ = static_cast<uint8_t>(length);
- std::memcpy(value_.small_string_val_,s,length*sizeof(char_type));
- value_.small_string_val_[length_or_precision_] = 0;
- }
- }
-
- explicit variant(const char_type* s, size_t length, const Alloc& a)
- {
- if (length > variant::small_string_capacity)
- {
- type_ = value_types::string_t;
- //value_.string_val_ = create_impl<string_type>(a, s, length, string_allocator(a));
- value_.string_val_ = create_string_data(s, length, string_allocator(a));
- }
- else
- {
- type_ = value_types::small_string_t;
- length_or_precision_ = static_cast<uint8_t>(length);
- std::memcpy(value_.small_string_val_,s,length*sizeof(char_type));
- value_.small_string_val_[length_or_precision_] = 0;
- }
- }
-
- template<class InputIterator>
- variant(InputIterator first, InputIterator last, const Alloc& a)
- : type_(value_types::array_t)
- {
- value_.array_val_ = create_impl<array>(a, first, last, array_allocator(a));
- }
-
- void init_variant(const variant& var)
- {
- type_ = var.type_;
- switch (type_)
- {
- case value_types::null_t:
- case value_types::empty_object_t:
- break;
- case value_types::double_t:
- length_or_precision_ = 0;
- value_.double_val_ = var.value_.double_val_;
- break;
- case value_types::integer_t:
- value_.integer_val_ = var.value_.integer_val_;
- break;
- case value_types::uinteger_t:
- value_.uinteger_val_ = var.value_.uinteger_val_;
- break;
- case value_types::bool_t:
- value_.bool_val_ = var.value_.bool_val_;
- break;
- case value_types::small_string_t:
- length_or_precision_ = var.length_or_precision_;
- std::memcpy(value_.small_string_val_,var.value_.small_string_val_,var.length_or_precision_*sizeof(char_type));
- value_.small_string_val_[length_or_precision_] = 0;
- break;
- case value_types::string_t:
- //value_.string_val_ = create_impl<string_type>(var.value_.string_val_->get_allocator(), *(var.value_.string_val_), string_allocator(var.value_.string_val_->get_allocator()));
- value_.string_val_ = create_string_data(var.value_.string_val_->data(), var.value_.string_val_->length(), string_allocator(var.value_.string_val_->get_allocator()));
- break;
- case value_types::array_t:
- value_.array_val_ = create_impl<array>(var.value_.array_val_->get_allocator(), *(var.value_.array_val_), array_allocator(var.value_.array_val_->get_allocator()));
- break;
- case value_types::object_t:
- value_.object_val_ = create_impl<object>(var.value_.object_val_->get_allocator(), *(var.value_.object_val_), object_allocator(var.value_.object_val_->get_allocator()));
- break;
- case value_types::any_t:
- value_.any_val_ = create_impl<any>(var.value_.any_val_->get_allocator(), *(var.value_.any_val_));
- break;
- default:
- break;
- }
- }
-
- ~variant()
- {
- destroy_variant();
- }
-
- void destroy_variant()
- {
- switch (type_)
- {
- case value_types::string_t:
- //destroy_impl(value_.string_val_->get_allocator(), value_.string_val_);
- destroy_string_data(value_.string_val_->get_allocator(), value_.string_val_);
- break;
- case value_types::array_t:
- destroy_impl(value_.array_val_->get_allocator(), value_.array_val_);
- break;
- case value_types::object_t:
- destroy_impl(value_.object_val_->get_allocator(), value_.object_val_);
- break;
- case value_types::any_t:
- destroy_impl(value_.any_val_->get_allocator(), value_.any_val_);
- break;
- default:
- break;
- }
- }
-
- variant& operator=(const variant& val)
- {
- if (this != &val)
- {
- if (is_simple(type_))
- {
- if (is_simple(val.type_))
- {
- type_ = val.type_;
- length_or_precision_ = val.length_or_precision_;
- value_ = val.value_;
- }
- else
- {
- init_variant(val);
- }
- }
- else
- {
- destroy_variant();
- init_variant(val);
- }
- }
- return *this;
- }
-
- variant& operator=(variant&& val)
- {
- if (this != &val)
- {
- val.swap(*this);
- }
- return *this;
- }
-
- void assign(const object & val)
- {
- destroy_variant();
- type_ = value_types::object_t;
- value_.object_val_ = create_impl<object>(val.get_allocator(), val, object_allocator(val.get_allocator()));
- }
-
- void assign(object && val)
- {
- switch (type_)
- {
- case value_types::object_t:
- value_.object_val_->swap(val);
- break;
- default:
- destroy_variant();
- type_ = value_types::object_t;
- value_.object_val_ = create_impl<object>(val.get_allocator(), std::move(val), object_allocator(val.get_allocator()));
- break;
- }
- }
-
- void assign(const array& val)
- {
- destroy_variant();
- type_ = value_types::array_t;
- value_.array_val_ = create_impl<array>(val.get_allocator(), val, array_allocator(val.get_allocator())) ;
- }
-
- void assign(array&& val)
- {
- switch (type_)
- {
- case value_types::array_t:
- value_.array_val_->swap(val);
- break;
- default:
- destroy_variant();
- type_ = value_types::array_t;
- value_.array_val_ = create_impl<array>(val.get_allocator(), std::move(val), array_allocator(val.get_allocator()));
- break;
- }
- }
-
- void assign(const string_type& s)
- {
- destroy_variant();
- if (s.length() > variant::small_string_capacity)
- {
- type_ = value_types::string_t;
- //value_.string_val_ = create_impl<string_type>(s.get_allocator(), s, string_allocator(s.get_allocator()));
- value_.string_val_ = create_string_data(s.data(), s.length(), string_allocator(s.get_allocator()));
- }
- else
- {
- type_ = value_types::small_string_t;
- length_or_precision_ = static_cast<uint8_t>(s.length());
- std::memcpy(value_.small_string_val_,s.data(),s.length()*sizeof(char_type));
- value_.small_string_val_[length_or_precision_] = 0;
- }
- }
-
- void assign_string(const char_type* s, size_t length, const Alloc& allocator = Alloc())
- {
- destroy_variant();
- if (length > variant::small_string_capacity)
- {
- type_ = value_types::string_t;
- //value_.string_val_ = create_impl<string_type>(allocator, s, length, string_allocator(allocator));
- value_.string_val_ = create_string_data(s, length, string_allocator(allocator));
- }
- else
- {
- type_ = value_types::small_string_t;
- length_or_precision_ = static_cast<uint8_t>(length);
- std::memcpy(value_.small_string_val_,s,length*sizeof(char_type));
- value_.small_string_val_[length_or_precision_] = 0;
- }
- }
-
- void assign(int64_t val)
- {
- destroy_variant();
- type_ = value_types::integer_t;
- value_.integer_val_ = val;
- }
-
- void assign(uint64_t val)
- {
- destroy_variant();
- type_ = value_types::uinteger_t;
- value_.uinteger_val_ = val;
- }
-
- void assign(double val, uint8_t precision = 0)
- {
- destroy_variant();
- type_ = value_types::double_t;
- length_or_precision_ = precision;
- value_.double_val_ = val;
- }
-
- void assign(bool val)
- {
- destroy_variant();
- type_ = value_types::bool_t;
- value_.bool_val_ = val;
- }
-
- void assign(null_type)
- {
- destroy_variant();
- type_ = value_types::null_t;
- }
-
- void assign(const any& rhs)
- {
- destroy_variant();
- type_ = value_types::any_t;
- value_.any_val_ = create_impl<any>(rhs.get_allocator(), rhs);
- }
-
- bool operator!=(const variant& rhs) const
- {
- return !(*this == rhs);
- }
-
- bool operator==(const variant& rhs) const
- {
- if (is_number() & rhs.is_number())
- {
- switch (type_)
- {
- case value_types::integer_t:
- switch (rhs.type_)
- {
- case value_types::integer_t:
- return value_.integer_val_ == rhs.value_.integer_val_;
- case value_types::uinteger_t:
- return value_.integer_val_ == rhs.value_.uinteger_val_;
- case value_types::double_t:
- return value_.integer_val_ == rhs.value_.double_val_;
- default:
- break;
- }
- break;
- case value_types::uinteger_t:
- switch (rhs.type_)
- {
- case value_types::integer_t:
- return value_.uinteger_val_ == rhs.value_.integer_val_;
- case value_types::uinteger_t:
- return value_.uinteger_val_ == rhs.value_.uinteger_val_;
- case value_types::double_t:
- return value_.uinteger_val_ == rhs.value_.double_val_;
- default:
- break;
- }
- break;
- case value_types::double_t:
- switch (rhs.type_)
- {
- case value_types::integer_t:
- return value_.double_val_ == rhs.value_.integer_val_;
- case value_types::uinteger_t:
- return value_.double_val_ == rhs.value_.uinteger_val_;
- case value_types::double_t:
- return value_.double_val_ == rhs.value_.double_val_;
- default:
- break;
- }
- break;
- default:
- break;
- }
- }
-
- switch (type_)
- {
- case value_types::bool_t:
- return type_ == rhs.type_ && value_.bool_val_ == rhs.value_.bool_val_;
- case value_types::null_t:
- return type_ == rhs.type_;
- case value_types::empty_object_t:
- return type_ == rhs.type_ || (rhs.type_ == value_types::object_t && rhs.empty());
- case value_types::small_string_t:
- return type_ == rhs.type_ && length_or_precision_ == rhs.length_or_precision_ ? std::char_traits<char_type>::compare(value_.small_string_val_,rhs.value_.small_string_val_,length_or_precision_) == 0 : false;
- case value_types::string_t:
- return type_ == rhs.type_ && *(value_.string_val_) == *(rhs.value_.string_val_);
- case value_types::array_t:
- return type_ == rhs.type_ && *(value_.array_val_) == *(rhs.value_.array_val_);
- break;
- case value_types::object_t:
- return (type_ == rhs.type_ && *(value_.object_val_) == *(rhs.value_.object_val_)) || (rhs.type_ == value_types::empty_object_t && empty());
- break;
- case value_types::any_t:
- return type_ == rhs.type_;
- default:
- // throw
- break;
- }
- return false;
- }
-
- bool is_null() const JSONCONS_NOEXCEPT
- {
- return type_ == value_types::null_t;
- }
-
- bool is_bool() const JSONCONS_NOEXCEPT
- {
- return type_ == value_types::bool_t;
- }
-
- bool empty() const JSONCONS_NOEXCEPT
- {
- switch (type_)
- {
- case value_types::small_string_t:
- return length_or_precision_ == 0;
- case value_types::string_t:
- return value_.string_val_->length() == 0;
- case value_types::array_t:
- return value_.array_val_->size() == 0;
- case value_types::empty_object_t:
- return true;
- case value_types::object_t:
- return value_.object_val_->size() == 0;
- default:
- return false;
- }
- }
-
- bool is_string() const JSONCONS_NOEXCEPT
- {
- return (type_ == value_types::string_t) | (type_ == value_types::small_string_t);
- }
-
- bool is_number() const JSONCONS_NOEXCEPT
- {
- return type_ == value_types::double_t || type_ == value_types::integer_t || type_ == value_types::uinteger_t;
- }
-
- void swap(variant& rhs)
- {
- using std::swap;
- if (this == &rhs)
- {
- // same object, do nothing
- }
- else
- {
- swap(type_, rhs.type_);
- swap(length_or_precision_, rhs.length_or_precision_);
- swap(value_, rhs.value_);
- }
- }
-
- value_types type_;
- uint8_t length_or_precision_;
- union
- {
- double double_val_;
- int64_t integer_val_;
- uint64_t uinteger_val_;
- bool bool_val_;
- object* object_val_;
- array* array_val_;
- any* any_val_;
- string_data* string_val_;
- char_type small_string_val_[sizeof(int64_t)/sizeof(char_type)];
- } value_;
- };
-
- template <class ParentT>
- class json_proxy
- {
- private:
- typedef json_proxy<ParentT> proxy_type;
-
- ParentT& parent_;
- const string_type& name_;
-
- json_proxy() = delete;
- json_proxy& operator = (const json_proxy& other) = delete;
-
- json_proxy(ParentT& parent, const string_type& name)
- : parent_(parent), name_(name)
- {
- }
-
- basic_json<CharT,Alloc>& evaluate()
- {
- return parent_.evaluate(name_);
- }
-
- const basic_json<CharT,Alloc>& evaluate() const
- {
- return parent_.evaluate(name_);
- }
-
- basic_json<CharT,Alloc>& evaluate_with_default()
- {
- basic_json<CharT,Alloc>& val = parent_.evaluate_with_default();
- auto it = val.find(name_.data(),name_.length());
- if (it == val.members().end())
- {
- it = val.set(val.members().begin(),name_,object(val.object_value().get_allocator()));
- }
- return it->value();
- }
-
- basic_json<CharT,Alloc>& evaluate(size_t index)
- {
- return parent_.evaluate(name_).at(index);
- }
-
- const basic_json<CharT,Alloc>& evaluate(size_t index) const
- {
- return parent_.evaluate(name_).at(index);
- }
-
- basic_json<CharT,Alloc>& evaluate(const string_type& index)
- {
- return parent_.evaluate(name_).at(index);
- }
-
- const basic_json<CharT,Alloc>& evaluate(const string_type& index) const
- {
- return parent_.evaluate(name_).at(index);
- }
- public:
-
- friend class basic_json<CharT,Alloc>;
-
- object_range members()
- {
- return evaluate().members();
- }
-
- const_object_range members() const
- {
- return evaluate().members();
- }
-
- array_range elements()
- {
- return evaluate().elements();
- }
-
- const_array_range elements() const
- {
- return evaluate().elements();
- }
-
- size_t size() const JSONCONS_NOEXCEPT
- {
- return evaluate().size();
- }
-
- value_types type() const
- {
- return evaluate().type();
- }
-
- size_t count(const string_type& name) const
- {
- return evaluate().count(name);
- }
-
- bool is_null() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_null();
- }
-
- bool empty() const
- {
- return evaluate().empty();
- }
-
- size_t capacity() const
- {
- return evaluate().capacity();
- }
-
- void reserve(size_t n)
- {
- evaluate().reserve(n);
- }
-
- void resize(size_t n)
- {
- evaluate().resize(n);
- }
-
- template <typename T>
- void resize(size_t n, T val)
- {
- evaluate().resize(n,val);
- }
-
- template<typename T>
- bool is() const
- {
- return evaluate().template is<T>();
- }
-
- bool is_string() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_string();
- }
-
- bool is_number() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_number();
- }
- bool is_bool() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_bool();
- }
-
- bool is_object() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_object();
- }
-
- bool is_array() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_array();
- }
-
- bool is_any() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_any();
- }
-
- bool is_integer() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_integer();
- }
-
- bool is_uinteger() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_uinteger();
- }
-
- bool is_double() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_double();
- }
-
- string_type as_string() const JSONCONS_NOEXCEPT
- {
- return evaluate().as_string();
- }
-
- string_type as_string(const string_allocator& allocator) const JSONCONS_NOEXCEPT
- {
- return evaluate().as_string(allocator);
- }
-
- string_type as_string(const basic_output_format<char_type>& format) const
- {
- return evaluate().as_string(format);
- }
-
- string_type as_string(const basic_output_format<char_type>& format,
- const string_allocator& allocator) const
- {
- return evaluate().as_string(format,allocator);
- }
-
- template<typename T>
- T as() const
- {
- return evaluate().template as<T>();
- }
-
- template<typename T>
- typename std::enable_if<std::is_same<string_type,T>::value>::type as(const string_allocator& allocator) const
- {
- return evaluate().template as<T>(allocator);
- }
-
- any& any_value()
- {
- return evaluate().any_value();
- }
-
- const any& any_value() const
- {
- return evaluate().any_value();
- }
-
- bool as_bool() const JSONCONS_NOEXCEPT
- {
- return evaluate().as_bool();
- }
-
- template <class T>
- std::vector<T> as_vector() const
- {
- return evaluate().template as_vector<T>();
- }
-
- double as_double() const
- {
- return evaluate().as_double();
- }
-
- int64_t as_integer() const
- {
- return evaluate().as_integer();
- }
-
- unsigned long long as_ulonglong() const
- {
- return evaluate().as_ulonglong();
- }
-
- uint64_t as_uinteger() const
- {
- return evaluate().as_uinteger();
- }
-
- template <class T>
- const T& any_cast() const
- {
- return evaluate().template any_cast<T>();
- }
- // Returns a const reference to the custom data associated with name
-
- template <class T>
- T& any_cast()
- {
- return evaluate().template any_cast<T>();
- }
- // Returns a reference to the custom data associated with name
-
- operator basic_json&()
- {
- return evaluate();
- }
-
- operator const basic_json&() const
- {
- return evaluate();
- }
-
- template <typename T>
- json_proxy& operator=(T val)
- {
- parent_.evaluate_with_default().set(name_, val);
- return *this;
- }
-
- json_proxy& operator=(const basic_json& val)
- {
- parent_.evaluate_with_default().set(name_, val);
- return *this;
- }
-
- json_proxy& operator=(basic_json&& val)
- {
- parent_.evaluate_with_default().set(name_, std::move(val));
- return *this;
- }
-
- bool operator==(const basic_json& val) const
- {
- return evaluate() == val;
- }
-
- bool operator!=(const basic_json& val) const
- {
- return evaluate() != val;
- }
-
- basic_json<CharT,Alloc>& operator[](size_t i)
- {
- return evaluate_with_default().at(i);
- }
-
- const basic_json<CharT,Alloc>& operator[](size_t i) const
- {
- return evaluate().at(i);
- }
-
- json_proxy<proxy_type> operator[](const string_type& name)
- {
- return json_proxy<proxy_type>(*this,name);
- }
-
- const json_proxy<proxy_type> operator[](const string_type& name) const
- {
- return json_proxy<proxy_type>(*this,name);
- }
-
- basic_json<CharT,Alloc>& at(const string_type& name)
- {
- return evaluate().at(name);
- }
-
- const basic_json<CharT,Alloc>& at(const string_type& name) const
- {
- return evaluate().at(name);
- }
-
- const basic_json<CharT,Alloc>& at(size_t index)
- {
- return evaluate().at(index);
- }
-
- const basic_json<CharT,Alloc>& at(size_t index) const
- {
- return evaluate().at(index);
- }
-
- object_iterator find(const string_type& name)
- {
- return evaluate().find(name);
- }
-
- const_object_iterator find(const string_type& name) const
- {
- return evaluate().find(name);
- }
-
- object_iterator find(const char_type* name)
- {
- return evaluate().find(name);
- }
-
- const_object_iterator find(const char_type* name) const
- {
- return evaluate().find(name);
- }
-
- object_iterator find(const char_type* name, size_t length)
- {
- return evaluate().find(name,length);
- }
-
- const_object_iterator find(const char_type* name, size_t length) const
- {
- return evaluate().find(name,length);
- }
-
- template <typename T>
- basic_json<CharT,Alloc> get(const string_type& name, T&& default_val) const
- {
- return evaluate().get(name,std::forward<T>(default_val));
- }
-
- void shrink_to_fit()
- {
- evaluate_with_default().shrink_to_fit();
- }
-
- void clear()
- {
- evaluate().clear();
- }
- // Remove all elements from an array or object
-
- void erase(object_iterator first, object_iterator last)
- {
- evaluate().erase(first, last);
- }
- // Remove a range of elements from an object
-
- void erase(array_iterator first, array_iterator last)
- {
- evaluate().erase(first, last);
- }
-
- void erase(const string_type& name)
- {
- evaluate().erase(name);
- }
-
- // Remove a member from an object
-
- void set(const string_type& name, const basic_json<CharT,Alloc>& value)
- {
- evaluate().set(name,value);
- }
-
- void set(string_type&& name, const basic_json<CharT,Alloc>& value)
-
- {
- evaluate().set(std::move(name),value);
- }
-
- void set(const string_type& name, basic_json<CharT,Alloc>&& value)
-
- {
- evaluate().set(name,std::move(value));
- }
-
- void set(string_type&& name, basic_json<CharT,Alloc>&& value)
-
- {
- evaluate().set(std::move(name),std::move(value));
- }
-
- object_iterator set(object_iterator hint, const string_type& name, const basic_json<CharT,Alloc>& value)
- {
- return evaluate().set(hint, name,value);
- }
-
- object_iterator set(object_iterator hint, string_type&& name, const basic_json<CharT,Alloc>& value)
-
- {
- return evaluate().set(hint, std::move(name),value);
- }
-
- object_iterator set(object_iterator hint, const string_type& name, basic_json<CharT,Alloc>&& value)
-
- {
- return evaluate().set(hint, name,std::move(value));
- }
-
- object_iterator set(object_iterator hint, string_type&& name, basic_json<CharT,Alloc>&& value)
-
- {
- return evaluate().set(hint, std::move(name),std::move(value));
- }
-
- void add(basic_json<CharT,Alloc>&& value)
- {
- evaluate_with_default().add(std::move(value));
- }
-
- void add(const basic_json<CharT,Alloc>& value)
- {
- evaluate_with_default().add(value);
- }
-
- array_iterator add(const_array_iterator pos, const basic_json<CharT,Alloc>& value)
- {
- return evaluate_with_default().add(pos, value);
- }
-
- array_iterator add(const_array_iterator pos, basic_json<CharT,Alloc>&& value)
- {
- return evaluate_with_default().add(pos, std::move(value));
- }
-
- string_type to_string(const string_allocator& allocator = string_allocator()) const JSONCONS_NOEXCEPT
- {
- return evaluate().to_string(allocator);
- }
-
- string_type to_string(const basic_output_format<char_type>& format, string_allocator& allocator = string_allocator()) const
- {
- return evaluate().to_string(format,allocator);
- }
-
- void to_stream(std::basic_ostream<char_type>& os) const
- {
- evaluate().to_stream(os);
- }
-
- void to_stream(std::basic_ostream<char_type>& os, const basic_output_format<char_type>& format) const
- {
- evaluate().to_stream(os,format);
- }
-
- void to_stream(std::basic_ostream<char_type>& os, const basic_output_format<char_type>& format, bool indenting) const
- {
- evaluate().to_stream(os,format,indenting);
- }
-
- void swap(basic_json<CharT,Alloc>& val)
- {
- evaluate_with_default().swap(val);
- }
-
- friend std::basic_ostream<char_type>& operator<<(std::basic_ostream<char_type>& os, const json_proxy& o)
- {
- o.to_stream(os);
- return os;
- }
-
-#if !defined(JSONCONS_NO_DEPRECATED)
-
- void resize_array(size_t n)
- {
- evaluate().resize_array(n);
- }
-
- template <typename T>
- void resize_array(size_t n, T val)
- {
- evaluate().resize_array(n,val);
- }
-
- object_iterator begin_members()
- {
- return evaluate().begin_members();
- }
-
- const_object_iterator begin_members() const
- {
- return evaluate().begin_members();
- }
-
- object_iterator end_members()
- {
- return evaluate().end_members();
- }
-
- const_object_iterator end_members() const
- {
- return evaluate().end_members();
- }
-
- array_iterator begin_elements()
- {
- return evaluate().begin_elements();
- }
-
- const_array_iterator begin_elements() const
- {
- return evaluate().begin_elements();
- }
-
- array_iterator end_elements()
- {
- return evaluate().end_elements();
- }
-
- const_array_iterator end_elements() const
- {
- return evaluate().end_elements();
- }
-
- const basic_json<CharT,Alloc>& get(const string_type& name) const
- {
- return evaluate().get(name);
- }
-
- bool is_ulonglong() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_ulonglong();
- }
-
- bool is_longlong() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_longlong();
- }
-
- int as_int() const
- {
- return evaluate().as_int();
- }
-
- unsigned int as_uint() const
- {
- return evaluate().as_uint();
- }
-
- long as_long() const
- {
- return evaluate().as_long();
- }
-
- unsigned long as_ulong() const
- {
- return evaluate().as_ulong();
- }
-
- long long as_longlong() const
- {
- return evaluate().as_longlong();
- }
-
- void add(size_t index, const basic_json<CharT,Alloc>& value)
- {
- evaluate_with_default().add(index, value);
- }
-
- void add(size_t index, basic_json<CharT,Alloc>&& value)
- {
- evaluate_with_default().add(index, std::move(value));
- }
-
- bool has_member(const string_type& name) const
- {
- return evaluate().has_member(name);
- }
-
- // Remove a range of elements from an array
- void remove_range(size_t from_index, size_t to_index)
- {
- evaluate().remove_range(from_index, to_index);
- }
- // Remove a range of elements from an array
- void remove(const string_type& name)
- {
- evaluate().remove(name);
- }
- void remove_member(const string_type& name)
- {
- evaluate().remove(name);
- }
- bool is_empty() const JSONCONS_NOEXCEPT
- {
- return empty();
- }
- bool is_numeric() const JSONCONS_NOEXCEPT
- {
- return is_number();
- }
-#endif
- };
-
- static basic_json parse_stream(std::basic_istream<char_type>& is);
- static basic_json parse_stream(std::basic_istream<char_type>& is, basic_parse_error_handler<char_type>& err_handler);
-
- static basic_json parse(const string_type& s)
- {
- basic_json_deserializer<basic_json<CharT, Alloc>> handler;
- basic_json_parser<char_type> parser(handler);
- parser.begin_parse();
- parser.parse(s.data(),0,s.length());
- parser.end_parse();
- parser.check_done(s.data(),parser.index(),s.length());
- if (!handler.is_valid())
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Failed to parse json string");
- }
- return handler.get_result();
- }
-
- static basic_json parse(const string_type& s, basic_parse_error_handler<char_type>& err_handler)
- {
- basic_json_deserializer<basic_json<CharT, Alloc>> handler;
- basic_json_parser<char_type> parser(handler,err_handler);
- parser.begin_parse();
- parser.parse(s.data(),0,s.length());
- parser.end_parse();
- parser.check_done(s.data(),parser.index(),s.length());
- if (!handler.is_valid())
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Failed to parse json string");
- }
- return handler.get_result();
- }
-
- static basic_json parse_file(const std::string& s);
-
- static basic_json parse_file(const std::string& s, basic_parse_error_handler<char_type>& err_handler);
-
- static basic_json make_array()
- {
- return basic_json::array();
- }
-
- static basic_json make_array(size_t n, const array_allocator& allocator = array_allocator())
- {
- return basic_json::array(n,allocator);
- }
-
- template <class T>
- static basic_json make_array(size_t n, const T& val, const array_allocator& allocator = array_allocator())
- {
- return basic_json::array(n, val,allocator);
- }
-
- template <size_t dim>
- static typename std::enable_if<dim==1,basic_json>::type make_array(size_t n)
- {
- return array(n);
- }
-
- template <size_t dim, class T>
- static typename std::enable_if<dim==1,basic_json>::type make_array(size_t n, const T& val, const Alloc& allocator = Alloc())
- {
- return array(n,val,allocator);
- }
-
- template <size_t dim, typename... Args>
- static typename std::enable_if<(dim>1),basic_json>::type make_array(size_t n, Args... args)
- {
- const size_t dim1 = dim - 1;
-
- basic_json val = make_array<dim1>(args...);
- val.resize(n);
- for (size_t i = 0; i < n; ++i)
- {
- val[i] = make_array<dim1>(args...);
- }
- return val;
- }
-
- variant var_;
-
- basic_json()
- : var_()
- {
- }
-
- basic_json(const Alloc& allocator)
- : var_(allocator)
- {
- }
-
- basic_json(std::initializer_list<value_type> init,
- const Alloc& allocator = Alloc())
- : var_(std::move(init), allocator)
- {
- }
-
- basic_json(const basic_json<CharT, Alloc>& val)
- : var_(val.var_)
- {
- }
-
- basic_json(const basic_json<CharT, Alloc>& val, const Alloc& allocator)
- : var_(val.var_,allocator)
- {
- }
-
- basic_json(basic_json<CharT,Alloc>&& other)
- : var_(std::move(other.var_))
- {
- }
-
- basic_json(basic_json<CharT,Alloc>&& other, const Alloc& allocator)
- : var_(std::move(other.var_),allocator)
- {
- }
-
- basic_json(const array& val)
- : var_(val)
- {
- }
-
- basic_json(array&& other)
- : var_(std::move(other))
- {
- }
-
- basic_json(const object& other)
- : var_(other)
- {
- }
-
- basic_json(object&& other)
- : var_(std::move(other))
- {
- }
-
- template <class ParentT>
- basic_json(const json_proxy<ParentT>& proxy, const Alloc& allocator = Alloc())
- : var_(proxy.evaluate().var_,allocator)
- {
- }
-
- template <typename T>
- basic_json(T val)
- : var_(null_type())
- {
- json_type_traits<value_type,T>::assign(*this,val);
- }
-
- basic_json(double val, uint8_t precision)
- : var_(val,precision)
- {
- }
-
- template <typename T>
- basic_json(T val, const Alloc& allocator)
- : var_(allocator)
- {
- json_type_traits<value_type,T>::assign(*this,val);
- }
-
- basic_json(const char_type *s, size_t length, const Alloc& allocator = Alloc())
- : var_(s, length, allocator)
- {
- }
- template<class InputIterator>
- basic_json(InputIterator first, InputIterator last, const Alloc& allocator = Alloc())
- : var_(first,last,allocator)
- {
- }
-
- ~basic_json()
- {
- }
-
- basic_json& operator=(const basic_json<CharT,Alloc>& rhs)
- {
- var_ = rhs.var_;
- return *this;
- }
-
- basic_json& operator=(basic_json<CharT,Alloc>&& rhs)
- {
- if (this != &rhs)
- {
- var_ = std::move(rhs.var_);
- }
- return *this;
- }
-
- basic_json& operator=(std::initializer_list<value_type> init)
- {
- basic_json<CharT,Alloc> val(init);
- swap(val);
- return *this;
- }
-
- template <class T>
- basic_json<CharT, Alloc>& operator=(T val)
- {
- json_type_traits<value_type,T>::assign(*this,val);
- return *this;
- }
-
- bool operator!=(const basic_json<CharT,Alloc>& rhs) const;
-
- bool operator==(const basic_json<CharT,Alloc>& rhs) const;
-
- size_t size() const JSONCONS_NOEXCEPT
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return 0;
- case value_types::object_t:
- return var_.value_.object_val_->size();
- case value_types::array_t:
- return var_.value_.array_val_->size();
- default:
- return 0;
- }
- }
-
- basic_json<CharT,Alloc>& operator[](size_t i)
- {
- return at(i);
- }
-
- const basic_json<CharT,Alloc>& operator[](size_t i) const
- {
- return at(i);
- }
-
- json_proxy<basic_json<CharT, Alloc>> operator[](const string_type& name)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- return json_proxy<basic_json<CharT,Alloc>>(*this, name);
- break;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an object");
- break;
- }
- }
-
- const basic_json<CharT,Alloc>& operator[](const string_type& name) const
- {
- return at(name);
- }
-
- string_type to_string(const string_allocator& allocator=string_allocator()) const JSONCONS_NOEXCEPT
- {
- string_type s(allocator);
- std::basic_ostringstream<char_type,char_traits_type,string_allocator> os(s);
- {
- basic_json_serializer<char_type> serializer(os);
- to_stream(serializer);
- }
- return os.str();
- }
-
- string_type to_string(const basic_output_format<char_type>& format,
- const string_allocator& allocator=string_allocator()) const
- {
- string_type s(allocator);
- std::basic_ostringstream<char_type> os(s);
- {
- basic_json_serializer<char_type> serializer(os, format);
- to_stream(serializer);
- }
- return os.str();
- }
-
- void to_stream(basic_json_output_handler<char_type>& handler) const
- {
- switch (var_.type_)
- {
- case value_types::small_string_t:
- handler.value(var_.value_.small_string_val_,var_.length_or_precision_);
- break;
- case value_types::string_t:
- handler.value(var_.value_.string_val_->data(),var_.value_.string_val_->length());
- break;
- case value_types::double_t:
- handler.value(var_.value_.double_val_, var_.length_or_precision_);
- break;
- case value_types::integer_t:
- handler.value(var_.value_.integer_val_);
- break;
- case value_types::uinteger_t:
- handler.value(var_.value_.uinteger_val_);
- break;
- case value_types::bool_t:
- handler.value(var_.value_.bool_val_);
- break;
- case value_types::null_t:
- handler.value(null_type());
- break;
- case value_types::empty_object_t:
- handler.begin_object();
- handler.end_object();
- break;
- case value_types::object_t:
- {
- handler.begin_object();
- object* o = var_.value_.object_val_;
- for (const_object_iterator it = o->begin(); it != o->end(); ++it)
- {
- handler.name((it->name()).data(),it->name().length());
- it->value().to_stream(handler);
- }
- handler.end_object();
- }
- break;
- case value_types::array_t:
- {
- handler.begin_array();
- array *o = var_.value_.array_val_;
- for (const_array_iterator it = o->begin(); it != o->end(); ++it)
- {
- it->to_stream(handler);
- }
- handler.end_array();
- }
- break;
- case value_types::any_t:
- var_.value_.any_val_->to_stream(handler);
- break;
- default:
- break;
- }
- }
-
- void to_stream(std::basic_ostream<char_type>& os) const
- {
- basic_json_serializer<char_type> serializer(os);
- to_stream(serializer);
- }
-
- void to_stream(std::basic_ostream<char_type>& os, const basic_output_format<char_type>& format) const
- {
- basic_json_serializer<char_type> serializer(os, format);
- to_stream(serializer);
- }
-
- void to_stream(std::basic_ostream<char_type>& os, const basic_output_format<char_type>& format, bool indenting) const
- {
- basic_json_serializer<char_type> serializer(os, format, indenting);
- to_stream(serializer);
- }
-
- bool is_null() const JSONCONS_NOEXCEPT
- {
- return var_.is_null();
- }
-
- size_t count(const string_type& name) const
- {
- switch (var_.type_)
- {
- case value_types::object_t:
- {
- auto it = var_.value_.object_val_->find(name.data(),name.length());
- if (it == members().end())
- {
- return 0;
- }
- size_t count = 0;
- while (it != members().end() && it->name() == name)
- {
- ++count;
- ++it;
- }
- return count;
- }
- break;
- default:
- return 0;
- }
- }
-
- template<typename T>
- bool is() const
- {
- return json_type_traits<value_type,T>::is(*this);
- }
-
- bool is_string() const JSONCONS_NOEXCEPT
- {
- return var_.is_string();
- }
-
-
- bool is_bool() const JSONCONS_NOEXCEPT
- {
- return var_.is_bool();
- }
-
- bool is_object() const JSONCONS_NOEXCEPT
- {
- return var_.type_ == value_types::object_t || var_.type_ == value_types::empty_object_t;
- }
-
- bool is_array() const JSONCONS_NOEXCEPT
- {
- return var_.type_ == value_types::array_t;
- }
-
- bool is_any() const JSONCONS_NOEXCEPT
- {
- return var_.type_ == value_types::any_t;
- }
-
- bool is_integer() const JSONCONS_NOEXCEPT
- {
- return var_.type_ == value_types::integer_t || (var_.type_ == value_types::uinteger_t && (as_uinteger() <= static_cast<unsigned long long>(std::numeric_limits<long long>::max JSONCONS_NO_MACRO_EXP())));
- }
-
- bool is_uinteger() const JSONCONS_NOEXCEPT
- {
- return var_.type_ == value_types::uinteger_t || (var_.type_ == value_types::integer_t && as_integer() >= 0);
- }
-
- bool is_double() const JSONCONS_NOEXCEPT
- {
- return var_.type_ == value_types::double_t;
- }
-
- bool is_number() const JSONCONS_NOEXCEPT
- {
- return var_.is_number();
- }
-
- bool empty() const JSONCONS_NOEXCEPT
- {
- return var_.empty();
- }
-
- size_t capacity() const
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- return var_.value_.array_val_->capacity();
- case value_types::object_t:
- return var_.value_.object_val_->capacity();
- default:
- return 0;
- }
- }
-
- template<class U=Alloc,
- typename std::enable_if<std::is_default_constructible<U>::value
- >::type* = nullptr>
- void create_object_implicitly()
- {
- var_.type_ = value_types::object_t;
- var_.value_.object_val_ = create_impl<object>(Alloc(),object_allocator(Alloc()));
- }
-
- template<class U=Alloc,
- typename std::enable_if<!std::is_default_constructible<U>::value
- >::type* = nullptr>
- void create_object_implicitly() const
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Cannot create_impl object implicitly - allocator is not default constructible.");
- }
-
- void reserve(size_t n)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->reserve(n);
- break;
- case value_types::empty_object_t:
- {
- create_object_implicitly();
- var_.value_.object_val_->reserve(n);
- }
- break;
- case value_types::object_t:
- {
- var_.value_.object_val_->reserve(n);
- }
- break;
- default:
- break;
- }
- }
-
- void resize(size_t n)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->resize(n);
- break;
- default:
- break;
- }
- }
-
- template <typename T>
- void resize(size_t n, T val)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->resize(n, val);
- break;
- default:
- break;
- }
- }
-
- template<typename T>
- T as() const
- {
- return json_type_traits<value_type,T>::as(*this);
- }
-
- template<typename T>
- typename std::enable_if<std::is_same<string_type,T>::value>::type as(const string_allocator& allocator) const
- {
- return json_type_traits<value_type,T>::as(*this,allocator);
- }
-
- bool as_bool() const JSONCONS_NOEXCEPT
- {
- switch (var_.type_)
- {
- case value_types::null_t:
- case value_types::empty_object_t:
- return false;
- case value_types::bool_t:
- return var_.value_.bool_val_;
- case value_types::double_t:
- return var_.value_.double_val_ != 0.0;
- case value_types::integer_t:
- return var_.value_.integer_val_ != 0;
- case value_types::uinteger_t:
- return var_.value_.uinteger_val_ != 0;
- case value_types::small_string_t:
- return var_.length_or_precision_ != 0;
- case value_types::string_t:
- return var_.value_.string_val_->length() != 0;
- case value_types::array_t:
- return var_.value_.array_val_->size() != 0;
- case value_types::object_t:
- return var_.value_.object_val_->size() != 0;
- case value_types::any_t:
- return true;
- default:
- return false;
- }
- }
-
- int64_t as_integer() const
- {
- switch (var_.type_)
- {
- case value_types::double_t:
- return static_cast<int64_t>(var_.value_.double_val_);
- case value_types::integer_t:
- return static_cast<int64_t>(var_.value_.integer_val_);
- case value_types::uinteger_t:
- return static_cast<int64_t>(var_.value_.uinteger_val_);
- case value_types::bool_t:
- return var_.value_.bool_val_ ? 1 : 0;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an integer");
- }
- }
-
- uint64_t as_uinteger() const
- {
- switch (var_.type_)
- {
- case value_types::double_t:
- return static_cast<uint64_t>(var_.value_.double_val_);
- case value_types::integer_t:
- return static_cast<uint64_t>(var_.value_.integer_val_);
- case value_types::uinteger_t:
- return static_cast<uint64_t>(var_.value_.uinteger_val_);
- case value_types::bool_t:
- return var_.value_.bool_val_ ? 1 : 0;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an unsigned integer");
- }
- }
-
- double as_double() const
- {
- switch (var_.type_)
- {
- case value_types::double_t:
- return var_.value_.double_val_;
- case value_types::integer_t:
- return static_cast<double>(var_.value_.integer_val_);
- case value_types::uinteger_t:
- return static_cast<double>(var_.value_.uinteger_val_);
- case value_types::null_t:
- return std::numeric_limits<double>::quiet_NaN();
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not a double");
- }
- }
-
- string_type as_string() const JSONCONS_NOEXCEPT
- {
- switch (var_.type_)
- {
- case value_types::small_string_t:
- return string_type(var_.value_.small_string_val_,var_.length_or_precision_);
- case value_types::string_t:
- return string_type(var_.value_.string_val_->data(),var_.value_.string_val_->length(),var_.value_.string_val_->get_allocator());
- default:
- return to_string();
- }
- }
-
- string_type as_string(const string_allocator& allocator) const JSONCONS_NOEXCEPT
- {
- switch (var_.type_)
- {
- case value_types::small_string_t:
- return string_type(var_.value_.small_string_val_,var_.length_or_precision_,allocator);
- case value_types::string_t:
- return string_type(var_.value_.string_val_->data(),var_.value_.string_val_->length(),allocator);
- default:
- return to_string(allocator);
- }
- }
-
- string_type as_string(const basic_output_format<char_type>& format) const
- {
- switch (var_.type_)
- {
- case value_types::small_string_t:
- return string_type(var_.value_.small_string_val_,var_.length_or_precision_);
- case value_types::string_t:
- return string_type(var_.value_.string_val_->data(),var_.value_.string_val_->length(),var_.value_.string_val_->get_allocator());
- default:
- return to_string(format);
- }
- }
-
- string_type as_string(const basic_output_format<char_type>& format,
- const string_allocator& allocator) const
- {
- switch (var_.type_)
- {
- case value_types::small_string_t:
- return string_type(var_.value_.small_string_val_,var_.length_or_precision_,allocator);
- case value_types::string_t:
- return string_type(var_.value_.string_val_->data(),var_.value_.string_val_->length(),allocator);
- default:
- return to_string(format,allocator);
- }
- }
-
- const char_type* as_cstring() const
- {
- switch (var_.type_)
- {
- case value_types::small_string_t:
- return var_.value_.small_string_val_;
- case value_types::string_t:
- return var_.value_.string_val_->c_str();
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not a cstring");
- }
- }
-
- any& any_value();
-
- const any& any_value() const;
-
- basic_json<CharT, Alloc>& at(const string_type& name)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- JSONCONS_THROW_EXCEPTION_1(std::out_of_range,"%s not found", name);
- case value_types::object_t:
- {
- auto it = var_.value_.object_val_->find(name.data(),name.length());
- if (it == members().end())
- {
- JSONCONS_THROW_EXCEPTION_1(std::out_of_range, "%s not found", name);
- }
- return it->value();
- }
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- basic_json<CharT, Alloc>& evaluate()
- {
- return *this;
- }
-
- basic_json<CharT, Alloc>& evaluate_with_default()
- {
- return *this;
- }
-
- const basic_json<CharT, Alloc>& evaluate() const
- {
- return *this;
- }
-
- basic_json<CharT, Alloc>& evaluate(size_t i)
- {
- return at(i);
- }
-
- const basic_json<CharT, Alloc>& evaluate(size_t i) const
- {
- return at(i);
- }
-
- basic_json<CharT, Alloc>& evaluate(const string_type& name)
- {
- return at(name);
- }
-
- const basic_json<CharT, Alloc>& evaluate(const string_type& name) const
- {
- return at(name);
- }
-
- const basic_json<CharT, Alloc>& at(const string_type& name) const
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- JSONCONS_THROW_EXCEPTION_1(std::out_of_range,"%s not found", name);
- case value_types::object_t:
- {
- auto it = var_.value_.object_val_->find(name.data(),name.length());
- if (it == members().end())
- {
- JSONCONS_THROW_EXCEPTION_1(std::out_of_range, "%s not found", name);
- }
- return it->value();
- }
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- basic_json<CharT, Alloc>& at(size_t i)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- if (i >= var_.value_.array_val_->size())
- {
- JSONCONS_THROW_EXCEPTION(std::out_of_range,"Invalid array subscript");
- }
- return var_.value_.array_val_->operator[](i);
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Index on non-array value not supported");
- }
- }
-
- const basic_json<CharT, Alloc>& at(size_t i) const
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- if (i >= var_.value_.array_val_->size())
- {
- JSONCONS_THROW_EXCEPTION(std::out_of_range,"Invalid array subscript");
- }
- return var_.value_.array_val_->operator[](i);
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Index on non-array value not supported");
- }
- }
-
- object_iterator find(const string_type& name)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return members().end();
- case value_types::object_t:
- return var_.value_.object_val_->find(name.data(),name.length());
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- const_object_iterator find(const string_type& name) const
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return members().end();
- case value_types::object_t:
- return var_.value_.object_val_->find(name.data(),name.length());
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- object_iterator find(const char_type* name)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return members().end();
- case value_types::object_t:
- return var_.value_.object_val_->find(name, std::char_traits<char_type>::length(name));
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- const_object_iterator find(const char_type* name) const
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return members().end();
- case value_types::object_t:
- return var_.value_.object_val_->find(name, std::char_traits<char_type>::length(name));
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- object_iterator find(const char_type* name, size_t length)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return members().end();
- case value_types::object_t:
- return var_.value_.object_val_->find(name, length);
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- const_object_iterator find(const char_type* name, size_t length) const
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return members().end();
- case value_types::object_t:
- return var_.value_.object_val_->find(name, length);
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- template<typename T>
- basic_json<CharT, Alloc> get(const string_type& name, T&& default_val) const
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- {
- return basic_json<CharT,Alloc>(std::forward<T>(default_val));
- }
- case value_types::object_t:
- {
- const_object_iterator it = var_.value_.object_val_->find(name.data(),name.length());
- if (it != members().end())
- {
- return it->value();
- }
- else
- {
- return basic_json<CharT,Alloc>(std::forward<T>(default_val));
- }
- }
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- // Modifiers
-
- void shrink_to_fit()
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->shrink_to_fit();
- break;
- case value_types::object_t:
- var_.value_.object_val_->shrink_to_fit();
- break;
- default:
- break;
- }
- }
-
- void clear()
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->clear();
- break;
- case value_types::object_t:
- var_.value_.object_val_->clear();
- break;
- default:
- break;
- }
- }
-
- void erase(object_iterator first, object_iterator last)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- break;
- case value_types::object_t:
- var_.value_.object_val_->erase(first, last);
- break;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an object");
- break;
- }
- }
-
- void erase(array_iterator first, array_iterator last)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->erase(first, last);
- break;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an array");
- break;
- }
- }
-
- // Removes all elements from an array value whose index is between from_index, inclusive, and to_index, exclusive.
-
- void erase(const string_type& name)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- break;
- case value_types::object_t:
- var_.value_.object_val_->erase(name.data(),name.length());
- break;
- default:
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object", name);
- break;
- }
- }
-
- void set(const string_type& name, const basic_json<CharT, Alloc>& value)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- var_.value_.object_val_->set(name, value);
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object", name);
- }
- }
- }
-
- void set(string_type&& name, const basic_json<CharT, Alloc>& value){
- switch (var_.type_){
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- var_.value_.object_val_->set(std::move(name),value);
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object",name);
- }
- }
- }
-
- void set(const string_type& name, basic_json<CharT, Alloc>&& value){
- switch (var_.type_){
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- var_.value_.object_val_->set(name,std::move(value));
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object",name);
- }
- }
- }
-
- void set(string_type&& name, basic_json<CharT, Alloc>&& value)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- var_.value_.object_val_->set(std::move(name),std::move(value));
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object",name);
- }
- }
- }
-
- object_iterator set(object_iterator hint, const string_type& name, const basic_json<CharT, Alloc>& value)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- return var_.value_.object_val_->set(hint, name, value);
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object", name);
- }
- }
- }
-
- object_iterator set(object_iterator hint, string_type&& name, const basic_json<CharT, Alloc>& value){
- switch (var_.type_){
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- return var_.value_.object_val_->set(hint, std::move(name),value);
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object",name);
- }
- }
- }
-
- object_iterator set(object_iterator hint, const string_type& name, basic_json<CharT, Alloc>&& value){
- switch (var_.type_){
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- return var_.value_.object_val_->set(hint, name,std::move(value));
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object",name);
- }
- }
- }
-
- object_iterator set(object_iterator hint, string_type&& name, basic_json<CharT, Alloc>&& value){
- switch (var_.type_){
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- return var_.value_.object_val_->set(hint, std::move(name),std::move(value));
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object",name);
- }
- }
- }
-
- void add(const basic_json<CharT, Alloc>& value)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->push_back(value);
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Attempting to insert into a value that is not an array");
- }
- }
- }
-
- void add(basic_json<CharT, Alloc>&& value){
- switch (var_.type_){
- case value_types::array_t:
- var_.value_.array_val_->push_back(std::move(value));
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Attempting to insert into a value that is not an array");
- }
- }
- }
-
- array_iterator add(const_array_iterator pos, const basic_json<CharT, Alloc>& value)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- return var_.value_.array_val_->add(pos, value);
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Attempting to insert into a value that is not an array");
- }
- }
- }
-
- array_iterator add(const_array_iterator pos, basic_json<CharT, Alloc>&& value){
- switch (var_.type_){
- case value_types::array_t:
- return var_.value_.array_val_->add(pos, std::move(value));
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Attempting to insert into a value that is not an array");
- }
- }
- }
-
- value_types type() const
- {
- return var_.type_;
- }
-
- uint8_t length_or_precision() const
- {
- return var_.length_or_precision_;
- }
-
- void swap(basic_json<CharT,Alloc>& b)
- {
- var_.swap(b.var_);
- }
-
- template <class T>
- std::vector<T> as_vector() const
- {
- std::vector<T> v(size());
- for (size_t i = 0; i < v.size(); ++i)
- {
- v[i] = json_type_traits<value_type,T>::as(at(i));
- }
- return v;
- }
-
- friend void swap(basic_json<CharT,Alloc>& a, basic_json<CharT,Alloc>& b)
- {
- a.swap(b);
- }
-
- void assign_any(const typename basic_json<CharT,Alloc>::any& rhs)
- {
- var_.assign(rhs);
- }
-
- void assign_string(const string_type& rhs)
- {
- var_.assign(rhs);
- }
-
- void assign_string(const char_type* rhs, size_t length)
- {
- var_.assign_string(rhs,length);
- }
-
- void assign_bool(bool rhs)
- {
- var_.assign(rhs);
- }
-
- void assign_object(const object & rhs)
- {
- var_.assign(rhs);
- }
-
- void assign_array(const array& rhs)
- {
- var_.assign(rhs);
- }
-
- void assign_null()
- {
- var_.assign(null_type());
- }
-
- template <typename T>
- const T& any_cast() const
- {
- if (var_.type_ != value_types::any_t)
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad any cast");
- }
- return var_.value_.any_val_->template cast<T>();
- }
- template <typename T>
- T& any_cast()
- {
- if (var_.type_ != value_types::any_t)
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad any cast");
- }
- return var_.value_.any_val_->template cast<T>();
- }
-
- void assign_integer(int64_t rhs)
- {
- var_.assign(rhs);
- }
-
- void assign_uinteger(uint64_t rhs)
- {
- var_.assign(rhs);
- }
-
- void assign_double(double rhs, uint8_t precision = 0)
- {
- var_.assign(rhs,precision);
- }
-
- static basic_json make_2d_array(size_t m, size_t n);
-
- template <typename T>
- static basic_json make_2d_array(size_t m, size_t n, T val);
-
- static basic_json make_3d_array(size_t m, size_t n, size_t k);
-
- template <typename T>
- static basic_json make_3d_array(size_t m, size_t n, size_t k, T val);
-
-#if !defined(JSONCONS_NO_DEPRECATED)
- typedef any json_any_type;
-
- static basic_json parse(std::basic_istream<char_type>& is)
- {
- return parse_stream(is);
- }
- static basic_json parse(std::basic_istream<char_type>& is, basic_parse_error_handler<char_type>& err_handler)
- {
- return parse_stream(is,err_handler);
- }
-
- static basic_json parse_string(const string_type& s)
- {
- return parse(s);
- }
-
- static basic_json parse_string(const string_type& s, basic_parse_error_handler<char_type>& err_handler)
- {
- return parse(s,err_handler);
- }
-
- void resize_array(size_t n)
- {
- resize(n);
- }
-
- template <typename T>
- void resize_array(size_t n, T val)
- {
- resize(n,val);
- }
-
- object_iterator begin_members()
- {
- return members().begin();
- }
-
- const_object_iterator begin_members() const
- {
- return members().begin();
- }
-
- object_iterator end_members()
- {
- return members().end();
- }
-
- const_object_iterator end_members() const
- {
- return members().end();
- }
-
- array_iterator begin_elements()
- {
- return elements().begin();
- }
-
- const_array_iterator begin_elements() const
- {
- return elements().begin();
- }
-
- array_iterator end_elements()
- {
- return elements().end();
- }
-
- const_array_iterator end_elements() const
- {
- return elements().end();
- }
-
- const basic_json<CharT,Alloc>& get(const string_type& name) const
- {
- static const basic_json<CharT, Alloc> a_null = null_type();
-
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return a_null;
- case value_types::object_t:
- {
- const_object_iterator it = var_.value_.object_val_->find(name.data(),name.length());
- return it != members().end() ? it->value() : a_null;
- }
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- bool is_longlong() const JSONCONS_NOEXCEPT
- {
- return var_.type_ == value_types::integer_t;
- }
-
- bool is_ulonglong() const JSONCONS_NOEXCEPT
- {
- return var_.type_ == value_types::uinteger_t;
- }
-
- long long as_longlong() const
- {
- return as_integer();
- }
-
- unsigned long long as_ulonglong() const
- {
- return as_uinteger();
- }
-
- int as_int() const
- {
- switch (var_.type_)
- {
- case value_types::double_t:
- return static_cast<int>(var_.value_.double_val_);
- case value_types::integer_t:
- return static_cast<int>(var_.value_.integer_val_);
- case value_types::uinteger_t:
- return static_cast<int>(var_.value_.uinteger_val_);
- case value_types::bool_t:
- return var_.value_.bool_val_ ? 1 : 0;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an int");
- }
- }
-
- unsigned int as_uint() const
- {
- switch (var_.type_)
- {
- case value_types::double_t:
- return static_cast<unsigned int>(var_.value_.double_val_);
- case value_types::integer_t:
- return static_cast<unsigned int>(var_.value_.integer_val_);
- case value_types::uinteger_t:
- return static_cast<unsigned int>(var_.value_.uinteger_val_);
- case value_types::bool_t:
- return var_.value_.bool_val_ ? 1 : 0;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an unsigned int");
- }
- }
-
- long as_long() const
- {
- switch (var_.type_)
- {
- case value_types::double_t:
- return static_cast<long>(var_.value_.double_val_);
- case value_types::integer_t:
- return static_cast<long>(var_.value_.integer_val_);
- case value_types::uinteger_t:
- return static_cast<long>(var_.value_.uinteger_val_);
- case value_types::bool_t:
- return var_.value_.bool_val_ ? 1 : 0;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not a long");
- }
- }
-
- unsigned long as_ulong() const
- {
- switch (var_.type_)
- {
- case value_types::double_t:
- return static_cast<unsigned long>(var_.value_.double_val_);
- case value_types::integer_t:
- return static_cast<unsigned long>(var_.value_.integer_val_);
- case value_types::uinteger_t:
- return static_cast<unsigned long>(var_.value_.uinteger_val_);
- case value_types::bool_t:
- return var_.value_.bool_val_ ? 1 : 0;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an unsigned long");
- }
- }
-
- void add(size_t index, const basic_json<CharT, Alloc>& value)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->add(index, value);
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Attempting to insert into a value that is not an array");
- }
- }
- }
-
- void add(size_t index, basic_json<CharT, Alloc>&& value){
- switch (var_.type_){
- case value_types::array_t:
- var_.value_.array_val_->add(index, std::move(value));
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Attempting to insert into a value that is not an array");
- }
- }
- }
-
- bool has_member(const string_type& name) const
- {
- switch (var_.type_)
- {
- case value_types::object_t:
- {
- const_object_iterator it = var_.value_.object_val_->find(name.data(),name.length());
- return it != members().end();
- }
- break;
- default:
- return false;
- }
- }
-
- void remove_range(size_t from_index, size_t to_index)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->remove_range(from_index, to_index);
- break;
- default:
- break;
- }
- }
- // Removes all elements from an array value whose index is between from_index, inclusive, and to_index, exclusive.
-
- void remove(const string_type& name)
- {
- erase(name.data(),name.length());
- }
- void remove_member(const string_type& name)
- {
- erase(name.data(),name.length());
- }
- // Removes a member from an object value
-
- bool is_empty() const JSONCONS_NOEXCEPT
- {
- return empty();
- }
- bool is_numeric() const JSONCONS_NOEXCEPT
- {
- return is_number();
- }
-
- void assign_longlong(long long rhs)
- {
- var_.assign(rhs);
- }
- void assign_ulonglong(unsigned long long rhs)
- {
- var_.assign(rhs);
- }
-
- template<int size>
- static typename std::enable_if<size==1,basic_json>::type make_multi_array()
- {
- return make_array();
- }
- template<size_t size>
- static typename std::enable_if<size==1,basic_json>::type make_multi_array(size_t n)
- {
- return make_array(n);
- }
- template<size_t size,typename T>
- static typename std::enable_if<size==1,basic_json>::type make_multi_array(size_t n, T val)
- {
- return make_array(n,val);
- }
- template<size_t size>
- static typename std::enable_if<size==2,basic_json>::type make_multi_array(size_t m, size_t n)
- {
- return make_array<2>(m, n);
- }
- template<size_t size,typename T>
- static typename std::enable_if<size==2,basic_json>::type make_multi_array(size_t m, size_t n, T val)
- {
- return make_array<2>(m, n, val);
- }
- template<size_t size>
- static typename std::enable_if<size==3,basic_json>::type make_multi_array(size_t m, size_t n, size_t k)
- {
- return make_array<3>(m, n, k);
- }
- template<size_t size,typename T>
- static typename std::enable_if<size==3,basic_json>::type make_multi_array(size_t m, size_t n, size_t k, T val)
- {
- return make_array<3>(m, n, k, val);
- }
-#endif
-
- object_range members()
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return object_range(object_iterator(true),object_iterator(true));
- case value_types::object_t:
- return object_range(object_value().begin(),object_value().end());
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an object");
- }
- }
-
- const_object_range members() const
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return const_object_range(const_object_iterator(true),const_object_iterator(true));
- case value_types::object_t:
- return const_object_range(object_value().begin(),object_value().end());
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an object");
- }
- }
-
- array_range elements()
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- return array_range(array_value().begin(),array_value().end());
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an array");
- }
- }
-
- const_array_range elements() const
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- return const_array_range(array_value().begin(),array_value().end());
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an array");
- }
- }
-
- array& array_value()
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- return *(var_.value_.array_val_);
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad array cast");
- break;
- }
- }
-
- const array& array_value() const
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- return *(var_.value_.array_val_);
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad array cast");
- break;
- }
- }
-
- object& object_value()
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- return *(var_.value_.object_val_);
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad object cast");
- break;
- }
- }
-
- const object& object_value() const
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- const_cast<value_type*>(this)->create_object_implicitly(); // HERE
- case value_types::object_t:
- return *(var_.value_.object_val_);
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad object cast");
- break;
- }
- }
-
-private:
-
- friend std::basic_ostream<typename string_type::value_type>& operator<<(std::basic_ostream<typename string_type::value_type>& os, const basic_json<CharT, Alloc>& o)
- {
- o.to_stream(os);
- return os;
- }
-
- friend std::basic_istream<typename string_type::value_type>& operator<<(std::basic_istream<typename string_type::value_type>& is, basic_json<CharT, Alloc>& o)
- {
- basic_json_deserializer<basic_json<CharT, Alloc>> handler;
- basic_json_reader<typename string_type::value_type> reader(is, handler);
- reader.read_next();
- reader.check_done();
- if (!handler.is_valid())
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Failed to parse json stream");
- }
- o = handler.get_result();
- return is;
- }
-};
-
-template <class JsonT>
-void swap(typename JsonT::member_type& a, typename JsonT::member_type& b)
-{
- a.swap(b);
-}
-
-template<typename CharT, typename Alloc>
-bool basic_json<CharT, Alloc>::operator!=(const basic_json<CharT, Alloc>& rhs) const
-{
- return !(*this == rhs);
-}
-
-template<typename CharT, typename Alloc>
-bool basic_json<CharT, Alloc>::operator==(const basic_json<CharT, Alloc>& rhs) const
-{
- return var_ == rhs.var_;
-}
-
-template<typename CharT, typename Alloc>
-basic_json<CharT, Alloc> basic_json<CharT, Alloc>::make_2d_array(size_t m, size_t n)
-{
- basic_json<CharT, Alloc> a = basic_json<CharT, Alloc>::array();
- a.resize(m);
- for (size_t i = 0; i < a.size(); ++i)
- {
- a[i] = basic_json<CharT, Alloc>::make_array(n);
- }
- return a;
-}
-
-template<typename CharT, typename Alloc>
-template<typename T>
-basic_json<CharT, Alloc> basic_json<CharT, Alloc>::make_2d_array(size_t m, size_t n, T val)
-{
- basic_json<CharT, Alloc> v;
- v = val;
- basic_json<CharT, Alloc> a = make_array(m);
- for (size_t i = 0; i < a.size(); ++i)
- {
- a[i] = basic_json<CharT, Alloc>::make_array(n, v);
- }
- return a;
-}
-
-template<typename CharT, typename Alloc>
-basic_json<CharT, Alloc> basic_json<CharT, Alloc>::make_3d_array(size_t m, size_t n, size_t k)
-{
- basic_json<CharT, Alloc> a = basic_json<CharT, Alloc>::array();
- a.resize(m);
- for (size_t i = 0; i < a.size(); ++i)
- {
- a[i] = basic_json<CharT, Alloc>::make_2d_array(n, k);
- }
- return a;
-}
-
-template<typename CharT, typename Alloc>
-template<typename T>
-basic_json<CharT, Alloc> basic_json<CharT, Alloc>::make_3d_array(size_t m, size_t n, size_t k, T val)
-{
- basic_json<CharT, Alloc> v;
- v = val;
- basic_json<CharT, Alloc> a = make_array(m);
- for (size_t i = 0; i < a.size(); ++i)
- {
- a[i] = basic_json<CharT, Alloc>::make_2d_array(n, k, v);
- }
- return a;
-}
-
-template<typename CharT, typename Alloc>
-basic_json<CharT, Alloc> basic_json<CharT, Alloc>::parse_stream(std::basic_istream<char_type>& is)
-{
- basic_json_deserializer<basic_json<CharT, Alloc>> handler;
- basic_json_reader<char_type> reader(is, handler);
- reader.read_next();
- reader.check_done();
- if (!handler.is_valid())
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Failed to parse json stream");
- }
- return handler.get_result();
-}
-
-template<typename CharT, typename Alloc>
-basic_json<CharT, Alloc> basic_json<CharT, Alloc>::parse_stream(std::basic_istream<char_type>& is,
- basic_parse_error_handler<char_type>& err_handler)
-{
- basic_json_deserializer<basic_json<CharT, Alloc>> handler;
- basic_json_reader<char_type> reader(is, handler, err_handler);
- reader.read_next();
- reader.check_done();
- if (!handler.is_valid())
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Failed to parse json stream");
- }
- return handler.get_result();
-}
-
-template<typename CharT, typename Alloc>
-basic_json<CharT, Alloc> basic_json<CharT, Alloc>::parse_file(const std::string& filename)
-{
- FILE* fp;
-
-#if defined(JSONCONS_HAS_FOPEN_S)
- errno_t err = fopen_s(&fp, filename.c_str(), "rb");
- if (err != 0)
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Cannot open file %s", filename);
- }
-#else
- fp = std::fopen(filename.c_str(), "rb");
- if (fp == nullptr)
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Cannot open file %s", filename);
- }
-#endif
- basic_json_deserializer<basic_json<CharT, Alloc>> handler;
- try
- {
- // obtain file size:
- std::fseek (fp , 0 , SEEK_END);
- long size = std::ftell (fp);
- std::rewind(fp);
-
- if (size > 0)
- {
- std::vector<char_type> buffer(size);
-
- // copy the file into the buffer:
- size_t result = std::fread (buffer.data(),1,size,fp);
- if (result != static_cast<unsigned long long>(size))
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Error reading file %s", filename);
- }
-
- basic_json_parser<char_type> parser(handler);
- parser.begin_parse();
- parser.parse(buffer.data(),0,buffer.size());
- parser.end_parse();
- parser.check_done(buffer.data(),parser.index(),buffer.size());
- }
-
- std::fclose (fp);
- }
- catch (...)
- {
- std::fclose (fp);
- throw;
- }
- if (!handler.is_valid())
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Failed to parse json file");
- }
- return handler.get_result();
-}
-
-template<typename CharT, typename Alloc>
-basic_json<CharT, Alloc> basic_json<CharT, Alloc>::parse_file(const std::string& filename,
- basic_parse_error_handler<char_type>& err_handler)
-{
- FILE* fp;
-
-#if !defined(JSONCONS_HAS_FOPEN_S)
- fp = std::fopen(filename.c_str(), "rb");
- if (fp == nullptr)
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Cannot open file %s", filename);
- }
-#else
- errno_t err = fopen_s(&fp, filename.c_str(), "rb");
- if (err != 0)
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Cannot open file %s", filename);
- }
-#endif
-
- basic_json_deserializer<basic_json<CharT, Alloc>> handler;
- try
- {
- // obtain file size:
- std::fseek (fp , 0 , SEEK_END);
- long size = std::ftell (fp);
- std::rewind(fp);
-
- if (size > 0)
- {
- std::vector<char_type> buffer(size);
-
- // copy the file into the buffer:
- size_t result = std::fread (buffer.data(),1,size,fp);
- if (result != static_cast<unsigned long long>(size))
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Error reading file %s", filename);
- }
-
- basic_json_parser<char_type> parser(handler,err_handler);
- parser.begin_parse();
- parser.parse(buffer.data(),0,buffer.size());
- parser.end_parse();
- parser.check_done(buffer.data(),parser.index(),buffer.size());
- }
-
- std::fclose (fp);
- }
- catch (...)
- {
- std::fclose (fp);
- throw;
- }
- if (!handler.is_valid())
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Failed to parse json file");
- }
- return handler.get_result();
-}
-
-template<typename CharT, typename Alloc>
-typename basic_json<CharT, Alloc>::any& basic_json<CharT, Alloc>::any_value()
-{
- switch (var_.type_)
- {
- case value_types::any_t:
- {
- return *var_.value_.any_val_;
- }
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an any value");
- }
-}
-
-template<typename CharT, typename Alloc>
-const typename basic_json<CharT, Alloc>::any& basic_json<CharT, Alloc>::any_value() const
-{
- switch (var_.type_)
- {
- case value_types::any_t:
- {
- return *var_.value_.any_val_;
- }
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an any value");
- }
-}
-
-template <typename JsonT>
-std::basic_istream<typename JsonT::char_type>& operator>>(std::basic_istream<typename JsonT::char_type>& is, JsonT& o)
-{
- basic_json_deserializer<JsonT> handler;
- basic_json_reader<typename JsonT::char_type> reader(is, handler);
- reader.read_next();
- reader.check_done();
- if (!handler.is_valid())
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Failed to parse json stream");
- }
- o = handler.get_result();
- return is;
-}
-
-template<typename JsonT>
-class json_printable
-{
-public:
- typedef typename JsonT::char_type char_type;
-
- json_printable(const JsonT& o,
- bool is_pretty_print)
- : o_(&o), is_pretty_print_(is_pretty_print)
- {
- }
-
- json_printable(const JsonT& o,
- bool is_pretty_print,
- const basic_output_format<char_type>& format)
- : o_(&o), is_pretty_print_(is_pretty_print), format_(format)
- {
- ;
- }
-
- void to_stream(std::basic_ostream<char_type>& os) const
- {
- o_->to_stream(os, format_, is_pretty_print_);
- }
-
- friend std::basic_ostream<char_type>& operator<<(std::basic_ostream<char_type>& os, const json_printable<JsonT>& o)
- {
- o.to_stream(os);
- return os;
- }
-
- const JsonT *o_;
- bool is_pretty_print_;
- basic_output_format<char_type> format_;
-private:
- json_printable();
-};
-
-template<typename JsonT>
-json_printable<JsonT> print(const JsonT& val)
-{
- return json_printable<JsonT>(val,false);
-}
-
-template<class JsonT>
-json_printable<JsonT> print(const JsonT& val,
- const basic_output_format<typename JsonT::char_type>& format)
-{
- return json_printable<JsonT>(val, false, format);
-}
-
-template<class JsonT>
-json_printable<JsonT> pretty_print(const JsonT& val)
-{
- return json_printable<JsonT>(val,true);
-}
-
-template<typename JsonT>
-json_printable<JsonT> pretty_print(const JsonT& val,
- const basic_output_format<typename JsonT::char_type>& format)
-{
- return json_printable<JsonT>(val, true, format);
-}
-
-typedef basic_json<char,std::allocator<char>> json;
-typedef basic_json<wchar_t,std::allocator<wchar_t>> wjson;
-
-typedef basic_json_deserializer<json> json_deserializer;
-typedef basic_json_deserializer<wjson> wjson_deserializer;
-
-}
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
-
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons/json_deserializer.hpp b/vendor/jsoncons-0.99.2/jsoncons/json_deserializer.hpp
deleted file mode 100644
index 31cd0db9..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/json_deserializer.hpp
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright 2013-2016 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_JSON_DESERIALIZER_HPP
-#define JSONCONS_JSON_DESERIALIZER_HPP
-
-#include <string>
-#include <sstream>
-#include <vector>
-#include <istream>
-#include <cstdlib>
-#include <memory>
-#include "jsoncons/jsoncons.hpp"
-#include "jsoncons/json_input_handler.hpp"
-
-namespace jsoncons {
-
-template <class JsonT>
-class basic_json_deserializer : public basic_json_input_handler<typename JsonT::char_type>
-{
- static const int default_stack_size = 1000;
-
- typedef typename JsonT::char_type char_type;
- typedef typename JsonT::member_type member_type;
- typedef typename JsonT::string_type string_type;
- typedef typename string_type::allocator_type string_allocator;
- typedef typename JsonT::allocator_type allocator_type;
- typedef typename JsonT::array array;
- typedef typename array::allocator_type array_allocator;
- typedef typename JsonT::object object;
- typedef typename object::allocator_type object_allocator;
- typedef typename JsonT::value_type value_type;
-
- string_allocator sa_;
- object_allocator oa_;
- array_allocator aa_;
-
- JsonT result_;
- size_t top_;
-
- struct stack_item
- {
- string_type name_;
- value_type value_;
- };
- std::vector<stack_item> stack_;
- std::vector<size_t> stack2_;
- bool is_valid_;
-
-public:
- basic_json_deserializer(const string_allocator& sa = string_allocator(),
- const allocator_type& allocator = allocator_type())
- : sa_(sa),
- oa_(allocator),
- aa_(allocator),
- top_(0),
- stack_(default_stack_size),
- stack2_(),
- is_valid_(true) // initial json value is an empty object
-
- {
- stack2_.reserve(100);
- }
-
- bool is_valid() const
- {
- return is_valid_;
- }
-
- JsonT get_result()
- {
- is_valid_ = false;
- return std::move(result_);
- }
-
-#if !defined(JSONCONS_NO_DEPRECATED)
- JsonT& root()
- {
- return result_;
- }
-#endif
-
-private:
-
- void push_initial()
- {
- top_ = 0;
- if (top_ >= stack_.size())
- {
- stack_.resize(top_*2);
- }
- }
-
- void pop_initial()
- {
- JSONCONS_ASSERT(top_ == 1);
- result_.swap(stack_[0].value_);
- --top_;
- }
-
- void push_object()
- {
- stack2_.push_back(top_);
- stack_[top_].value_ = object(oa_);
- if (++top_ >= stack_.size())
- {
- stack_.resize(top_*2);
- }
- }
-
- void pop_object()
- {
- stack2_.pop_back();
- JSONCONS_ASSERT(top_ > 0);
- }
-
- void push_array()
- {
- stack2_.push_back(top_);
- stack_[top_].value_ = array(aa_);
- if (++top_ >= stack_.size())
- {
- stack_.resize(top_*2);
- }
- }
-
- void pop_array()
- {
- stack2_.pop_back();
- JSONCONS_ASSERT(top_ > 0);
- }
-
- void do_begin_json() override
- {
- is_valid_ = false;
- push_initial();
- }
-
- void do_end_json() override
- {
- is_valid_ = true;
- pop_initial();
- }
-
- void do_begin_object(const basic_parsing_context<char_type>&) override
- {
- push_object();
- }
-
- void do_end_object(const basic_parsing_context<char_type>&) override
- {
- end_structure();
- pop_object();
- }
-
- void do_begin_array(const basic_parsing_context<char_type>&) override
- {
- push_array();
- }
-
- void do_end_array(const basic_parsing_context<char_type>&) override
- {
- end_structure();
- pop_array();
- }
-
- static member_type move_pair(stack_item&& val)
- {
- return member_type(std::move(val.name_),std::move(val.value_));
- }
-
- void end_structure()
- {
- JSONCONS_ASSERT(stack2_.size() > 0);
- if (stack_[stack2_.back()].value_.is_object())
- {
- size_t count = top_ - (stack2_.back() + 1);
- auto s = stack_.begin() + (stack2_.back()+1);
- auto send = s + count;
- stack_[stack2_.back()].value_.object_value().insert(
- std::make_move_iterator(s),
- std::make_move_iterator(send),
- move_pair);
- top_ -= count;
- }
- else
- {
- size_t count = top_ - (stack2_.back() + 1);
- stack_[stack2_.back()].value_.resize(count);
-
- auto s = stack_.begin() + (stack2_.back()+1);
- auto dend = stack_[stack2_.back()].value_.elements().end();
- for (auto it = stack_[stack2_.back()].value_.elements().begin();
- it != dend; ++it, ++s)
- {
- *it = std::move(s->value_);
- }
- top_ -= count;
- }
- }
-
- void do_name(const char_type* p, size_t length, const basic_parsing_context<char_type>&) override
- {
- stack_[top_].name_ = string_type(p,length,sa_);
- }
-
- void do_string_value(const char_type* p, size_t length, const basic_parsing_context<char_type>&) override
- {
- stack_[top_].value_ = JsonT(p,length,sa_);
- if (++top_ >= stack_.size())
- {
- stack_.resize(top_*2);
- }
- }
-
- void do_integer_value(int64_t value, const basic_parsing_context<char_type>&) override
- {
- stack_[top_].value_ = value;
- if (++top_ >= stack_.size())
- {
- stack_.resize(top_*2);
- }
- }
-
- void do_uinteger_value(uint64_t value, const basic_parsing_context<char_type>&) override
- {
- stack_[top_].value_ = value;
- if (++top_ >= stack_.size())
- {
- stack_.resize(top_*2);
- }
- }
-
- void do_double_value(double value, uint8_t precision, const basic_parsing_context<char_type>&) override
- {
- stack_[top_].value_ = value_type(value,precision);
- if (++top_ >= stack_.size())
- {
- stack_.resize(top_*2);
- }
- }
-
- void do_bool_value(bool value, const basic_parsing_context<char_type>&) override
- {
- stack_[top_].value_ = value;
- if (++top_ >= stack_.size())
- {
- stack_.resize(top_*2);
- }
- }
-
- void do_null_value(const basic_parsing_context<char_type>&) override
- {
- stack_[top_].value_ = null_type();
- if (++top_ >= stack_.size())
- {
- stack_.resize(top_*2);
- }
- }
-};
-
-}
-
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons/json_filter.hpp b/vendor/jsoncons-0.99.2/jsoncons/json_filter.hpp
deleted file mode 100644
index 2019c01d..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/json_filter.hpp
+++ /dev/null
@@ -1,324 +0,0 @@
-// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_JSON_FILTER_HPP
-#define JSONCONS_JSON_FILTER_HPP
-
-#include <string>
-
-#include "jsoncons/json_input_handler.hpp"
-#include "jsoncons/json_output_handler.hpp"
-#include "jsoncons/parse_error_handler.hpp"
-
-namespace jsoncons {
-
-template <typename CharT>
-class basic_json_input_output_adapter : public basic_json_input_handler<CharT>
-{
-public:
- basic_json_input_output_adapter()
- : writer_(std::addressof(null_json_output_handler<CharT>()))
- {
- }
-
- basic_json_input_output_adapter(basic_json_output_handler<CharT>& handler)
- : writer_(std::addressof(handler))
- {
- }
-
-private:
-
- void do_begin_json() override
- {
- writer_->begin_json();
- }
-
- void do_end_json() override
- {
- writer_->end_json();
- }
-
- void do_begin_object(const basic_parsing_context<CharT>& context) override
- {
- writer_->begin_object();
- }
-
- void do_end_object(const basic_parsing_context<CharT>& context) override
- {
- writer_->end_object();
- }
-
- void do_begin_array(const basic_parsing_context<CharT>& context) override
- {
- writer_->begin_array();
- }
-
- void do_end_array(const basic_parsing_context<CharT>& context) override
- {
- writer_->end_array();
- }
-
- void do_name(const CharT* name, size_t length,
- const basic_parsing_context<CharT>& context) override
- {
- writer_->name(name, length);
- }
-
- void do_string_value(const CharT* value, size_t length,
- const basic_parsing_context<CharT>& context) override
- {
- writer_->value(value, length);
- }
-
- void do_integer_value(int64_t value, const basic_parsing_context<CharT>& context) override
- {
- writer_->value(value);
- }
-
- void do_uinteger_value(uint64_t value,
- const basic_parsing_context<CharT>& context) override
- {
- writer_->value(value);
- }
-
- void do_double_value(double value, uint8_t precision, const basic_parsing_context<CharT>& context) override
- {
- writer_->value(value, precision);
- }
-
- void do_bool_value(bool value, const basic_parsing_context<CharT>& context) override
- {
- writer_->value(value);
- }
-
- void do_null_value(const basic_parsing_context<CharT>& context) override
- {
- writer_->value(null_type());
- }
-
- basic_json_output_handler<CharT>* writer_;
-};
-
-template <typename CharT>
-class basic_json_filter : public basic_json_input_handler<CharT>
-{
-public:
- basic_json_filter(basic_json_input_handler<CharT>& handler)
- : handler_(std::addressof(handler)),
- err_handler_(std::addressof(basic_default_parse_error_handler<CharT>::instance()))
- {
- }
-
- basic_json_filter(basic_json_input_handler<CharT>& handler,
- basic_parse_error_handler<CharT>& err_handler)
- : handler_(std::addressof(handler)),
- err_handler_(std::addressof(err_handler))
- {
- }
-
- basic_json_filter(basic_json_output_handler<CharT>& output_handler)
- : input_output_adapter_(output_handler), handler_(std::addressof(input_output_adapter_)),
- err_handler_(std::addressof(basic_default_parse_error_handler<CharT>::instance()))
- {
- }
-
- basic_json_filter(basic_json_output_handler<CharT>& output_handler,
- basic_parse_error_handler<CharT>& err_handler)
- : input_output_adapter_(output_handler), handler_(std::addressof(input_output_adapter_)),
- err_handler_(std::addressof(err_handler))
- {
- }
-
- basic_json_input_handler<CharT>& input_handler()
- {
- return *handler_;
- }
-
-#if !defined(JSONCONS_NO_DEPRECATED)
- basic_json_input_handler<CharT>& parent()
- {
- return *handler_;
- }
-#endif
-
-private:
- void do_begin_json() override
- {
- handler_->begin_json();
- }
-
- void do_end_json() override
- {
- handler_->end_json();
- }
-
- void do_begin_object(const basic_parsing_context<CharT>& context) override
- {
- handler_->begin_object(context);
- }
-
- void do_end_object(const basic_parsing_context<CharT>& context) override
- {
- handler_->end_object(context);
- }
-
- void do_begin_array(const basic_parsing_context<CharT>& context) override
- {
- handler_->begin_array(context);
- }
-
- void do_end_array(const basic_parsing_context<CharT>& context) override
- {
- handler_->end_array(context);
- }
-
- void do_name(const CharT* name, size_t length, const basic_parsing_context<CharT>& context) override
- {
- handler_->name(name, length, context);
- }
-
- void do_string_value(const CharT* value, size_t length, const basic_parsing_context<CharT>& context) override
- {
- handler_->value(value,length,context);
- }
-
- void do_double_value(double value, uint8_t precision, const basic_parsing_context<CharT>& context) override
- {
- handler_->value(value,precision,context);
- }
-
- void do_integer_value(int64_t value, const basic_parsing_context<CharT>& context) override
- {
- handler_->value(value,context);
- }
-
- void do_uinteger_value(uint64_t value, const basic_parsing_context<CharT>& context) override
- {
- handler_->value(value,context);
- }
-
- void do_bool_value(bool value, const basic_parsing_context<CharT>& context) override
- {
- handler_->value(value,context);
- }
-
- void do_null_value(const basic_parsing_context<CharT>& context) override
- {
- handler_->value(null_type(),context);
- }
-
- basic_json_input_output_adapter<CharT> input_output_adapter_;
- basic_json_input_handler<CharT>* handler_;
- basic_parse_error_handler<CharT>* err_handler_;
-};
-
-// Filters out begin_json and end_json events
-template <typename CharT>
-class basic_begin_end_json_filter : public basic_json_filter<CharT>
-{
-public:
- basic_begin_end_json_filter(basic_json_input_handler<CharT>& handler)
- : basic_json_filter<CharT>(handler)
- {
- }
-private:
- void do_begin_json() override
- {
- }
-
- void do_end_json() override
- {
- }
-};
-
-template <typename CharT>
-class basic_json_output_input_adapter : public basic_json_output_handler<CharT>
-{
-public:
- basic_json_output_input_adapter(basic_json_input_handler<CharT>& input_handler,
- const basic_parsing_context<CharT>& context)
- : input_handler_(std::addressof(input_handler)),
- context_(std::addressof(context))
- {
- }
-
-private:
-
- void do_begin_json() override
- {
- input_handler_->begin_json();
- }
-
- void do_end_json() override
- {
- input_handler_->end_json();
- }
-
- void do_begin_object() override
- {
- input_handler_->begin_object(*context_);
- }
-
- void do_end_object() override
- {
- input_handler_->end_object(*context_);
- }
-
- void do_begin_array() override
- {
- input_handler_->begin_array(*context_);
- }
-
- void do_end_array() override
- {
- input_handler_->end_array(*context_);
- }
-
- void do_name(const CharT* name, size_t length) override
- {
- input_handler_->name(name, length, *context_);
- }
-
- void do_string_value(const CharT* value, size_t length) override
- {
- input_handler_->value(value, length, *context_);
- }
-
- void do_integer_value(int64_t value) override
- {
- input_handler_->value(value, *context_);
- }
-
- void do_uinteger_value(uint64_t value) override
- {
- input_handler_->value(value, *context_);
- }
-
- void do_double_value(double value, uint8_t precision) override
- {
- input_handler_->value(value, precision, *context_);
- }
-
- void do_bool_value(bool value) override
- {
- input_handler_->value(value, *context_);
- }
-
- void do_null_value() override
- {
- input_handler_->value(null_type(), *context_);
- }
-
- basic_json_input_handler<CharT>* input_handler_;
- const basic_parsing_context<CharT>* context_;
-};
-
-typedef basic_json_filter<char> json_filter;
-typedef basic_json_filter<wchar_t> wjson_filter;
-
-}
-
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons/json_input_handler.hpp b/vendor/jsoncons-0.99.2/jsoncons/json_input_handler.hpp
deleted file mode 100644
index 566209e5..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/json_input_handler.hpp
+++ /dev/null
@@ -1,282 +0,0 @@
-// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_JSON_INPUT_HANDLER_HPP
-#define JSONCONS_JSON_INPUT_HANDLER_HPP
-
-#include <string>
-#include "jsoncons/jsoncons.hpp"
-
-namespace jsoncons {
-
-template<typename CharT>
-uint64_t string_to_uinteger(const CharT *s, size_t length) throw(std::overflow_error)
-{
- static const uint64_t max_value = std::numeric_limits<uint64_t>::max JSONCONS_NO_MACRO_EXP();
- static const uint64_t max_value_div_10 = max_value / 10;
- uint64_t n = 0;
- for (size_t i = 0; i < length; ++i)
- {
- uint64_t x = s[i] - '0';
- if (n > max_value_div_10)
- {
- throw std::overflow_error("Unsigned overflow");
- }
- n = n * 10;
- if (n > max_value - x)
- {
- throw std::overflow_error("Unsigned overflow");
- }
-
- n += x;
- }
- return n;
-}
-
-template<typename CharT>
-int64_t string_to_integer(bool has_neg, const CharT *s, size_t length) throw(std::overflow_error)
-{
- const long long max_value = std::numeric_limits<int64_t>::max JSONCONS_NO_MACRO_EXP();
- const long long max_value_div_10 = max_value / 10;
-
- long long n = 0;
- for (size_t i = 0; i < length; ++i)
- {
- long long x = s[i] - '0';
- if (n > max_value_div_10)
- {
- throw std::overflow_error("Integer overflow");
- }
- n = n * 10;
- if (n > max_value - x)
- {
- throw std::overflow_error("Integer overflow");
- }
-
- n += x;
- }
- return has_neg ? -n : n;
-}
-
-template <typename CharT>
-class basic_parsing_context;
-
-template <typename CharT>
-class basic_json_input_handler
-{
-public:
- virtual ~basic_json_input_handler() {}
-
- void begin_json()
- {
- do_begin_json();
- }
-
- void end_json()
- {
- do_end_json();
- }
-
- void begin_object(const basic_parsing_context<CharT>& context)
- {
- do_begin_object(context);
- }
-
- void end_object(const basic_parsing_context<CharT>& context)
- {
- do_end_object(context);
- }
-
- void begin_array(const basic_parsing_context<CharT>& context)
- {
- do_begin_array(context);
- }
-
- void end_array(const basic_parsing_context<CharT>& context)
- {
- do_end_array(context);
- }
-
- void name(const std::basic_string<CharT>& name, const basic_parsing_context<CharT>& context)
- {
- do_name(name.data(), name.length(), context);
- }
-
- void name(const CharT* p, size_t length, const basic_parsing_context<CharT>& context)
- {
- do_name(p, length, context);
- }
-
- void value(const std::basic_string<CharT>& value, const basic_parsing_context<CharT>& context)
- {
- do_string_value(value.data(), value.length(), context);
- }
-
- void value(const CharT* p, size_t length, const basic_parsing_context<CharT>& context)
- {
- do_string_value(p, length, context);
- }
-
- void value(const CharT* p, const basic_parsing_context<CharT>& context)
- {
- do_string_value(p, std::char_traits<CharT>::length(p), context);
- }
-
- void value(int value, const basic_parsing_context<CharT>& context)
- {
- do_integer_value(value,context);
- }
-
- void value(long value, const basic_parsing_context<CharT>& context)
- {
- do_integer_value(value,context);
- }
-
- void value(long long value, const basic_parsing_context<CharT>& context)
- {
- do_integer_value(value,context);
- }
-
- void value(unsigned int value, const basic_parsing_context<CharT>& context)
- {
- do_uinteger_value(value,context);
- }
-
- void value(unsigned long value, const basic_parsing_context<CharT>& context)
- {
- do_uinteger_value(value,context);
- }
-
- void value(unsigned long long value, const basic_parsing_context<CharT>& context)
- {
- do_uinteger_value(value,context);
- }
-
- void value(float value, uint8_t precision, const basic_parsing_context<CharT>& context)
- {
- do_double_value(value, precision, context);
- }
-
- void value(double value, uint8_t precision, const basic_parsing_context<CharT>& context)
- {
- do_double_value(value, precision, context);
- }
-
- void value(bool value, const basic_parsing_context<CharT>& context)
- {
- do_bool_value(value,context);
- }
-
- void value(null_type, const basic_parsing_context<CharT>& context)
- {
- do_null_value(context);
- }
-
-private:
- virtual void do_begin_json() = 0;
-
- virtual void do_end_json() = 0;
-
- virtual void do_begin_object(const basic_parsing_context<CharT>& context) = 0;
-
- virtual void do_end_object(const basic_parsing_context<CharT>& context) = 0;
-
- virtual void do_begin_array(const basic_parsing_context<CharT>& context) = 0;
-
- virtual void do_end_array(const basic_parsing_context<CharT>& context) = 0;
-
- virtual void do_name(const CharT* name, size_t length, const basic_parsing_context<CharT>& context) = 0;
-
- virtual void do_null_value(const basic_parsing_context<CharT>& context) = 0;
-
- virtual void do_string_value(const CharT* value, size_t length, const basic_parsing_context<CharT>& context) = 0;
-
- virtual void do_double_value(double value, uint8_t precision, const basic_parsing_context<CharT>& context) = 0;
-
- virtual void do_integer_value(int64_t value, const basic_parsing_context<CharT>& context) = 0;
-
- virtual void do_uinteger_value(uint64_t value, const basic_parsing_context<CharT>& context) = 0;
-
- virtual void do_bool_value(bool value, const basic_parsing_context<CharT>& context) = 0;
-};
-
-
-template <typename CharT>
-class basic_empty_json_input_handler : public basic_json_input_handler<CharT>
-{
-public:
- static basic_json_input_handler<CharT>& instance()
- {
- static basic_empty_json_input_handler<CharT> instance;
- return instance;
- }
-private:
- void do_begin_json() override
- {
- }
-
- void do_end_json() override
- {
- }
-
- void do_begin_object(const basic_parsing_context<CharT>&) override
- {
- }
-
- void do_end_object(const basic_parsing_context<CharT>&) override
- {
- }
-
- void do_begin_array(const basic_parsing_context<CharT>&) override
- {
- }
-
- void do_end_array(const basic_parsing_context<CharT>&) override
- {
- }
-
- void do_name(const CharT* p, size_t length, const basic_parsing_context<CharT>&) override
- {
- (void)p;
- (void)length;
- }
-
- void do_null_value(const basic_parsing_context<CharT>&) override
- {
- }
-
- void do_string_value(const CharT* p, size_t length, const basic_parsing_context<CharT>&) override
- {
- (void)p;
- (void)length;
- }
-
- void do_double_value(double, uint8_t, const basic_parsing_context<CharT>&) override
- {
- }
-
- void do_integer_value(int64_t, const basic_parsing_context<CharT>&) override
- {
- }
-
- void do_uinteger_value(uint64_t, const basic_parsing_context<CharT>&) override
- {
- }
-
- void do_bool_value(bool, const basic_parsing_context<CharT>&) override
- {
- }
-};
-
-typedef basic_json_input_handler<char> json_input_handler;
-typedef basic_json_input_handler<wchar_t> wjson_input_handler;
-
-typedef basic_empty_json_input_handler<char> empty_json_input_handler;
-typedef basic_empty_json_input_handler<wchar_t> wempty_json_input_handler;
-
-}
-
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons/json_parser.hpp b/vendor/jsoncons-0.99.2/jsoncons/json_parser.hpp
deleted file mode 100644
index 8a06c2e7..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/json_parser.hpp
+++ /dev/null
@@ -1,1587 +0,0 @@
-// Copyright 2015 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_JSON_PARSER_HPP
-#define JSONCONS_JSON_PARSER_HPP
-
-#include <memory>
-#include <string>
-#include <sstream>
-#include <vector>
-#include <istream>
-#include <cstdlib>
-#include <stdexcept>
-#include <system_error>
-#include "jsoncons/jsoncons.hpp"
-#include "jsoncons/json_input_handler.hpp"
-#include "jsoncons/parse_error_handler.hpp"
-#include "jsoncons/json_error_category.hpp"
-
-namespace jsoncons {
-
-enum class states
-{
- root,
- start,
- slash,
- slash_slash,
- slash_star,
- slash_star_star,
- expect_comma_or_end,
- object,
- expect_member_name_or_end,
- expect_member_name,
- expect_colon,
- expect_value_or_end,
- expect_value,
- array,
- string,
- member_name,
- escape,
- u1,
- u2,
- u3,
- u4,
- expect_surrogate_pair1,
- expect_surrogate_pair2,
- u6,
- u7,
- u8,
- u9,
- minus,
- zero,
- integer,
- fraction,
- exp1,
- exp2,
- exp3,
- n,
- t,
- f,
- cr,
- lf,
- done
-};
-
-template<typename CharT>
-class basic_json_parser : private basic_parsing_context<CharT>
-{
- static const int default_initial_stack_capacity_ = 100;
-
- std::vector<states> stack_;
- basic_json_input_handler<CharT> *handler_;
- basic_parse_error_handler<CharT> *err_handler_;
- size_t column_;
- size_t line_;
- uint32_t cp_;
- uint32_t cp2_;
- std::basic_string<CharT> string_buffer_;
- std::basic_string<char> number_buffer_;
- bool is_negative_;
- size_t index_;
- int initial_stack_capacity_;
- int nesting_depth_;
- int max_depth_;
- float_reader float_reader_;
- const CharT* begin_input_;
- const CharT* end_input_;
- const CharT* p_;
- uint8_t precision_;
- std::pair<const CharT*,size_t> literal_;
- size_t literal_index_;
-
-public:
- basic_json_parser(basic_json_input_handler<CharT>& handler)
- : handler_(std::addressof(handler)),
- err_handler_(std::addressof(basic_default_parse_error_handler<CharT>::instance())),
- column_(0),
- line_(0),
- cp_(0),
- is_negative_(false),
- index_(0),
- initial_stack_capacity_(default_initial_stack_capacity_)
- {
- max_depth_ = std::numeric_limits<int>::max JSONCONS_NO_MACRO_EXP();
- }
-
- basic_json_parser(basic_json_input_handler<CharT>& handler,
- basic_parse_error_handler<CharT>& err_handler)
- : handler_(std::addressof(handler)),
- err_handler_(std::addressof(err_handler)),
- column_(0),
- line_(0),
- cp_(0),
- is_negative_(false),
- index_(0),
- initial_stack_capacity_(default_initial_stack_capacity_)
-
- {
- max_depth_ = std::numeric_limits<int>::max JSONCONS_NO_MACRO_EXP();
- }
-
- const basic_parsing_context<CharT>& parsing_context() const
- {
- return *this;
- }
-
- ~basic_json_parser()
- {
- }
-
- size_t max_nesting_depth() const
- {
- return static_cast<size_t>(max_depth_);
- }
-
- void max_nesting_depth(size_t max_nesting_depth)
- {
- max_depth_ = static_cast<int>(std::min(max_nesting_depth,static_cast<size_t>(std::numeric_limits<int>::max JSONCONS_NO_MACRO_EXP())));
- }
-
- states parent() const
- {
- return stack_[stack_.size()-2];
- }
-
- bool done() const
- {
- return stack_.back() == states::done;
- }
-
- void do_space()
- {
- while ((p_ + 1) < end_input_ && (*(p_ + 1) == ' ' || *(p_ + 1) == '\t'))
- {
- ++p_;
- ++column_;
- }
- }
-
- void do_begin_object()
- {
- if (++nesting_depth_ >= max_depth_)
- {
- err_handler_->error(std::error_code(json_parser_errc::max_depth_exceeded, json_error_category()), *this);
- }
- stack_.back() = states::object;
- stack_.push_back(states::expect_member_name_or_end);
- handler_->begin_object(*this);
- }
-
- void do_end_object()
- {
- --nesting_depth_;
- JSONCONS_ASSERT(!stack_.empty())
- stack_.pop_back();
- if (stack_.back() == states::object)
- {
- handler_->end_object(*this);
- }
- else if (stack_.back() == states::array)
- {
- err_handler_->fatal_error(std::error_code(json_parser_errc::expected_comma_or_right_bracket, json_error_category()), *this);
- }
- else
- {
- err_handler_->fatal_error(std::error_code(json_parser_errc::unexpected_right_brace, json_error_category()), *this);
- }
-
- JSONCONS_ASSERT(stack_.size() >= 2);
- if (parent() == states::root)
- {
- stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- stack_.back() = states::expect_comma_or_end;
- }
- }
-
- void do_begin_array()
- {
- if (++nesting_depth_ >= max_depth_)
- {
- err_handler_->error(std::error_code(json_parser_errc::max_depth_exceeded, json_error_category()), *this);
- }
- stack_.back() = states::array;
- stack_.push_back(states::expect_value_or_end);
- handler_->begin_array(*this);
- }
-
- void do_end_array()
- {
- --nesting_depth_;
- JSONCONS_ASSERT(!stack_.empty())
- stack_.pop_back();
- if (stack_.back() == states::array)
- {
- handler_->end_array(*this);
- }
- else if (stack_.back() == states::object)
- {
- err_handler_->fatal_error(std::error_code(json_parser_errc::expected_comma_or_right_brace, json_error_category()), *this);
- }
- else
- {
- err_handler_->fatal_error(std::error_code(json_parser_errc::unexpected_right_bracket, json_error_category()), *this);
- }
- JSONCONS_ASSERT(stack_.size() >= 2);
- if (parent() == states::root)
- {
- stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- stack_.back() = states::expect_comma_or_end;
- }
- }
-
- void begin_parse()
- {
- stack_.clear();
- stack_.reserve(initial_stack_capacity_);
- stack_.push_back(states::root);
- stack_.push_back(states::start);
- line_ = 1;
- column_ = 1;
- nesting_depth_ = 0;
- }
-
- void check_done(const CharT* input, size_t start, size_t length)
- {
- index_ = start;
- for (; index_ < length; ++index_)
- {
- CharT curr_char_ = input[index_];
- switch (curr_char_)
- {
- case '\n':
- case '\r':
- case '\t':
- case ' ':
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::extra_character, json_error_category()), *this);
- break;
- }
- }
- }
-
- void parse_string()
- {
- const CharT* sb = p_;
- bool done = false;
- while (!done && p_ < end_input_)
- {
- switch (*p_)
- {
- case 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06:case 0x07:case 0x08:case 0x0b:
- case 0x0c:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12:case 0x13:case 0x14:case 0x15:case 0x16:
- case 0x17:case 0x18:case 0x19:case 0x1a:case 0x1b:case 0x1c:case 0x1d:case 0x1e:case 0x1f:
- string_buffer_.append(sb,p_-sb);
- column_ += (p_ - sb + 1);
- err_handler_->error(std::error_code(json_parser_errc::illegal_control_character, json_error_category()), *this);
- // recovery - skip
- done = true;
- ++p_;
- break;
- case '\r':
- {
- column_ += (p_ - sb + 1);
- err_handler_->error(std::error_code(json_parser_errc::illegal_character_in_string, json_error_category()), *this);
- // recovery - keep
- string_buffer_.append(sb, p_ - sb + 1);
- stack_.push_back(states::cr);
- done = true;
- ++p_;
- }
- break;
- case '\n':
- {
- column_ += (p_ - sb + 1);
- err_handler_->error(std::error_code(json_parser_errc::illegal_character_in_string, json_error_category()), *this);
- // recovery - keep
- string_buffer_.append(sb, p_ - sb + 1);
- stack_.push_back(states::lf);
- done = true;
- ++p_;
- }
- break;
- case '\t':
- {
- column_ += (p_ - sb + 1);
- err_handler_->error(std::error_code(json_parser_errc::illegal_character_in_string, json_error_category()), *this);
- // recovery - keep
- string_buffer_.append(sb, p_ - sb + 1);
- done = true;
- ++p_;
- }
- break;
- case '\\':
- string_buffer_.append(sb,p_-sb);
- column_ += (p_ - sb + 1);
- stack_.back() = states::escape;
- done = true;
- ++p_;
- break;
- case '\"':
- if (string_buffer_.length() == 0)
- {
- end_string_value(sb,p_-sb);
- }
- else
- {
- string_buffer_.append(sb,p_-sb);
- end_string_value(string_buffer_.data(),string_buffer_.length());
- string_buffer_.clear();
- }
- column_ += (p_ - sb + 1);
- done = true;
- ++p_;
- break;
- default:
- ++p_;
- break;
- }
- }
- if (!done)
- {
- string_buffer_.append(sb,p_-sb);
- column_ += (p_ - sb + 1);
- }
- }
-
- void parse(const CharT* const input, size_t start, size_t length)
- {
- begin_input_ = input + start;
- end_input_ = input + length;
- p_ = begin_input_;
-
- index_ = start;
- while ((p_ < end_input_) && (stack_.back() != states::done))
- {
- switch (*p_)
- {
- case 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06:case 0x07:case 0x08:case 0x0b:
- case 0x0c:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12:case 0x13:case 0x14:case 0x15:case 0x16:
- case 0x17:case 0x18:case 0x19:case 0x1a:case 0x1b:case 0x1c:case 0x1d:case 0x1e:case 0x1f:
- err_handler_->error(std::error_code(json_parser_errc::illegal_control_character, json_error_category()), *this);
- break;
- default:
- break;
- }
-
- switch (stack_.back())
- {
- case states::cr:
- ++line_;
- column_ = 1;
- switch (*p_)
- {
- case '\n':
- JSONCONS_ASSERT(!stack_.empty())
- stack_.pop_back();
- ++p_;
- break;
- default:
- JSONCONS_ASSERT(!stack_.empty())
- stack_.pop_back();
- break;
- }
- break;
- case states::lf:
- ++line_;
- column_ = 1;
- JSONCONS_ASSERT(!stack_.empty())
- stack_.pop_back();
- break;
- case states::start:
- {
- switch (*p_)
- {
- case '\r':
- stack_.push_back(states::cr);
- break;
- case '\n':
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- do_space();
- break;
- case '/':
- stack_.push_back(states::slash);
- break;
- case '{':
- handler_->begin_json();
- do_begin_object();
- break;
- case '[':
- handler_->begin_json();
- do_begin_array();
- break;
- case '\"':
- handler_->begin_json();
- stack_.back() = states::string;
- break;
- case '-':
- handler_->begin_json();
- is_negative_ = true;
- stack_.back() = states::minus;
- break;
- case '0':
- handler_->begin_json();
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::zero;
- break;
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- handler_->begin_json();
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::integer;
- break;
- case 'f':
- handler_->begin_json();
- stack_.back() = states::f;
- literal_ = json_literals<CharT>::false_literal();
- literal_index_ = 1;
- break;
- case 'n':
- handler_->begin_json();
- stack_.back() = states::n;
- literal_ = json_literals<CharT>::null_literal();
- literal_index_ = 1;
- break;
- case 't':
- handler_->begin_json();
- stack_.back() = states::t;
- literal_ = json_literals<CharT>::true_literal();
- literal_index_ = 1;
- break;
- case '}':
- err_handler_->fatal_error(std::error_code(json_parser_errc::unexpected_right_brace, json_error_category()), *this);
- break;
- case ']':
- err_handler_->fatal_error(std::error_code(json_parser_errc::unexpected_right_bracket, json_error_category()), *this);
- break;
- default:
- err_handler_->fatal_error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
-
- case states::expect_comma_or_end:
- {
- switch (*p_)
- {
- case '\r':
- stack_.push_back(states::cr);
- break;
- case '\n':
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- do_space();
- break;
- case '/':
- stack_.push_back(states::slash);
- break;
- case '}':
- do_end_object();
- break;
- case ']':
- do_end_array();
- break;
- case ',':
- begin_member_or_element();
- break;
- default:
- JSONCONS_ASSERT(stack_.size() >= 2);
- if (parent() == states::array)
- {
- err_handler_->error(std::error_code(json_parser_errc::expected_comma_or_right_bracket, json_error_category()), *this);
- }
- else if (parent() == states::object)
- {
- err_handler_->error(std::error_code(json_parser_errc::expected_comma_or_right_brace, json_error_category()), *this);
- }
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_member_name_or_end:
- {
- switch (*p_)
- {
- case '\r':
- stack_.push_back(states::cr);
- break;
- case '\n':
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- do_space();
- break;
- case '/':
- stack_.push_back(states::slash);
- break;
- case '}':
- do_end_object();
- break;
- case '\"':
- stack_.back() = states::member_name;
- stack_.push_back(states::string);
- break;
- case '\'':
- err_handler_->error(std::error_code(json_parser_errc::single_quote, json_error_category()), *this);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_name, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_member_name:
- {
- switch (*p_)
- {
- case '\r':
- stack_.push_back(states::cr);
- break;
- case '\n':
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- do_space();
- break;
- case '/':
- stack_.push_back(states::slash);
- break;
- case '\"':
- //stack_.back() = states::string;
- stack_.back() = states::member_name;
- stack_.push_back(states::string);
- break;
- case '}':
- --nesting_depth_;
- err_handler_->error(std::error_code(json_parser_errc::extra_comma, json_error_category()), *this);
- break;
- case '\'':
- err_handler_->error(std::error_code(json_parser_errc::single_quote, json_error_category()), *this);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_name, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_colon:
- {
- switch (*p_)
- {
- case '\r':
- stack_.push_back(states::cr);
- break;
- case '\n':
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- do_space();
- break;
- case '/':
- stack_.push_back(states::slash);
- break;
- case ':':
- stack_.back() = states::expect_value;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_colon, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_value:
- {
- switch (*p_)
- {
- case '\r':
- stack_.push_back(states::cr);
- break;
- case '\n':
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- do_space();
- break;
- case '/':
- stack_.push_back(states::slash);
- break;
- case '{':
- do_begin_object();
- break;
- case '[':
- do_begin_array();
- break;
- case '\"':
- stack_.back() = states::string;
- break;
- case '-':
- is_negative_ = true;
- stack_.back() = states::minus;
- break;
- case '0':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::zero;
- break;
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::integer;
- break;
- case 'f':
- stack_.back() = states::f;
- literal_ = json_literals<CharT>::false_literal();
- literal_index_ = 1;
- break;
- case 'n':
- stack_.back() = states::n;
- literal_ = json_literals<CharT>::null_literal();
- literal_index_ = 1;
- break;
- case 't':
- stack_.back() = states::t;
- literal_ = json_literals<CharT>::true_literal();
- literal_index_ = 1;
- break;
- case ']':
- JSONCONS_ASSERT(stack_.size() >= 2);
- if (parent() == states::array)
- {
- err_handler_->error(std::error_code(json_parser_errc::extra_comma, json_error_category()), *this);
- }
- else
- {
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- }
- break;
- case '\'':
- err_handler_->error(std::error_code(json_parser_errc::single_quote, json_error_category()), *this);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_value_or_end:
- {
- switch (*p_)
- {
- case '\r':
- stack_.push_back(states::cr);
- break;
- case '\n':
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- do_space();
- break;
- case '/':
- stack_.push_back(states::slash);
- break;
- case '{':
- do_begin_object();
- break;
- case '[':
- do_begin_array();
- break;
- case ']':
- do_end_array();
- break;
- case '\"':
- stack_.back() = states::string;
- break;
- case '-':
- is_negative_ = true;
- stack_.back() = states::minus;
- break;
- case '0':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::zero;
- break;
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::integer;
- break;
- case 'f':
- stack_.back() = states::f;
- literal_ = json_literals<CharT>::false_literal();
- literal_index_ = 1;
- break;
- case 'n':
- stack_.back() = states::n;
- literal_ = json_literals<CharT>::null_literal();
- literal_index_ = 1;
- break;
- case 't':
- stack_.back() = states::t;
- literal_ = json_literals<CharT>::true_literal();
- literal_index_ = 1;
- break;
- case '\'':
- err_handler_->error(std::error_code(json_parser_errc::single_quote, json_error_category()), *this);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::string:
- parse_string();
- break;
- case states::escape:
- {
- escape_next_char(*p_);
- }
- ++p_;
- ++column_;
- break;
- case states::u1:
- {
- append_codepoint(*p_);
- stack_.back() = states::u2;
- }
- ++p_;
- ++column_;
- break;
- case states::u2:
- {
- append_codepoint(*p_);
- stack_.back() = states::u3;
- }
- ++p_;
- ++column_;
- break;
- case states::u3:
- {
- append_codepoint(*p_);
- stack_.back() = states::u4;
- }
- ++p_;
- ++column_;
- break;
- case states::u4:
- {
- append_codepoint(*p_);
- if (cp_ >= min_lead_surrogate && cp_ <= max_lead_surrogate)
- {
- stack_.back() = states::expect_surrogate_pair1;
- }
- else
- {
- json_char_traits<CharT, sizeof(CharT)>::append_codepoint_to_string(cp_, string_buffer_);
- stack_.back() = states::string;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_surrogate_pair1:
- {
- switch (*p_)
- {
- case '\\':
- cp2_ = 0;
- stack_.back() = states::expect_surrogate_pair2;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_codepoint_surrogate_pair, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_surrogate_pair2:
- {
- switch (*p_)
- {
- case 'u':
- stack_.back() = states::u6;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_codepoint_surrogate_pair, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::u6:
- {
- append_second_codepoint(*p_);
- stack_.back() = states::u7;
- }
- ++p_;
- ++column_;
- break;
- case states::u7:
- {
- append_second_codepoint(*p_);
- stack_.back() = states::u8;
- }
- ++p_;
- ++column_;
- break;
- case states::u8:
- {
- append_second_codepoint(*p_);
- stack_.back() = states::u9;
- }
- ++p_;
- ++column_;
- break;
- case states::u9:
- {
- append_second_codepoint(*p_);
- uint32_t cp = 0x10000 + ((cp_ & 0x3FF) << 10) + (cp2_ & 0x3FF);
- json_char_traits<CharT, sizeof(CharT)>::append_codepoint_to_string(cp, string_buffer_);
- stack_.back() = states::string;
- }
- ++p_;
- ++column_;
- break;
- case states::minus:
- {
- switch (*p_)
- {
- case '0':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::zero;
- break;
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::integer;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::zero:
- {
- switch (*p_)
- {
- case '\r':
- end_integer_value();
- stack_.push_back(states::cr);
- break;
- case '\n':
- end_integer_value();
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- end_integer_value();
- do_space();
- break;
- case '/':
- end_integer_value();
- stack_.push_back(states::slash);
- break;
- case '}':
- end_integer_value();
- do_end_object();
- break;
- case ']':
- end_integer_value();
- do_end_array();
- break;
- case '.':
- precision_ = static_cast<uint8_t>(number_buffer_.length());
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::fraction;
- break;
- case ',':
- end_integer_value();
- begin_member_or_element();
- break;
- case '0': case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- err_handler_->error(std::error_code(json_parser_errc::leading_zero, json_error_category()), *this);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::integer:
- {
- switch (*p_)
- {
- case '\r':
- end_integer_value();
- stack_.push_back(states::cr);
- break;
- case '\n':
- end_integer_value();
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- end_integer_value();
- do_space();
- break;
- case '/':
- end_integer_value();
- stack_.push_back(states::slash);
- break;
- case '}':
- end_integer_value();
- do_end_object();
- break;
- case ']':
- end_integer_value();
- do_end_array();
- break;
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::integer;
- break;
- case '.':
- precision_ = static_cast<uint8_t>(number_buffer_.length());
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::fraction;
- break;
- case ',':
- end_integer_value();
- begin_member_or_element();
- break;
- case 'e':case 'E':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::exp1;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::fraction:
- {
- switch (*p_)
- {
- case '\r':
- end_fraction_value();
- stack_.push_back(states::cr);
- break;
- case '\n':
- end_fraction_value();
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- end_fraction_value();
- do_space();
- break;
- case '/':
- end_fraction_value();
- stack_.push_back(states::slash);
- break;
- case '}':
- end_fraction_value();
- do_end_object();
- break;
- case ']':
- end_fraction_value();
- do_end_array();
- break;
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- ++precision_;
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::fraction;
- break;
- case ',':
- end_fraction_value();
- begin_member_or_element();
- break;
- case 'e':case 'E':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::exp1;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::exp1:
- {
- switch (*p_)
- {
- case '+':
- stack_.back() = states::exp2;
- break;
- case '-':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::exp2;
- break;
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::exp3;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::exp2:
- {
- switch (*p_)
- {
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::exp3;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::exp3:
- {
- switch (*p_)
- {
- case '\r':
- end_fraction_value();
- stack_.push_back(states::cr);
- break;
- case '\n':
- end_fraction_value();
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- end_fraction_value();
- do_space();
- break;
- case '/':
- end_fraction_value();
- stack_.push_back(states::slash);
- break;
- case '}':
- end_fraction_value();
- do_end_object();
- break;
- case ']':
- end_fraction_value();
- do_end_array();
- break;
- case ',':
- end_fraction_value();
- begin_member_or_element();
- break;
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::exp3;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::t:
- while (p_ < end_input_ && literal_index_ < literal_.second)
- {
- if (*p_ != literal_.first[literal_index_])
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_value, json_error_category()), *this);
- }
- ++p_;
- ++literal_index_;
- ++column_;
- }
- if (literal_index_ == literal_.second)
- {
- handler_->value(true, *this);
- JSONCONS_ASSERT(stack_.size() >= 2);
- if (parent() == states::root)
- {
- stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- stack_.back() = states::expect_comma_or_end;
- }
- }
- break;
- case states::f:
- while (p_ < end_input_ && literal_index_ < literal_.second)
- {
- if (*p_ != literal_.first[literal_index_])
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_value, json_error_category()), *this);
- }
- ++p_;
- ++literal_index_;
- ++column_;
- }
- if (literal_index_ == literal_.second)
- {
- handler_->value(false, *this);
- JSONCONS_ASSERT(stack_.size() >= 2);
- if (parent() == states::root)
- {
- stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- stack_.back() = states::expect_comma_or_end;
- }
- }
- break;
- case states::n:
- while (p_ < end_input_ && literal_index_ < literal_.second)
- {
- if (*p_ != literal_.first[literal_index_])
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_value, json_error_category()), *this);
- }
- ++p_;
- ++literal_index_;
- ++column_;
- }
- if (literal_index_ == literal_.second)
- {
- handler_->value(null_type(), *this);
- JSONCONS_ASSERT(stack_.size() >= 2);
- if (parent() == states::root)
- {
- stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- stack_.back() = states::expect_comma_or_end;
- }
- }
- break;
- case states::slash:
- {
- switch (*p_)
- {
- case '*':
- stack_.back() = states::slash_star;
- break;
- case '/':
- stack_.back() = states::slash_slash;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::slash_star:
- {
- switch (*p_)
- {
- case '\r':
- stack_.push_back(states::cr);
- break;
- case '\n':
- stack_.push_back(states::lf);
- break;
- case '*':
- stack_.back() = states::slash_star_star;
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::slash_slash:
- {
- switch (*p_)
- {
- case '\r':
- stack_.pop_back();
- break;
- case '\n':
- stack_.pop_back();
- break;
- default:
- ++p_;
- ++column_;
- }
- }
- break;
- case states::slash_star_star:
- {
- switch (*p_)
- {
- case '/':
- JSONCONS_ASSERT(!stack_.empty())
- stack_.pop_back();
- break;
- default:
- stack_.back() = states::slash_star;
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad parser state");
- break;
- }
- }
- index_ += (p_-begin_input_);
- }
-
- void end_parse()
- {
- JSONCONS_ASSERT(stack_.size() >= 2);
- if (parent() == states::root)
- {
- switch (stack_.back())
- {
- case states::zero:
- case states::integer:
- end_integer_value();
- break;
- case states::fraction:
- case states::exp3:
- end_fraction_value();
- break;
- default:
- break;
- }
- }
- if (stack_.back() == states::lf || stack_.back() == states::cr)
- {
- stack_.pop_back();
- }
- if (!(stack_.back() == states::done || stack_.back() == states::start))
- {
- err_handler_->error(std::error_code(json_parser_errc::unexpected_eof, json_error_category()), *this);
- }
- }
-
- states state() const
- {
- return stack_.back();
- }
-
- size_t index() const
- {
- return index_;
- }
-private:
- void end_fraction_value()
- {
- try
- {
- double d = float_reader_.read(number_buffer_.data(), precision_);
- if (is_negative_)
- d = -d;
- handler_->value(d, static_cast<uint8_t>(precision_), *this);
- }
- catch (...)
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- handler_->value(null_type(), *this); // recovery
- }
- number_buffer_.clear();
- is_negative_ = false;
-
- JSONCONS_ASSERT(stack_.size() >= 2);
- switch (parent())
- {
- case states::array:
- case states::object:
- stack_.back() = states::expect_comma_or_end;
- break;
- case states::root:
- stack_.back() = states::done;
- handler_->end_json();
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- }
-
- void end_integer_value()
- {
- if (is_negative_)
- {
- try
- {
- int64_t d = string_to_integer(is_negative_, number_buffer_.data(), number_buffer_.length());
- handler_->value(d, *this);
- }
- catch (const std::exception&)
- {
- try
- {
- double d = float_reader_.read(number_buffer_.data(), number_buffer_.length());
- handler_->value(-d, static_cast<uint8_t>(number_buffer_.length()), *this);
- }
- catch (...)
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- handler_->value(null_type(), *this);
- }
- }
- }
- else
- {
- try
- {
- uint64_t d = string_to_uinteger(number_buffer_.data(), number_buffer_.length());
- handler_->value(d, *this);
- }
- catch (const std::exception&)
- {
- try
- {
- double d = float_reader_.read(number_buffer_.data(),number_buffer_.length());
- handler_->value(d, static_cast<uint8_t>(number_buffer_.length()), *this);
- }
- catch (...)
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- handler_->value(null_type(), *this);
- }
- }
- }
-
- JSONCONS_ASSERT(stack_.size() >= 2);
- switch (parent())
- {
- case states::array:
- case states::object:
- stack_.back() = states::expect_comma_or_end;
- break;
- case states::root:
- stack_.back() = states::done;
- handler_->end_json();
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- number_buffer_.clear();
- is_negative_ = false;
- }
-
- void append_codepoint(int c)
- {
- switch (c)
- {
- case '0': case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':
- case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
- cp_ = append_to_codepoint(cp_, c);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
-
- void append_second_codepoint(int c)
- {
- switch (c)
- {
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':
- case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
- cp2_ = append_to_codepoint(cp2_, c);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
-
- void escape_next_char(int next_input)
- {
- switch (next_input)
- {
- case '\"':
- string_buffer_.push_back('\"');
- stack_.back() = states::string;
- break;
- case '\\':
- string_buffer_.push_back('\\');
- stack_.back() = states::string;
- break;
- case '/':
- string_buffer_.push_back('/');
- stack_.back() = states::string;
- break;
- case 'b':
- string_buffer_.push_back('\b');
- stack_.back() = states::string;
- break;
- case 'f':
- string_buffer_.push_back('\f');
- stack_.back() = states::string;
- break;
- case 'n':
- string_buffer_.push_back('\n');
- stack_.back() = states::string;
- break;
- case 'r':
- string_buffer_.push_back('\r');
- stack_.back() = states::string;
- break;
- case 't':
- string_buffer_.push_back('\t');
- stack_.back() = states::string;
- break;
- case 'u':
- cp_ = 0;
- stack_.back() = states::u1;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::illegal_escaped_character, json_error_category()), *this);
- break;
- }
- }
-
- void end_string_value(const CharT* s, size_t length)
- {
- JSONCONS_ASSERT(stack_.size() >= 2);
- switch (parent())
- {
- case states::member_name:
- handler_->name(s, length, *this);
- stack_.pop_back();
- stack_.back() = states::expect_colon;
- break;
- case states::object:
- case states::array:
- handler_->value(s, length, *this);
- stack_.back() = states::expect_comma_or_end;
- break;
- case states::root:
- handler_->value(s, length, *this);
- stack_.back() = states::done;
- handler_->end_json();
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- }
-
- void begin_member_or_element()
- {
- JSONCONS_ASSERT(stack_.size() >= 2);
- switch (parent())
- {
- case states::object:
- stack_.back() = states::expect_member_name;
- break;
- case states::array:
- stack_.back() = states::expect_value;
- break;
- case states::root:
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- }
-
- uint32_t append_to_codepoint(uint32_t cp, int c)
- {
- cp *= 16;
- if (c >= '0' && c <= '9')
- {
- cp += c - '0';
- }
- else if (c >= 'a' && c <= 'f')
- {
- cp += c - 'a' + 10;
- }
- else if (c >= 'A' && c <= 'F')
- {
- cp += c - 'A' + 10;
- }
- else
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_hex_escape_sequence, json_error_category()), *this);
- }
- return cp;
- }
-
- size_t do_line_number() const override
- {
- return line_;
- }
-
- size_t do_column_number() const override
- {
- return column_;
- }
-
- CharT do_current_char() const override
- {
- return p_ < end_input_? *p_ : 0;
- }
-};
-
-typedef basic_json_parser<char> json_parser;
-typedef basic_json_parser<wchar_t> wjson_parser;
-
-}
-
-#endif
-
diff --git a/vendor/jsoncons-0.99.2/jsoncons/json_parser.hpp.orig b/vendor/jsoncons-0.99.2/jsoncons/json_parser.hpp.orig
deleted file mode 100644
index e4769d5c..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/json_parser.hpp.orig
+++ /dev/null
@@ -1,2157 +0,0 @@
-// Copyright 2015 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_JSON_PARSER_HPP
-#define JSONCONS_JSON_PARSER_HPP
-
-#include <memory>
-#include <string>
-#include <sstream>
-#include <vector>
-#include <istream>
-#include <cstdlib>
-#include <stdexcept>
-#include <system_error>
-#include "jsoncons/jsoncons.hpp"
-#include "jsoncons/json_input_handler.hpp"
-#include "jsoncons/parse_error_handler.hpp"
-#include "jsoncons/json_error_category.hpp"
-
-namespace jsoncons {
-
-enum class modes
-{
- done,
- start,
- array_element,
- object_member_name,
- object_member_value
-};
-
-enum class states
-{
- start,
- slash,
- slash_slash,
- slash_star,
- slash_star_star,
- expect_comma_or_end,
- object,
- expect_member_name,
- expect_colon,
- expect_value,
- array,
- string,
- escape,
- u1,
- u2,
- u3,
- u4,
- expect_surrogate_pair1,
- expect_surrogate_pair2,
- u6,
- u7,
- u8,
- u9,
- minus,
- zero,
- integer,
- fraction,
- exp1,
- exp2,
- exp3,
- n,
- t,
- f,
- cr,
- lf,
- done,
- scalar
-};
-
-template<typename CharT>
-class basic_json_parser : private basic_parsing_context<CharT>
-{
- static const int default_depth = 100;
-
- std::vector<states> state_stack_;
- int top_;
- std::vector<modes> stack_;
- basic_json_input_handler<CharT> *handler_;
- basic_parse_error_handler<CharT> *err_handler_;
- size_t column_;
- size_t line_;
- uint32_t cp_;
- uint32_t cp2_;
- std::basic_string<CharT> string_buffer_;
- std::basic_string<char> number_buffer_;
- bool is_negative_;
- states saved_state_;
- states pre_line_break_state_;
- size_t index_;
- int depth_;
- int max_depth_;
- float_reader float_reader_;
- const CharT* begin_input_;
- const CharT* end_input_;
- const CharT* p_;
- uint8_t precision_;
- std::pair<const CharT*,size_t> literal_;
- size_t literal_index_;
-
- std::vector<states> stack2_;
-
-public:
- basic_json_parser(basic_json_input_handler<CharT>& handler)
- : top_(-1),
- stack_(default_depth),
- handler_(std::addressof(handler)),
- err_handler_(std::addressof(basic_default_parse_error_handler<CharT>::instance())),
- column_(0),
- line_(0),
- cp_(0),
- is_negative_(false),
- index_(0),
- depth_(default_depth)
- {
- max_depth_ = std::numeric_limits<int>::max JSONCONS_NO_MACRO_EXP();
- }
-
- basic_json_parser(basic_json_input_handler<CharT>& handler,
- basic_parse_error_handler<CharT>& err_handler)
- : top_(-1),
- stack_(default_depth),
- handler_(std::addressof(handler)),
- err_handler_(std::addressof(err_handler)),
- column_(0),
- line_(0),
- cp_(0),
- is_negative_(false),
- index_(0),
- depth_(default_depth)
-
- {
- max_depth_ = std::numeric_limits<int>::max JSONCONS_NO_MACRO_EXP();
- }
-
- const basic_parsing_context<CharT>& parsing_context() const
- {
- return *this;
- }
-
- ~basic_json_parser()
- {
- }
-
- size_t max_nesting_depth() const
- {
- return static_cast<size_t>(max_depth_);
- }
-
- void max_nesting_depth(size_t max_nesting_depth)
- {
- max_depth_ = static_cast<int>(std::min(max_nesting_depth,static_cast<size_t>(std::numeric_limits<int>::max JSONCONS_NO_MACRO_EXP())));
- if (depth_ > max_depth_)
- {
- depth_ = max_depth_;
- stack_.resize(depth_);
- }
- }
-
- bool done() const
- {
- return state_stack_.back() == states::done;
- }
-
- void begin_parse()
- {
- if (!push(modes::done))
- {
- err_handler_->error(std::error_code(json_parser_errc::max_depth_exceeded, json_error_category()), *this);
- }
- state_stack_.clear();
- state_stack_.push_back(states::start);
- line_ = 1;
- column_ = 1;
- stack2_.push_back(states::start);
- stack2_.push_back(states::scalar);
- }
-
- void check_done(const CharT* input, size_t start, size_t length)
- {
- index_ = start;
- for (; index_ < length; ++index_)
- {
- CharT curr_char_ = input[index_];
- switch (curr_char_)
- {
- case '\n':
- case '\r':
- case '\t':
- case ' ':
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::extra_character, json_error_category()), *this);
- break;
- }
- }
- }
-
- bool parse_string(const CharT** first, const CharT** last)
- {
- const CharT* sb = p_;
- bool done = false;
- bool complete = false;
- while (!done && p_ < end_input_)
- {
- switch (*p_)
- {
- case 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06:case 0x07:case 0x08:case 0x0b:
- case 0x0c:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12:case 0x13:case 0x14:case 0x15:case 0x16:
- case 0x17:case 0x18:case 0x19:case 0x1a:case 0x1b:case 0x1c:case 0x1d:case 0x1e:case 0x1f:
- string_buffer_.append(sb,p_-sb);
- column_ += (p_ - sb + 1);
- err_handler_->error(std::error_code(json_parser_errc::illegal_control_character, json_error_category()), *this);
- // recovery - skip
- done = true;
- ++p_;
- break;
- case '\r':
- {
- column_ += (p_ - sb + 1);
- err_handler_->error(std::error_code(json_parser_errc::illegal_character_in_string, json_error_category()), *this);
- // recovery - keep
- string_buffer_.append(sb, p_ - sb + 1);
-<<<<<<< HEAD
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::cr;
-=======
- pre_line_break_state_ = state_;
- state_ = states::cr;
-
->>>>>>> 8522df40eb2e2c14a4b40274eedf44dd9d631bb8
- done = true;
- ++p_;
-
- stack2_.push_back(states::cr);
- }
- break;
- case '\n':
- {
- column_ += (p_ - sb + 1);
- err_handler_->error(std::error_code(json_parser_errc::illegal_character_in_string, json_error_category()), *this);
- // recovery - keep
- string_buffer_.append(sb, p_ - sb + 1);
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::lf;
- done = true;
- ++p_;
-
- stack2_.push_back(states::lf);
- }
- break;
- case '\t':
- {
- column_ += (p_ - sb + 1);
- err_handler_->error(std::error_code(json_parser_errc::illegal_character_in_string, json_error_category()), *this);
- // recovery - keep
- string_buffer_.append(sb, p_ - sb + 1);
- done = true;
- ++p_;
- }
- break;
- case '\\':
- string_buffer_.append(sb,p_-sb);
- column_ += (p_ - sb + 1);
-<<<<<<< HEAD
- state_stack_.back() = states::escape;
-=======
- state_ = states::escape;
- stack2_.front() = states::escape;
->>>>>>> 8522df40eb2e2c14a4b40274eedf44dd9d631bb8
- done = true;
- ++p_;
- break;
- case '\"':
- if (string_buffer_.length() == 0)
- {
- *first = sb;
- *last = p_;
- //end_string_value(sb,p_-sb);
- }
- else
- {
- string_buffer_.append(sb,p_-sb);
- *first = string_buffer_.data();
- *last = string_buffer_.data() + string_buffer_.length();
- //end_string_value(string_buffer_.data(),string_buffer_.length());
- //string_buffer_.clear();
- }
- column_ += (p_ - sb + 1);
- done = true;
- complete = true;
- ++p_;
- break;
- default:
- ++p_;
- break;
- }
- }
- if (!done)
- {
- string_buffer_.append(sb,p_-sb);
- column_ += (p_ - sb + 1);
- }
-
- return complete;
- }
-
- void parse(const CharT* const input, size_t start, size_t length)
- {
- begin_input_ = input + start;
- end_input_ = input + length;
- p_ = begin_input_;
-
- index_ = start;
- while ((p_ < end_input_) && (state_stack_.back() != states::done))
- {
- switch (*p_)
- {
- case 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06:case 0x07:case 0x08:case 0x0b:
- case 0x0c:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12:case 0x13:case 0x14:case 0x15:case 0x16:
- case 0x17:case 0x18:case 0x19:case 0x1a:case 0x1b:case 0x1c:case 0x1d:case 0x1e:case 0x1f:
- err_handler_->error(std::error_code(json_parser_errc::illegal_control_character, json_error_category()), *this);
- break;
- default:
- break;
- }
-
- switch (state_stack_.back())
- {
- case states::cr:
- ++line_;
- column_ = 1;
- switch (*p_)
- {
- case '\n':
- state_stack_.back() = pre_line_break_state_;
- ++p_;
- break;
- default:
- state_stack_.back() = pre_line_break_state_;
- break;
- }
- JSONCONS_ASSERT(stack2_.size() > 0);
- stack2_.pop_back();
- break;
- case states::lf:
- ++line_;
- column_ = 1;
-<<<<<<< HEAD
- state_stack_.back() = pre_line_break_state_;
-=======
- state_ = pre_line_break_state_;
- JSONCONS_ASSERT(stack2_.size() > 0);
- stack2_.pop_back();
->>>>>>> 8522df40eb2e2c14a4b40274eedf44dd9d631bb8
- break;
- case states::start:
- {
- switch (*p_)
- {
- case '\r':
-<<<<<<< HEAD
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::lf;
-=======
- pre_line_break_state_ = state_;
- state_ = states::cr;
- stack2_.push_back(states::cr);
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- stack2_.push_back(states::lf);
->>>>>>> 8522df40eb2e2c14a4b40274eedf44dd9d631bb8
- break;
- case ' ':case '\t':
- {
- bool done = false;
- while (!done && (p_ + 1) < end_input_)
- {
- switch (*(p_ + 1))
- {
- case ' ':case '\t':
- ++p_;
- ++column_;
- break;
- default:
- done = true;
- break;
- }
- }
- }
- break;
- case '{':
- handler_->begin_json();
- if (!push(modes::object_member_name))
- {
- err_handler_->error(std::error_code(json_parser_errc::max_depth_exceeded, json_error_category()), *this);
- }
-<<<<<<< HEAD
- state_stack_.back() = states::object;
-=======
- state_ = states::object;
-
->>>>>>> 8522df40eb2e2c14a4b40274eedf44dd9d631bb8
- handler_->begin_object(*this);
- break;
- case '[':
- handler_->begin_json();
- if (!push(modes::array_element))
- {
- err_handler_->error(std::error_code(json_parser_errc::max_depth_exceeded, json_error_category()), *this);
- }
- state_stack_.back() = states::array;
- handler_->begin_array(*this);
- break;
- case '\"':
- handler_->begin_json();
- flip(modes::done, modes::start);
- state_stack_.back() = states::string;
- break;
- case '-':
- handler_->begin_json();
- flip(modes::done, modes::start);
- is_negative_ = true;
- state_stack_.back() = states::minus;
- break;
- case '0':
- handler_->begin_json();
- flip(modes::done, modes::start);
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::zero;
- break;
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- handler_->begin_json();
- flip(modes::done, modes::start);
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::integer;
- break;
- case 'f':
- handler_->begin_json();
- flip(modes::done, modes::start);
- state_stack_.back() = states::f;
- literal_ = json_literals<CharT>::false_literal();
- literal_index_ = 1;
- break;
- case 'n':
- handler_->begin_json();
- flip(modes::done, modes::start);
- state_stack_.back() = states::n;
- literal_ = json_literals<CharT>::null_literal();
- literal_index_ = 1;
- break;
- case 't':
- handler_->begin_json();
- flip(modes::done, modes::start);
- state_stack_.back() = states::t;
- literal_ = json_literals<CharT>::true_literal();
- literal_index_ = 1;
- break;
- case '/':
- saved_state_ = state_stack_.back();
- state_stack_.back() = states::slash;
- break;
- case '}':
- err_handler_->fatal_error(std::error_code(json_parser_errc::unexpected_right_brace, json_error_category()), *this);
- break;
- case ']':
- err_handler_->fatal_error(std::error_code(json_parser_errc::unexpected_right_bracket, json_error_category()), *this);
- break;
- default:
- err_handler_->fatal_error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
-
- case states::expect_comma_or_end:
- {
- switch (*p_)
- {
- case '\r':
-<<<<<<< HEAD
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::lf;
-=======
- pre_line_break_state_ = state_;
- state_ = states::cr;
- stack2_.push_back(states::cr);
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- stack2_.push_back(states::lf);
->>>>>>> 8522df40eb2e2c14a4b40274eedf44dd9d631bb8
- break;
- case ' ':case '\t':
- {
- bool done = false;
- while (!done && (p_ + 1) < end_input_)
- {
- switch (*(p_ + 1))
- {
- case ' ':case '\t':
- ++p_;
- ++column_;
- break;
- default:
- done = true;
- break;
- }
- }
- }
- break;
- case '}':
- if (peek() == modes::object_member_value)
- {
- pop(modes::object_member_value);
- handler_->end_object(*this);
- if (peek() == modes::done)
- {
- state_stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- state_stack_.back() = states::expect_comma_or_end;
- }
- }
- else if (peek() == modes::array_element)
- {
- err_handler_->fatal_error(std::error_code(json_parser_errc::expected_comma_or_right_bracket, json_error_category()), *this);
- }
- else
- {
- err_handler_->fatal_error(std::error_code(json_parser_errc::unexpected_right_brace, json_error_category()), *this);
- }
- break;
- case ']':
- if (peek() == modes::array_element)
- {
- pop(modes::array_element);
- handler_->end_array(*this);
- if (peek() == modes::done)
- {
- state_stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- state_stack_.back() = states::expect_comma_or_end;
- }
- }
- else if (peek() == modes::object_member_value)
- {
- err_handler_->fatal_error(std::error_code(json_parser_errc::expected_comma_or_right_brace, json_error_category()), *this);
- }
- else
- {
- err_handler_->fatal_error(std::error_code(json_parser_errc::unexpected_right_bracket, json_error_category()), *this);
- }
- break;
- case ',':
- begin_member_or_element();
- break;
- case '/':
- saved_state_ = state_stack_.back();
- state_stack_.back() = states::slash;
- break;
- default:
- if (peek() == modes::array_element)
- {
- err_handler_->error(std::error_code(json_parser_errc::expected_comma_or_right_bracket, json_error_category()), *this);
- }
- else if (peek() == modes::object_member_value)
- {
- err_handler_->error(std::error_code(json_parser_errc::expected_comma_or_right_brace, json_error_category()), *this);
- }
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::object:
- {
- switch (*p_)
- {
- case '\r':
-<<<<<<< HEAD
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::lf;
-=======
- pre_line_break_state_ = state_;
- state_ = states::cr;
- stack2_.push_back(states::cr);
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- stack2_.push_back(states::lf);
->>>>>>> 8522df40eb2e2c14a4b40274eedf44dd9d631bb8
- break;
- case ' ':case '\t':
- {
- bool done = false;
- while (!done && (p_ + 1) < end_input_)
- {
- switch (*(p_ + 1))
- {
- case ' ':case '\t':
- ++p_;
- ++column_;
- break;
- default:
- done = true;
- break;
- }
- }
- }
- break;
- case '}':
- if (!pop(modes::object_member_name))
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- }
- handler_->end_object(*this);
- if (peek() == modes::done)
- {
- state_stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- state_stack_.back() = states::expect_comma_or_end;
- }
- break;
- case '\"':
- state_stack_.back() = states::string;
- break;
- case '/':
- saved_state_ = state_stack_.back();
- state_stack_.back() = states::slash;
- break;
- case '\'':
- err_handler_->error(std::error_code(json_parser_errc::single_quote, json_error_category()), *this);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_name, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_member_name:
- {
- switch (*p_)
- {
- case '\r':
-<<<<<<< HEAD
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::lf;
-=======
- pre_line_break_state_ = state_;
- state_ = states::cr;
- stack2_.push_back(states::cr);
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- stack2_.push_back(states::lf);
->>>>>>> 8522df40eb2e2c14a4b40274eedf44dd9d631bb8
- break;
- case ' ':case '\t':
- {
- bool done = false;
- while (!done && (p_ + 1) < end_input_)
- {
- switch (*(p_ + 1))
- {
- case ' ':case '\t':
- ++p_;
- ++column_;
- break;
- default:
- done = true;
- break;
- }
- }
- }
- break;
- case '\"':
- state_stack_.back() = states::string;
- break;
- case '/':
- saved_state_ = state_stack_.back();
- state_stack_.back() = states::slash;
- break;
- case '}':
- err_handler_->error(std::error_code(json_parser_errc::extra_comma, json_error_category()), *this);
- break;
- case '\'':
- err_handler_->error(std::error_code(json_parser_errc::single_quote, json_error_category()), *this);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_name, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_colon:
- {
- switch (*p_)
- {
- case '\r':
-<<<<<<< HEAD
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::lf;
-=======
- pre_line_break_state_ = state_;
- state_ = states::cr;
- stack2_.push_back(states::cr);
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- stack2_.push_back(states::lf);
->>>>>>> 8522df40eb2e2c14a4b40274eedf44dd9d631bb8
- break;
- case ' ':case '\t':
- {
- bool done = false;
- while (!done && (p_ + 1) < end_input_)
- {
- switch (*(p_ + 1))
- {
- case ' ':case '\t':
- ++p_;
- ++column_;
- break;
- default:
- done = true;
- break;
- }
- }
- }
- break;
- case ':':
- begin_member_value();
- state_stack_.back() = states::expect_value;
- break;
- case '/':
- saved_state_ = state_stack_.back();
- state_stack_.back() = states::slash;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_colon, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_value:
- {
- switch (*p_)
- {
- case '\r':
-<<<<<<< HEAD
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::lf;
-=======
- pre_line_break_state_ = state_;
- state_ = states::cr;
- stack2_.push_back(states::cr);
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- stack2_.push_back(states::lf);
->>>>>>> 8522df40eb2e2c14a4b40274eedf44dd9d631bb8
- break;
- case ' ':case '\t':
- {
- bool done = false;
- while (!done && (p_ + 1) < end_input_)
- {
- switch (*(p_ + 1))
- {
- case ' ':case '\t':
- ++p_;
- ++column_;
- break;
- default:
- done = true;
- break;
- }
- }
- }
- break;
- case '{':
- if (!push(modes::object_member_name))
- {
- err_handler_->error(std::error_code(json_parser_errc::max_depth_exceeded, json_error_category()), *this);
- }
- state_stack_.back() = states::object;
- handler_->begin_object(*this);
- break;
- case '[':
- if (!push(modes::array_element))
- {
- err_handler_->error(std::error_code(json_parser_errc::max_depth_exceeded, json_error_category()), *this);
- }
- state_stack_.back() = states::array;
- handler_->begin_array(*this);
- break;
- case '/':
- saved_state_ = state_stack_.back();
- state_stack_.back() = states::slash;
- break;
-
- case '\"':
- state_stack_.back() = states::string;
- break;
- case '-':
- is_negative_ = true;
- state_stack_.back() = states::minus;
- break;
- case '0':
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::zero;
- break;
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::integer;
- break;
- case 'f':
- state_stack_.back() = states::f;
- literal_ = json_literals<CharT>::false_literal();
- literal_index_ = 1;
- /*if ((p_+4) < end_input_)
- {
- if ((*(p_+1) == 'a') & (*(p_+2) == 'l') & (*(p_+3) == 's') & (*(p_+4) == 'e'))
- {
- p_ += 4;
- column_ += 4;
- handler_->value(false, *this);
- if (peek() == modes::start)
- {
- flip(modes::start,modes::done);
- state_stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- state_stack_.back() = states::expect_comma_or_end;
- }
- }
- }*/
- break;
- case 'n':
- state_stack_.back() = states::n;
- literal_ = json_literals<CharT>::null_literal();
- literal_index_ = 1;
- break;
- case 't':
- state_stack_.back() = states::t;
- literal_ = json_literals<CharT>::true_literal();
- literal_index_ = 1;
- break;
- case ']':
- if (peek() == modes::array_element)
- {
- err_handler_->error(std::error_code(json_parser_errc::extra_comma, json_error_category()), *this);
- }
- else
- {
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- }
- break;
- case '\'':
- err_handler_->error(std::error_code(json_parser_errc::single_quote, json_error_category()), *this);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::array:
- {
- switch (*p_)
- {
- case '\r':
-<<<<<<< HEAD
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::lf;
-=======
- pre_line_break_state_ = state_;
- state_ = states::cr;
- stack2_.push_back(states::cr);
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- stack2_.push_back(states::lf);
->>>>>>> 8522df40eb2e2c14a4b40274eedf44dd9d631bb8
- break;
- case ' ':case '\t':
- {
- bool done = false;
- while (!done && (p_ + 1) < end_input_)
- {
- switch (*(p_ + 1))
- {
- case ' ':case '\t':
- ++p_;
- ++column_;
- break;
- default:
- done = true;
- break;
- }
- }
- }
- break;
- case '{':
- if (!push(modes::object_member_name))
- {
- err_handler_->error(std::error_code(json_parser_errc::max_depth_exceeded, json_error_category()), *this);
- }
- state_stack_.back() = states::object;
- handler_->begin_object(*this);
- break;
- case '[':
- if (!push(modes::array_element))
- {
- err_handler_->error(std::error_code(json_parser_errc::max_depth_exceeded, json_error_category()), *this);
- }
- state_stack_.back() = states::array;
- handler_->begin_array(*this);
- break;
- case ']':
- if (!pop(modes::array_element))
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- }
- handler_->end_array(*this);
- if (peek() == modes::done)
- {
- state_stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- state_stack_.back() = states::expect_comma_or_end;
- }
- break;
- case '\"':
- state_stack_.back() = states::string;
- break;
- case '/':
- saved_state_ = state_stack_.back();
- state_stack_.back() = states::slash;
- break;
- case '-':
- is_negative_ = true;
- state_stack_.back() = states::minus;
- break;
- case '0':
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::zero;
- break;
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::integer;
- break;
- case 'f':
- state_stack_.back() = states::f;
- literal_ = json_literals<CharT>::false_literal();
- literal_index_ = 1;
- /*if ((p_+4) < end_input_)
- {
- if ((*(p_+1) == 'a') & (*(p_+2) == 'l') & (*(p_+3) == 's') & (*(p_+4) == 'e'))
- {
- p_ += 4;
- column_ += 4;
- handler_->value(false, *this);
- if (peek() == modes::start)
- {
- flip(modes::start,modes::done);
- state_stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- state_stack_.back() = states::expect_comma_or_end;
- }
- }
- }*/
- break;
- case 'n':
- state_stack_.back() = states::n;
- literal_ = json_literals<CharT>::null_literal();
- literal_index_ = 1;
- break;
- case 't':
- state_stack_.back() = states::t;
- literal_ = json_literals<CharT>::true_literal();
- literal_index_ = 1;
- break;
- case '\'':
- err_handler_->error(std::error_code(json_parser_errc::single_quote, json_error_category()), *this);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::string:
- {
- const CharT* first;
- const CharT* last;
- if (parse_string(&first,&last))
- {
- end_string_value(first,last-first);
- string_buffer_.clear();
- }
- }
- break;
- case states::escape:
- {
- escape_next_char(*p_);
- }
- ++p_;
- ++column_;
- break;
- case states::u1:
- {
- append_codepoint(*p_);
- state_stack_.back() = states::u2;
- }
- ++p_;
- ++column_;
- break;
- case states::u2:
- {
- append_codepoint(*p_);
- state_stack_.back() = states::u3;
- }
- ++p_;
- ++column_;
- break;
- case states::u3:
- {
- append_codepoint(*p_);
- state_stack_.back() = states::u4;
- }
- ++p_;
- ++column_;
- break;
- case states::u4:
- {
- append_codepoint(*p_);
- if (cp_ >= min_lead_surrogate && cp_ <= max_lead_surrogate)
- {
- state_stack_.back() = states::expect_surrogate_pair1;
- }
- else
- {
- json_char_traits<CharT, sizeof(CharT)>::append_codepoint_to_string(cp_, string_buffer_);
- state_stack_.back() = states::string;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_surrogate_pair1:
- {
- switch (*p_)
- {
- case '\\':
- cp2_ = 0;
- state_stack_.back() = states::expect_surrogate_pair2;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_codepoint_surrogate_pair, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_surrogate_pair2:
- {
- switch (*p_)
- {
- case 'u':
- state_stack_.back() = states::u6;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_codepoint_surrogate_pair, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::u6:
- {
- append_second_codepoint(*p_);
- state_stack_.back() = states::u7;
- }
- ++p_;
- ++column_;
- break;
- case states::u7:
- {
- append_second_codepoint(*p_);
- state_stack_.back() = states::u8;
- }
- ++p_;
- ++column_;
- break;
- case states::u8:
- {
- append_second_codepoint(*p_);
- state_stack_.back() = states::u9;
- }
- ++p_;
- ++column_;
- break;
- case states::u9:
- {
- append_second_codepoint(*p_);
- uint32_t cp = 0x10000 + ((cp_ & 0x3FF) << 10) + (cp2_ & 0x3FF);
- json_char_traits<CharT, sizeof(CharT)>::append_codepoint_to_string(cp, string_buffer_);
- state_stack_.back() = states::string;
- }
- ++p_;
- ++column_;
- break;
- case states::minus:
- {
- switch (*p_)
- {
- case '0':
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::zero;
- break;
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::integer;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::zero:
- {
- switch (*p_)
- {
- case '\r':
-<<<<<<< HEAD
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::lf;
-=======
- pre_line_break_state_ = state_;
- state_ = states::cr;
- stack2_.push_back(states::cr);
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- stack2_.push_back(states::lf);
->>>>>>> 8522df40eb2e2c14a4b40274eedf44dd9d631bb8
- break;
- case ' ':case '\t':
- {
- bool done = false;
- while (!done && (p_ + 1) < end_input_)
- {
- switch (*(p_ + 1))
- {
- case ' ':case '\t':
- ++p_;
- ++column_;
- break;
- default:
- done = true;
- break;
- }
- }
- }
- end_integer_value();
- break; // No change
- case '}':
- end_integer_value();
- if (!pop(modes::object_member_value))
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- }
- handler_->end_object(*this);
- if (peek() == modes::done)
- {
- state_stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- state_stack_.back() = states::expect_comma_or_end;
- }
- break;
- case ']':
- end_integer_value();
- if (!pop(modes::array_element))
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- }
- handler_->end_array(*this);
- if (peek() == modes::done)
- {
- state_stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- state_stack_.back() = states::expect_comma_or_end;
- }
- break;
- case '.':
- precision_ = static_cast<uint8_t>(number_buffer_.length());
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::fraction;
- break;
- case ',':
- end_integer_value();
- begin_member_or_element();
- break;
- case '0': case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- err_handler_->error(std::error_code(json_parser_errc::leading_zero, json_error_category()), *this);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::integer:
- {
- switch (*p_)
- {
- case '\r':
-<<<<<<< HEAD
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::lf;
-=======
- pre_line_break_state_ = state_;
- state_ = states::cr;
- stack2_.push_back(states::cr);
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- stack2_.push_back(states::lf);
->>>>>>> 8522df40eb2e2c14a4b40274eedf44dd9d631bb8
- break;
- case ' ':case '\t':
- {
- bool done = false;
- while (!done && (p_ + 1) < end_input_)
- {
- switch (*(p_ + 1))
- {
- case ' ':case '\t':
- ++p_;
- ++column_;
- break;
- default:
- done = true;
- break;
- }
- }
- }
- end_integer_value();
- break;
- case '}':
- end_integer_value();
- if (!pop(modes::object_member_value))
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- }
- handler_->end_object(*this);
- if (peek() == modes::done)
- {
- state_stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- state_stack_.back() = states::expect_comma_or_end;
- }
- break;
- case ']':
- end_integer_value();
- if (!pop(modes::array_element))
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- }
- handler_->end_array(*this);
- if (peek() == modes::done)
- {
- state_stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- state_stack_.back() = states::expect_comma_or_end;
- }
- break;
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::integer;
- break;
- case '.':
- precision_ = static_cast<uint8_t>(number_buffer_.length());
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::fraction;
- break;
- case ',':
- end_integer_value();
- begin_member_or_element();
- break;
- case 'e':case 'E':
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::exp1;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::fraction:
- {
- switch (*p_)
- {
- case '\r':
-<<<<<<< HEAD
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::lf;
-=======
- pre_line_break_state_ = state_;
- state_ = states::cr;
- stack2_.push_back(states::cr);
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- stack2_.push_back(states::lf);
->>>>>>> 8522df40eb2e2c14a4b40274eedf44dd9d631bb8
- break;
- case ' ':case '\t':
- {
- bool done = false;
- while (!done && (p_ + 1) < end_input_)
- {
- switch (*(p_ + 1))
- {
- case ' ':case '\t':
- ++p_;
- ++column_;
- break;
- default:
- done = true;
- break;
- }
- }
- }
- end_fraction_value();
- break;
- case '}':
- end_fraction_value();
- if (!pop(modes::object_member_value))
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- }
- handler_->end_object(*this);
- if (peek() == modes::done)
- {
- state_stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- state_stack_.back() = states::expect_comma_or_end;
- }
- break;
- case ']':
- end_fraction_value();
- if (!pop(modes::array_element))
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- }
- handler_->end_array(*this);
- if (peek() == modes::done)
- {
- state_stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- state_stack_.back() = states::expect_comma_or_end;
- }
- break;
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- ++precision_;
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::fraction;
- break;
- case ',':
- end_fraction_value();
- begin_member_or_element();
- break;
- case 'e':case 'E':
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::exp1;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::exp1:
- {
- switch (*p_)
- {
- case '+':
- state_stack_.back() = states::exp2;
- break;
- case '-':
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::exp2;
- break;
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::exp3;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::exp2:
- {
- switch (*p_)
- {
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::exp3;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::exp3:
- {
- switch (*p_)
- {
- case '\r':
-<<<<<<< HEAD
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::lf;
-=======
- pre_line_break_state_ = state_;
- state_ = states::cr;
- stack2_.push_back(states::cr);
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- stack2_.push_back(states::lf);
->>>>>>> 8522df40eb2e2c14a4b40274eedf44dd9d631bb8
- break;
- case ' ':case '\t':
- {
- bool done = false;
- while (!done && (p_ + 1) < end_input_)
- {
- switch (*(p_ + 1))
- {
- case ' ':case '\t':
- ++p_;
- ++column_;
- break;
- default:
- done = true;
- break;
- }
- }
- }
- end_fraction_value();
- break;
- case '}':
- end_fraction_value();
- if (!pop(modes::object_member_value))
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- }
- handler_->end_object(*this);
- if (peek() == modes::done)
- {
- state_stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- state_stack_.back() = states::expect_comma_or_end;
- }
- break;
- case ']':
- end_fraction_value();
- if (!pop(modes::array_element))
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- }
- handler_->end_array(*this);
- if (peek() == modes::done)
- {
- state_stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- state_stack_.back() = states::expect_comma_or_end;
- }
- break;
- case ',':
- end_fraction_value();
- begin_member_or_element();
- break;
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- state_stack_.back() = states::exp3;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::t:
- while (p_ < end_input_ && literal_index_ < literal_.second)
- {
- if (*p_ != literal_.first[literal_index_])
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_value, json_error_category()), *this);
- }
- ++p_;
- ++literal_index_;
- ++column_;
- }
- if (literal_index_ == literal_.second)
- {
- handler_->value(true, *this);
- if (peek() == modes::start)
- {
- flip(modes::start,modes::done);
- state_stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- state_stack_.back() = states::expect_comma_or_end;
- }
- }
- break;
- case states::f:
- while (p_ < end_input_ && literal_index_ < literal_.second)
- {
- if (*p_ != literal_.first[literal_index_])
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_value, json_error_category()), *this);
- }
- ++p_;
- ++literal_index_;
- ++column_;
- }
- if (literal_index_ == literal_.second)
- {
- handler_->value(false, *this);
- if (peek() == modes::start)
- {
- flip(modes::start,modes::done);
- state_stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- state_stack_.back() = states::expect_comma_or_end;
- }
- }
- break;
- case states::n:
- while (p_ < end_input_ && literal_index_ < literal_.second)
- {
- if (*p_ != literal_.first[literal_index_])
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_value, json_error_category()), *this);
- }
- ++p_;
- ++literal_index_;
- ++column_;
- }
- if (literal_index_ == literal_.second)
- {
- handler_->value(null_type(), *this);
- if (peek() == modes::start)
- {
- flip(modes::start,modes::done);
- state_stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- state_stack_.back() = states::expect_comma_or_end;
- }
- }
- break;
- case states::slash:
- {
- switch (*p_)
- {
- case '*':
- state_stack_.back() = states::slash_star;
- break;
- case '/':
- state_stack_.back() = states::slash_slash;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::slash_star:
- {
- switch (*p_)
- {
- case '\r':
-<<<<<<< HEAD
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_stack_.back();
- state_stack_.back() = states::lf;
-=======
- pre_line_break_state_ = state_;
- state_ = states::cr;
- stack2_.push_back(states::cr);
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- stack2_.push_back(states::lf);
->>>>>>> 8522df40eb2e2c14a4b40274eedf44dd9d631bb8
- break;
- case '*':
- state_stack_.back() = states::slash_star_star;
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::slash_slash:
- {
- switch (*p_)
- {
- case '\r':
- pre_line_break_state_ = saved_state_;
-<<<<<<< HEAD
- state_stack_.back() = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = saved_state_;
- state_stack_.back() = states::lf;
-=======
- state_ = states::cr;
- stack2_.push_back(states::cr);
- break;
- case '\n':
- pre_line_break_state_ = saved_state_;
- state_ = states::lf;
- stack2_.push_back(states::lf);
->>>>>>> 8522df40eb2e2c14a4b40274eedf44dd9d631bb8
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::slash_star_star:
- {
- switch (*p_)
- {
- case '/':
- state_stack_.back() = saved_state_;
- break;
- default:
- state_stack_.back() = states::slash_star;
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad parser state");
- break;
- }
- }
- index_ += (p_-begin_input_);
- }
-
- void end_parse()
- {
- if (peek() == modes::start)
- {
- switch (state_stack_.back())
- {
- case states::zero:
- case states::integer:
- end_integer_value();
- break;
- case states::fraction:
- case states::exp3:
- end_fraction_value();
- break;
- default:
- break;
- }
- }
- if (!pop(modes::done))
- {
- err_handler_->error(std::error_code(json_parser_errc::unexpected_eof, json_error_category()), *this);
- }
- }
-
- states state() const
- {
- return state_stack_.back();
- }
-
- size_t index() const
- {
- return index_;
- }
-private:
- void end_fraction_value()
- {
- try
- {
- double d = float_reader_.read(number_buffer_.data(), precision_);
- if (is_negative_)
- d = -d;
- handler_->value(d, static_cast<uint8_t>(precision_), *this);
- }
- catch (...)
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- handler_->value(null_type(), *this); // recovery
- }
- number_buffer_.clear();
- is_negative_ = false;
- switch (stack_[top_])
- {
- case modes::array_element:
- case modes::object_member_value:
- state_stack_.back() = states::expect_comma_or_end;
- break;
- case modes::start:
- flip(modes::start,modes::done);
- state_stack_.back() = states::done;
- handler_->end_json();
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- }
-
- void end_integer_value()
- {
- if (is_negative_)
- {
- try
- {
- int64_t d = string_to_integer(is_negative_, number_buffer_.data(), number_buffer_.length());
- handler_->value(d, *this);
- }
- catch (const std::exception&)
- {
- try
- {
- double d = float_reader_.read(number_buffer_.data(), number_buffer_.length());
- handler_->value(-d, static_cast<uint8_t>(number_buffer_.length()), *this);
- }
- catch (...)
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- handler_->value(null_type(), *this);
- }
- }
- }
- else
- {
- try
- {
- uint64_t d = string_to_uinteger(number_buffer_.data(), number_buffer_.length());
- handler_->value(d, *this);
- }
- catch (const std::exception&)
- {
- try
- {
- double d = float_reader_.read(number_buffer_.data(),number_buffer_.length());
- handler_->value(d, static_cast<uint8_t>(number_buffer_.length()), *this);
- }
- catch (...)
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- handler_->value(null_type(), *this);
- }
- }
- }
-
- switch (stack_[top_])
- {
- case modes::array_element:
- case modes::object_member_value:
- state_stack_.back() = states::expect_comma_or_end;
- break;
- case modes::start:
- flip(modes::start,modes::done);
- state_stack_.back() = states::done;
- handler_->end_json();
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- number_buffer_.clear();
- is_negative_ = false;
- }
-
- void append_codepoint(int c)
- {
- switch (c)
- {
- case '0': case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':
- case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
- cp_ = append_to_codepoint(cp_, c);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
-
- void append_second_codepoint(int c)
- {
- switch (c)
- {
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':
- case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
- cp2_ = append_to_codepoint(cp2_, c);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
-
- void escape_next_char(int next_input)
- {
- switch (next_input)
- {
- case '\"':
- string_buffer_.push_back('\"');
- state_stack_.back() = states::string;
- break;
- case '\\':
- string_buffer_.push_back('\\');
- state_stack_.back() = states::string;
- break;
- case '/':
- string_buffer_.push_back('/');
- state_stack_.back() = states::string;
- break;
- case 'b':
- string_buffer_.push_back('\b');
- state_stack_.back() = states::string;
- break;
- case 'f':
- string_buffer_.push_back('\f');
- state_stack_.back() = states::string;
- break;
- case 'n':
- string_buffer_.push_back('\n');
- state_stack_.back() = states::string;
- break;
- case 'r':
- string_buffer_.push_back('\r');
- state_stack_.back() = states::string;
- break;
- case 't':
- string_buffer_.push_back('\t');
- state_stack_.back() = states::string;
- break;
- case 'u':
- cp_ = 0;
- state_stack_.back() = states::u1;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::illegal_escaped_character, json_error_category()), *this);
- break;
- }
- }
-
- void end_string_value(const CharT* s, size_t length)
- {
- switch (stack_[top_])
- {
- case modes::object_member_name:
- handler_->name(s, length, *this);
- state_stack_.back() = states::expect_colon;
- break;
- case modes::array_element:
- case modes::object_member_value:
- handler_->value(s, length, *this);
- state_stack_.back() = states::expect_comma_or_end;
- break;
- case modes::start:
- handler_->value(s, length, *this);
- flip(modes::start,modes::done);
- state_stack_.back() = states::done;
- handler_->end_json();
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- }
-
- void begin_member_or_element()
- {
- switch (stack_[top_])
- {
- case modes::object_member_value:
- // A comma causes a flip from object_member_value modes to object_member_name modes.
- flip(modes::object_member_value, modes::object_member_name);
- state_stack_.back() = states::expect_member_name;
- break;
- case modes::array_element:
- state_stack_.back() = states::expect_value;
- break;
- case modes::done:
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- }
-
- void begin_member_value()
- {
- flip(modes::object_member_name, modes::object_member_value);
- state_stack_.back() = states::expect_value;
- }
-
- uint32_t append_to_codepoint(uint32_t cp, int c)
- {
- cp *= 16;
- if (c >= '0' && c <= '9')
- {
- cp += c - '0';
- }
- else if (c >= 'a' && c <= 'f')
- {
- cp += c - 'a' + 10;
- }
- else if (c >= 'A' && c <= 'F')
- {
- cp += c - 'A' + 10;
- }
- else
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_hex_escape_sequence, json_error_category()), *this);
- }
- return cp;
- }
-
- size_t do_line_number() const override
- {
- return line_;
- }
-
- size_t do_column_number() const override
- {
- return column_;
- }
-
- CharT do_current_char() const override
- {
- return p_ < end_input_? *p_ : 0;
- }
-
- bool push(modes mode)
- {
- ++top_;
- if (top_ >= depth_)
- {
- if (top_ >= max_depth_)
- {
- return false;
- }
- depth_ *= 2;
- stack_.resize(depth_);
- }
- stack_[top_] = mode;
- return true;
- }
-
- modes peek()
- {
- return stack_[top_];
- }
-
- bool peek(modes mode)
- {
- return stack_[top_] == mode;
- }
-
- void flip(modes mode1, modes mode2)
- {
- JSONCONS_ASSERT((top_ >= 0) && (stack_[top_] == mode1))
- stack_[top_] = mode2;
- }
-
- bool pop(modes mode)
- {
- if (top_ < 0 || stack_[top_] != mode)
- {
- return false;
- }
- --top_;
- return true;
- }
-};
-
-typedef basic_json_parser<char> json_parser;
-typedef basic_json_parser<wchar_t> wjson_parser;
-
-}
-
-#endif
-
diff --git a/vendor/jsoncons-0.99.2/jsoncons/json_reader.hpp b/vendor/jsoncons-0.99.2/jsoncons/json_reader.hpp
deleted file mode 100644
index a0dd4641..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/json_reader.hpp
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright 2015 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_JSON_READER_HPP
-#define JSONCONS_JSON_READER_HPP
-
-#include <memory>
-#include <string>
-#include <sstream>
-#include <vector>
-#include <istream>
-#include <cstdlib>
-#include <stdexcept>
-#include <system_error>
-#include "jsoncons/jsoncons.hpp"
-#include "jsoncons/json_input_handler.hpp"
-#include "jsoncons/parse_error_handler.hpp"
-#include "jsoncons/json_parser.hpp"
-
-namespace jsoncons {
-
-template<typename CharT>
-class basic_json_reader
-{
- static const size_t default_max_buffer_length = 16384;
-
- basic_json_parser<CharT> parser_;
- std::basic_istream<CharT> *is_;
- basic_parse_error_handler<CharT> *err_handler_;
- bool eof_;
- std::vector<CharT> buffer_;
- size_t buffer_length_;
- size_t buffer_capacity_;
- size_t index_;
-public:
- basic_json_reader(std::basic_istream<CharT>& is,
- basic_json_input_handler<CharT>& handler)
- : parser_(handler),
- is_(std::addressof(is)),
- err_handler_(std::addressof(basic_default_parse_error_handler<CharT>::instance())),
- eof_(false),
- buffer_length_(0),
- buffer_capacity_(default_max_buffer_length),
- index_(0)
- {
- buffer_.resize(buffer_capacity_);
- }
-
- basic_json_reader(std::basic_istream<CharT>& is,
- basic_json_input_handler<CharT>& handler,
- basic_parse_error_handler<CharT>& err_handler)
- : parser_(handler,err_handler),
- is_(std::addressof(is)),
- err_handler_(std::addressof(err_handler)),
- eof_(false),
- buffer_length_(0),
- buffer_capacity_(default_max_buffer_length),
- index_(0)
- {
- buffer_.resize(buffer_capacity_);
- }
-
- size_t buffer_capacity() const
- {
- return buffer_capacity_;
- }
-
- void buffer_capacity(size_t capacity)
- {
- buffer_capacity_ = capacity;
- buffer_.resize(buffer_capacity_);
- }
-
- size_t max_nesting_depth() const
- {
- return parser_.max_nesting_depth();
- }
-
- void max_nesting_depth(size_t depth)
- {
- parser_.max_nesting_depth(depth);
- }
-
- void read_next()
- {
- parser_.begin_parse();
- while (!eof_ && !parser_.done())
- {
- if (!(index_ < buffer_length_))
- {
- if (!is_->eof())
- {
- is_->read(buffer_.data(), buffer_capacity_);
- buffer_length_ = static_cast<size_t>(is_->gcount());
- if (buffer_length_ == 0)
- {
- eof_ = true;
- }
- index_ = 0;
- }
- else
- {
- eof_ = true;
- }
- }
- if (!eof_)
- {
- parser_.parse(buffer_.data(),index_,buffer_length_);
- index_ = parser_.index();
- }
- }
- parser_.end_parse();
- }
-
- void check_done()
- {
- while (!eof_)
- {
- if (!(index_ < buffer_length_))
- {
- if (!is_->eof())
- {
- is_->read(buffer_.data(), buffer_capacity_);
- buffer_length_ = static_cast<size_t>(is_->gcount());
- if (buffer_length_ == 0)
- {
- eof_ = true;
- }
- index_ = 0;
- }
- else
- {
- eof_ = true;
- }
- }
- if (!eof_)
- {
- parser_.check_done(buffer_.data(),index_,buffer_length_);
- index_ = parser_.index();
- }
- }
- }
-
- bool eof() const
- {
- return eof_;
- }
-
-#if !defined(JSONCONS_NO_DEPRECATED)
- void read()
- {
- read_next();
- }
-
- size_t max_depth() const
- {
- return parser_.max_nesting_depth();
- }
-
- void max_depth(size_t depth)
- {
- parser_.max_nesting_depth(depth);
- }
-#endif
-};
-
-typedef basic_json_reader<char> json_reader;
-typedef basic_json_reader<wchar_t> wjson_reader;
-
-}
-
-#endif
-
diff --git a/vendor/jsoncons-0.99.2/jsoncons/json_serializer.hpp b/vendor/jsoncons-0.99.2/jsoncons/json_serializer.hpp
deleted file mode 100644
index d9f3bf4f..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/json_serializer.hpp
+++ /dev/null
@@ -1,435 +0,0 @@
-// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_JSON_SERIALIZER_HPP
-#define JSONCONS_JSON_SERIALIZER_HPP
-
-#include <string>
-#include <sstream>
-#include <vector>
-#include <istream>
-#include <ostream>
-#include <cstdlib>
-#include <limits> // std::numeric_limits
-#include <fstream>
-#include "jsoncons/jsoncons.hpp"
-#include "jsoncons/output_format.hpp"
-#include "jsoncons/json_output_handler.hpp"
-
-namespace jsoncons {
-
-template<typename CharT>
-class basic_json_serializer : public basic_json_output_handler<CharT>
-{
- static const size_t default_buffer_length = 16384;
-
- struct stack_item
- {
- stack_item(bool is_object)
- : is_object_(is_object), count_(0), option_(block_options::next_line), multiline_(false)
- {
- scalar_option_ = is_object ? block_options::next_line : block_options::same_line;
- }
- stack_item(bool is_object, block_options option)
- : is_object_(is_object), count_(0), option_(option), multiline_(false)
- {
- scalar_option_ = is_object ? block_options::next_line : block_options::same_line;
- }
- bool is_multiline() const
- {
- return multiline_;
- }
-
- bool is_object() const
- {
- return is_object_;
- }
-
- bool is_same_line() const
- {
- return option_ = block_options::same_line;
- }
-
- bool is_next_line() const
- {
- return option_ == block_options::next_line;
- }
-
- bool scalar_next_line() const
- {
- return scalar_option_ == block_options::next_line;
- }
-
- bool is_object_;
- size_t count_;
- block_options option_;
- block_options scalar_option_;
- bool multiline_;
- };
- basic_output_format<CharT> format_;
- std::vector<stack_item> stack_;
- int indent_;
- std::streamsize original_precision_;
- std::ios_base::fmtflags original_format_flags_;
- bool indenting_;
- float_printer<CharT> fp_;
- buffered_ostream<CharT> bos_;
-public:
- basic_json_serializer(std::basic_ostream<CharT>& os)
- : indent_(0),
- indenting_(false),
- fp_(format_.precision()),
- bos_(os)
- {
- }
-
- basic_json_serializer(std::basic_ostream<CharT>& os, bool indenting)
- : indent_(0),
- indenting_(indenting),
- fp_(format_.precision()),
- bos_(os)
- {
- }
-
- basic_json_serializer(std::basic_ostream<CharT>& os, const basic_output_format<CharT>& format)
- : format_(format),
- indent_(0),
- indenting_(false),
- fp_(format_.precision()),
- bos_(os)
- {
- }
- basic_json_serializer(std::basic_ostream<CharT>& os, const basic_output_format<CharT>& format, bool indenting)
- : format_(format),
- indent_(0),
- indenting_(indenting),
- fp_(format_.precision()),
- bos_(os)
- {
- }
-
- ~basic_json_serializer()
- {
- }
-
-private:
- // Implementing methods
- void do_begin_json() override
- {
- }
-
- void do_end_json() override
- {
- bos_.flush();
- }
-
- void do_begin_object() override
- {
- if (!stack_.empty() && !stack_.back().is_object())
- {
- if (!stack_.empty())
- {
- if (stack_.back().count_ > 0)
- {
- bos_. put(',');
- }
- }
- }
-
- if (indenting_)
- {
- if (!stack_.empty() && stack_.back().is_object())
- {
- if (format_.object_object_block_option() == block_options::next_line)
- {
- write_indent();
- }
- stack_.push_back(stack_item(true,format_.object_object_block_option()));
- }
- else if (!stack_.empty())
- {
- if (format_.array_object_block_option() == block_options::next_line)
- {
- write_indent();
- }
- stack_.push_back(stack_item(true,format_.array_object_block_option()));
- }
- else
- {
- stack_.push_back(stack_item(true));
- }
- indent();
- }
- else
- {
- stack_.push_back(stack_item(true));
- }
- bos_.put('{');
- }
-
- void do_end_object() override
- {
- JSONCONS_ASSERT(!stack_.empty());
- if (indenting_)
- {
- unindent();
- write_indent();
- }
- stack_.pop_back();
- bos_.put('}');
-
- end_value();
- }
-
-
- void do_begin_array() override
- {
- if (!stack_.empty() && !stack_.back().is_object())
- {
- if (!stack_.empty())
- {
- if (stack_.back().count_ > 0)
- {
- bos_. put(',');
- }
- }
- }
- if (indenting_)
- {
- if (!stack_.empty() && stack_.back().is_object())
- {
- if (format_.object_array_block_option() == block_options::next_line)
- {
- write_indent();
- }
- stack_.push_back(stack_item(false,format_.object_array_block_option()));
- }
- else if (!stack_.empty())
- {
- if (format_.array_array_block_option() == block_options::next_line)
- {
- write_indent();
- }
- stack_.push_back(stack_item(false,format_.array_array_block_option()));
- }
- else
- {
- stack_.push_back(stack_item(false));
- }
- indent();
- }
- else
- {
- stack_.push_back(stack_item(false));
- }
- bos_.put('[');
- }
-
- void do_end_array() override
- {
- JSONCONS_ASSERT(!stack_.empty());
- if (indenting_)
- {
- unindent();
- if (stack_.back().is_multiline())
- {
- write_indent();
- }
- }
- stack_.pop_back();
- bos_.put(']');
- end_value();
- }
-
- void do_name(const CharT* name, size_t length) override
- {
- if (!stack_.empty())
- {
- if (stack_.back().count_ > 0)
- {
- bos_. put(',');
- }
- if (indenting_)
- {
- if (stack_.back().scalar_next_line())
- {
- write_indent();
- }
- }
- }
-
- bos_.put('\"');
- escape_string<CharT>(name, length, format_, bos_);
- bos_.put('\"');
- bos_.put(':');
- bos_.put(' ');
- }
-
- void do_null_value() override
- {
- if (!stack_.empty() && !stack_.back().is_object())
- {
- begin_scalar_value();
- }
-
- auto buf = json_literals<CharT>::null_literal();
- bos_.write(buf.first,buf.second);
-
- end_value();
- }
-
- void do_string_value(const CharT* value, size_t length) override
- {
- if (!stack_.empty() && !stack_.back().is_object())
- {
- begin_scalar_value();
- }
-
- bos_. put('\"');
- escape_string<CharT>(value, length, format_, bos_);
- bos_. put('\"');
-
- end_value();
- }
-
- void do_double_value(double value, uint8_t precision) override
- {
- if (!stack_.empty() && !stack_.back().is_object())
- {
- begin_scalar_value();
- }
-
- if (is_nan(value) && format_.replace_nan())
- {
- bos_.write(format_.nan_replacement());
- }
- else if (is_pos_inf(value) && format_.replace_pos_inf())
- {
- bos_.write(format_.pos_inf_replacement());
- }
- else if (is_neg_inf(value) && format_.replace_neg_inf())
- {
- bos_.write(format_.neg_inf_replacement());
- }
- else
- {
- fp_.print(value,precision,bos_);
- }
-
- end_value();
- }
-
- void do_integer_value(int64_t value) override
- {
- if (!stack_.empty() && !stack_.back().is_object())
- {
- begin_scalar_value();
- }
- print_integer(value,bos_);
- end_value();
- }
-
- void do_uinteger_value(uint64_t value) override
- {
- if (!stack_.empty() && !stack_.back().is_object())
- {
- begin_scalar_value();
- }
- print_uinteger(value,bos_);
- end_value();
- }
-
- void do_bool_value(bool value) override
- {
- if (!stack_.empty() && !stack_.back().is_object())
- {
- begin_scalar_value();
- }
-
- if (value)
- {
- auto buf = json_literals<CharT>::true_literal();
- bos_.write(buf.first,buf.second);
- }
- else
- {
- auto buf = json_literals<CharT>::false_literal();
- bos_.write(buf.first,buf.second);
- }
-
- end_value();
- }
-
- void begin_scalar_value()
- {
- if (!stack_.empty())
- {
- if (stack_.back().count_ > 0)
- {
- bos_. put(',');
- }
- if (indenting_)
- {
- if (stack_.back().scalar_next_line())
- {
- write_indent();
- }
- }
- }
- }
-
- void begin_value()
- {
- if (!stack_.empty())
- {
- if (stack_.back().count_ > 0)
- {
- bos_. put(',');
- }
- if (indenting_ && stack_.back().is_next_line())
- {
- write_indent();
- }
- }
- }
-
- void end_value()
- {
- if (!stack_.empty())
- {
- ++stack_.back().count_;
- }
- }
-
- void indent()
- {
- indent_ += static_cast<int>(format_.indent());
- }
-
- void unindent()
- {
- indent_ -= static_cast<int>(format_.indent());
- }
-
- void write_indent()
- {
- if (!stack_.empty())
- {
- stack_.back().multiline_ = true;
- }
- bos_. put('\n');
- for (int i = 0; i < indent_; ++i)
- {
- bos_. put(' ');
- }
- }
-};
-
-typedef basic_json_serializer<char> json_serializer;
-typedef basic_json_serializer<wchar_t> wjson_serializer;
-
-}
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons/json_structures.hpp b/vendor/jsoncons-0.99.2/jsoncons/json_structures.hpp
deleted file mode 100644
index ee8f75af..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/json_structures.hpp
+++ /dev/null
@@ -1,860 +0,0 @@
-// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_JSON_STRUCTURES_HPP
-#define JSONCONS_JSON_STRUCTURES_HPP
-
-#include <string>
-#include <vector>
-#include <exception>
-#include <cstdlib>
-#include <cstring>
-#include <iostream>
-#include <algorithm>
-#include <sstream>
-#include <iomanip>
-#include <utility>
-#include <initializer_list>
-#include "jsoncons/jsoncons.hpp"
-
-namespace jsoncons {
-
-template <class JsonT, class Alloc>
-class json_array
-{
-public:
- typedef Alloc allocator_type;
- typedef JsonT value_type;
- typedef typename std::allocator_traits<Alloc>:: template rebind_alloc<JsonT> vector_allocator_type;
- typedef typename std::vector<JsonT,Alloc>::reference reference;
- typedef typename std::vector<JsonT,Alloc>::const_reference const_reference;
- typedef typename std::vector<JsonT,Alloc>::iterator iterator;
- typedef typename std::vector<JsonT,Alloc>::const_iterator const_iterator;
-
- json_array()
- : elements_()
- {
- }
-
- explicit json_array(const Alloc& allocator)
- : elements_(allocator)
- {
- }
-
- explicit json_array(size_t n, const Alloc& allocator = Alloc())
- : elements_(n,JsonT(),allocator)
- {
- }
-
- explicit json_array(size_t n, const JsonT& value, const Alloc& allocator = Alloc())
- : elements_(n,value,allocator)
- {
- }
-
- template <class InputIterator>
- json_array(InputIterator begin, InputIterator end, const Alloc& allocator = Alloc())
- : elements_(begin,end,allocator)
- {
- }
-
- json_array(const json_array& val)
- : elements_(val.elements_)
- {
- }
-
- json_array(const json_array& val, const Alloc& allocator)
- : elements_(val.elements_,allocator)
- {
- }
- json_array(json_array&& val)
- : elements_(std::move(val.elements_))
- {
- }
- json_array(json_array&& val, const Alloc& allocator)
- : elements_(std::move(val.elements_),allocator)
- {
- }
-
- json_array(std::initializer_list<JsonT> init,
- const Alloc& allocator = Alloc())
- : elements_(std::move(init),allocator)
- {
- }
-
- Alloc get_allocator() const
- {
- return elements_.get_allocator();
- }
-
- void swap(json_array<JsonT,Alloc>& val)
- {
- elements_.swap(val.elements_);
- }
-
- size_t size() const {return elements_.size();}
-
- size_t capacity() const {return elements_.capacity();}
-
- void clear() {elements_.clear();}
-
- void shrink_to_fit()
- {
- for (size_t i = 0; i < elements_.size(); ++i)
- {
- elements_[i].shrink_to_fit();
- }
- elements_.shrink_to_fit();
- }
-
- void reserve(size_t n) {elements_.reserve(n);}
-
- void resize(size_t n) {elements_.resize(n);}
-
- void resize(size_t n, const JsonT& val) {elements_.resize(n,val);}
-
- void remove_range(size_t from_index, size_t to_index)
- {
- JSONCONS_ASSERT(from_index <= to_index);
- JSONCONS_ASSERT(to_index <= elements_.size());
- elements_.erase(elements_.begin()+from_index,elements_.begin()+to_index);
- }
-
- void erase(iterator first, iterator last)
- {
- elements_.erase(first,last);
- }
-
- JsonT& operator[](size_t i) {return elements_[i];}
-
- const JsonT& operator[](size_t i) const {return elements_[i];}
-
- void push_back(const JsonT& value)
- {
- elements_.push_back(value);
- }
-
- void push_back(JsonT&& value)
- {
- elements_.push_back(std::move(value));
- }
-
- void add(size_t index, const JsonT& value)
- {
- auto position = index < elements_.size() ? elements_.begin() + index : elements_.end();
- elements_.insert(position, value);
- }
-
- void add(size_t index, JsonT&& value)
- {
- auto it = index < elements_.size() ? elements_.begin() + index : elements_.end();
- elements_.insert(it, std::move(value));
- }
-
-#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 9
- // work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54577
- iterator add(const_iterator pos, const JsonT& value)
- {
- iterator it = elements_.begin() + (pos - elements_.begin());
- return elements_.insert(it, value);
- }
-
- iterator add(const_iterator pos, JsonT&& value)
- {
- iterator it = elements_.begin() + (pos - elements_.begin());
- return elements_.insert(it, std::move(value));
- }
-#else
- iterator add(const_iterator pos, const JsonT& value)
- {
- return elements_.insert(pos, value);
- }
-
- iterator add(const_iterator pos, JsonT&& value)
- {
- return elements_.insert(pos, std::move(value));
- }
-#endif
-
- iterator begin() {return elements_.begin();}
-
- iterator end() {return elements_.end();}
-
- const_iterator begin() const {return elements_.begin();}
-
- const_iterator end() const {return elements_.end();}
-
- bool operator==(const json_array<JsonT,Alloc>& rhs) const
- {
- if (size() != rhs.size())
- {
- return false;
- }
- for (size_t i = 0; i < size(); ++i)
- {
- if (elements_[i] != rhs.elements_[i])
- {
- return false;
- }
- }
- return true;
- }
-private:
- json_array& operator=(const json_array<JsonT,Alloc>&);
- std::vector<JsonT,Alloc> elements_;
-};
-
-template <class ValueT,typename CharT>
-class member_lt_string
-{
- size_t length_;
-public:
- member_lt_string(size_t length)
- : length_(length)
- {
- }
-
- bool operator()(const ValueT& a, const CharT* b) const
- {
- size_t len = std::min JSONCONS_NO_MACRO_EXP(a.name().length(),length_);
- int result = std::char_traits<CharT>::compare(a.name().data(),b,len);
- if (result != 0)
- {
- return result < 0;
- }
-
- return a.name().length() < length_;
- }
-};
-
-template <class StringT,typename CharT>
-bool name_le_string(const StringT& a, const CharT* b, size_t length)
-{
- size_t min_len = std::min JSONCONS_NO_MACRO_EXP(a.length(),length);
- int result = std::char_traits<CharT>::compare(a.data(),b, min_len);
- if (result != 0)
- {
- return result < 0;
- }
-
- return a.length() <= length;
-}
-
-template <class StringT,typename CharT>
-bool name_eq_string(const StringT& a, const CharT* b, size_t length)
-{
- return a.length() == length && std::char_traits<CharT>::compare(a.data(),b,length) == 0;
-}
-
-template <class ValueT>
-class member_lt_member
-{
- typedef typename ValueT::char_type char_type;
-public:
- bool operator()(const ValueT& a, const ValueT& b) const
- {
- if (a.name().length() == b.name().length())
- {
- return std::char_traits<char_type>::compare(a.name().data(),b.name().data(),a.name().length()) < 0;
- }
-
- size_t len = std::min JSONCONS_NO_MACRO_EXP(a.name().length(),b.name().length());
- int result = std::char_traits<char_type>::compare(a.name().data(),b.name().data(),len);
- if (result != 0)
- {
- return result < 0;
- }
-
- return a.name().length() < b.name().length();
- }
-};
-
-template <class StringT, class ValueT>
-class name_value_pair
-{
-public:
- typedef StringT string_type;
- typedef typename StringT::value_type char_type;
-
- name_value_pair()
- {
- }
- name_value_pair(const string_type& name)
- : name_(name)
- {
- }
- name_value_pair(string_type&& name)
- : name_(std::move(name))
- {
- }
-
- name_value_pair(const string_type& name, const ValueT& val)
- : name_(name), value_(val)
- {
- }
- name_value_pair(string_type&& name, const ValueT& val)
- : name_(std::move(name)), value_(val)
- {
- }
- name_value_pair(const string_type& name, ValueT&& val)
- : name_(name), value_(std::move(val))
- {
- }
- name_value_pair(string_type&& name, ValueT&& val)
- : name_(std::move(name)), value_(std::move(val))
- {
- }
- name_value_pair(const name_value_pair& member)
- : name_(member.name_), value_(member.value_)
- {
- }
- name_value_pair(name_value_pair&& member)
- : name_(std::move(member.name_)), value_(std::move(member.value_))
- {
- }
-
- const string_type& name() const
- {
- return name_;
- }
-
- ValueT& value()
- {
- return value_;
- }
-
- const ValueT& value() const
- {
- return value_;
- }
-
- void value(const ValueT& value)
- {
- value_ = value;
- }
-
- void value(ValueT&& value)
- {
- value_ = std::move(value);
- }
-
- void swap(name_value_pair& member)
- {
- name_.swap(member.name_);
- value_.swap(member.value_);
- }
-
- name_value_pair& operator=(const name_value_pair& member)
- {
- if (this != & member)
- {
- name_ = member.name_;
- value_ = member.value_;
- }
- return *this;
- }
-
- name_value_pair& operator=(name_value_pair&& member)
- {
- if (this != &member)
- {
- name_.swap(member.name_);
- value_.swap(member.value_);
- }
- return *this;
- }
-
- void shrink_to_fit()
- {
- name_.shrink_to_fit();
- value_.shrink_to_fit();
- }
-private:
- string_type name_;
- ValueT value_;
-};
-
-template <class IteratorT,class NonConstIteratorT>
-class json_object_iterator
-{
-public:
- typedef IteratorT iterator;
- typedef typename std::iterator_traits<IteratorT>::value_type value_type;
- typedef typename std::iterator_traits<IteratorT>::difference_type difference_type;
- typedef typename std::iterator_traits<IteratorT>::pointer pointer;
- typedef typename std::iterator_traits<IteratorT>::reference reference;
- typedef std::bidirectional_iterator_tag iterator_category;
-
- json_object_iterator(bool empty = false)
- : empty_(empty)
- {
- }
-
- json_object_iterator(iterator it)
- : empty_(false), it_(it)
- {
- }
-
- json_object_iterator(const json_object_iterator<NonConstIteratorT,NonConstIteratorT>& it)
- : empty_(it.empty_), it_(it.it_)
- {
- }
-
- json_object_iterator& operator=(json_object_iterator rhs)
- {
- swap(*this,rhs);
- return *this;
- }
-
- json_object_iterator& operator++()
- {
- ++it_;
- return *this;
- }
-
- json_object_iterator operator++(int) // postfix increment
- {
- json_object_iterator temp(*this);
- ++it_;
- return temp;
- }
-
- json_object_iterator& operator--()
- {
- --it_;
- return *this;
- }
-
- json_object_iterator operator--(int)
- {
- json_object_iterator temp(*this);
- --it_;
- return temp;
- }
-
- reference operator*() const
- {
- return *it_;
- }
-
- pointer operator->() const
- {
- return &(*it_);
- }
-
- bool empty() const
- {
- return empty_;
- }
-
- friend bool operator==(const json_object_iterator& it1, const json_object_iterator& it2)
- {
- return (it1.empty() && it2.empty()) || (it1.it_ == it2.it_);
- }
- friend bool operator!=(const json_object_iterator& it1, const json_object_iterator& it2)
- {
- return !(it1.it_ == it2.it_);
- }
- friend void swap(json_object_iterator& lhs, json_object_iterator& rhs)
- {
- using std::swap;
- swap(lhs.it_,rhs.it_);
- swap(lhs.empty_,rhs.empty_);
- }
-
- iterator get()
- {
- return it_;
- }
-
-//private:
- bool empty_;
- IteratorT it_;
-};
-
-template <class StringT,class JsonT,class Alloc>
-class json_object
-{
-public:
- typedef Alloc allocator_type;
- typedef typename JsonT::char_type char_type;
- typedef StringT string_type;
- typedef name_value_pair<StringT,JsonT> value_type;
- typedef typename std::vector<value_type, allocator_type>::iterator base_iterator;
- typedef typename std::vector<value_type, allocator_type>::const_iterator const_base_iterator;
-
- typedef json_object_iterator<base_iterator,base_iterator> iterator;
- typedef json_object_iterator<const_base_iterator,base_iterator> const_iterator;
-private:
- std::vector<value_type,allocator_type> members_;
-public:
- json_object(const allocator_type& allocator = allocator_type())
- : members_(allocator)
- {
- }
-
- json_object(const json_object<StringT,JsonT,Alloc>& val)
- : members_(val.members_)
- {
- }
-
- json_object(json_object&& val)
- : members_(std::move(val.members_))
- {
- }
-
- json_object(const json_object<StringT,JsonT,Alloc>& val, const allocator_type& allocator) :
- members_(val.members_,allocator)
- {
- }
-
- json_object(json_object&& val,const allocator_type& allocator) :
- members_(std::move(val.members_),allocator)
- {
- }
-
- Alloc get_allocator() const
- {
- return members_.get_allocator();
- }
-
- iterator begin()
- {
- //return members_.begin();
- return iterator(members_.begin());
- }
-
- iterator end()
- {
- //return members_.end();
- return iterator(members_.end());
- }
-
- const_iterator begin() const
- {
- //return iterator(members.data());
- return const_iterator(members_.begin());
- }
-
- const_iterator end() const
- {
- //return members_.end();
- return const_iterator(members_.end());
- }
-/*
- const_iterator cbegin() const
- {
- return members_.begin();
- }
-
- const_iterator cend() const
- {
- return members_.end();
- }
-*/
- void swap(json_object& val)
- {
- members_.swap(val.members_);
- }
-
- size_t size() const {return members_.size();}
-
- size_t capacity() const {return members_.capacity();}
-
- void clear() {members_.clear();}
-
- void shrink_to_fit()
- {
- for (size_t i = 0; i < members_.size(); ++i)
- {
- members_[i].shrink_to_fit();
- }
- members_.shrink_to_fit();
- }
-
- void reserve(size_t n) {members_.reserve(n);}
-
- iterator find(const char_type* name, size_t length)
- {
- member_lt_string<value_type,char_type> comp(length);
- auto it = std::lower_bound(members_.begin(),members_.end(), name, comp);
- auto result = (it != members_.end() && name_eq_string(it->name(),name,length)) ? it : members_.end();
- return iterator(result);
- }
-
- const_iterator find(const char_type* name, size_t length) const
- {
- member_lt_string<value_type,char_type> comp(length);
- auto it = std::lower_bound(members_.begin(),members_.end(), name, comp);
- auto result = (it != members_.end() && name_eq_string(it->name(),name,length)) ? it : members_.end();
- return const_iterator(result);
- }
-
- void erase(iterator first, iterator last)
- {
- members_.erase(first.get(),last.get());
- }
-
- void erase(const char_type* name, size_t length)
- {
- member_lt_string<value_type,char_type> comp(length);
- auto it = std::lower_bound(members_.begin(),members_.end(), name, comp);
- if (it != members_.end() && name_eq_string(it->name(),name,length))
- {
- members_.erase(it);
- }
- }
-
- template<class InputIt, class UnaryPredicate>
- void insert(InputIt first, InputIt last, UnaryPredicate pred)
- {
- size_t count = std::distance(first,last);
- size_t pos = members_.size();
- members_.resize(pos+count);
- auto d = members_.begin()+pos;
- for (auto s = first; s != last; ++s, ++d)
- {
- *d = pred(*s);
- }
- std::sort(members_.begin(),members_.end(),member_lt_member<value_type>());
- }
-
- void set(const char_type* s, size_t length, const JsonT& value)
- {
- auto it = std::lower_bound(members_.begin(),members_.end(),s,member_lt_string<value_type,char_type>(length));
- if (it == members_.end())
- {
- members_.push_back(value_type(string_type(s,length),value));
- }
- else if (name_eq_string(it->name(),s,length))
- {
- it->value(value);
- }
- else
- {
- members_.insert(it,value_type(string_type(s,length),value));
- }
- }
-
- void set(const char_type* s, size_t length, JsonT&& value)
- {
- auto it = std::lower_bound(members_.begin(),members_.end(),s,member_lt_string<value_type,char_type>(length));
- if (it == members_.end())
- {
- members_.push_back(value_type(string_type(s,length),std::move(value)));
- }
- else if (name_eq_string(it->name(),s,length))
- {
- it->value(std::move(value));
- }
- else
- {
- members_.insert(it,value_type(string_type(s,length),std::move(value)));
- }
- }
-
- void set(string_type&& name, const JsonT& value)
- {
- auto it = std::lower_bound(members_.begin(),members_.end(),name.data() ,member_lt_string<value_type,char_type>(name.length()));
- if (it == members_.end())
- {
- members_.push_back(value_type(std::move(name), value));
- }
- else if (it->name() == name)
- {
- it->value(value);
- }
- else
- {
- members_.insert(it,value_type(std::move(name),value));
- }
- }
-
- void set(const string_type& name, const JsonT& value)
- {
- set(name.data(),name.length(),value);
- }
-
- void set(const string_type& name, JsonT&& value)
- {
- set(name.data(),name.length(),std::move(value));
- }
-
- void set(string_type&& name, JsonT&& value)
- {
- auto it = std::lower_bound(members_.begin(),members_.end(),name.data() ,member_lt_string<value_type,char_type>(name.length()));
- if (it == members_.end())
- {
- members_.push_back(value_type(std::move(name), std::move(value)));
- }
- else if (it->name() == name)
- {
- it->value(std::move(value));
- }
- else
- {
- members_.insert(it,value_type(std::move(name),std::move(value)));
- }
- }
-
- iterator set(iterator hint, const char_type* name, const JsonT& value)
- {
- return set(hint, name, std::char_traits<char_type>::length(name), value);
- }
-
- iterator set(iterator hint, const char_type* name, JsonT&& value)
- {
- return set(hint, name, std::char_traits<char_type>::length(name), std::move(value));
- }
-
- iterator set(iterator hint, const char_type* s, size_t length, const JsonT& value)
- {
- base_iterator it;
- if (hint.get() != members_.end() && name_le_string(hint.get()->name(), s, length))
- {
- it = std::lower_bound(hint.get(),members_.end(),s,member_lt_string<value_type,char_type>(length));
- }
- else
- {
- it = std::lower_bound(members_.begin(),members_.end(),s, member_lt_string<value_type,char_type>(length));
- }
-
- if (it == members_.end())
- {
- members_.push_back(value_type(string_type(s, length), value));
- it = members_.begin() + (members_.size() - 1);
- }
- else if (name_eq_string(it->name(),s,length))
- {
- it->value(value);
- }
- else
- {
- it = members_.insert(it,value_type(string_type(s,length),value));
- }
- return iterator(it);
- }
-
- iterator set(iterator hint, const char_type* s, size_t length, JsonT&& value)
- {
- base_iterator it;
- if (hint.get() != members_.end() && name_le_string(hint.get()->name(), s, length))
- {
- it = std::lower_bound(hint.get(),members_.end(),s,member_lt_string<value_type,char_type>(length));
- }
- else
- {
- it = std::lower_bound(members_.begin(),members_.end(),s, member_lt_string<value_type,char_type>(length));
- }
-
- if (it == members_.end())
- {
- members_.push_back(value_type(string_type(s, length), std::move(value)));
- it = members_.begin() + (members_.size() - 1);
- }
- else if (name_eq_string(it->name(),s,length))
- {
- it->value(std::move(value));
- }
- else
- {
- it = members_.insert(it,value_type(string_type(s,length),std::move(value)));
- }
- return iterator(it);
- }
-
- iterator set(iterator hint, const string_type& name, const JsonT& value)
- {
- return set(hint,name.data(),name.length(),value);
- }
-
- iterator set(iterator hint, string_type&& name, const JsonT& value)
- {
- base_iterator it;
- if (hint.get() != members_.end() && hint.get()->name() <= name)
- {
- it = std::lower_bound(hint.get(),members_.end(),name.data() ,member_lt_string<value_type,char_type>(name.length()));
- }
- else
- {
- it = std::lower_bound(members_.begin(),members_.end(),name.data() ,member_lt_string<value_type,char_type>(name.length()));
- }
-
- if (it == members_.end())
- {
- members_.push_back(value_type(std::move(name), value));
- it = members_.begin() + (members_.size() - 1);
- }
- else if (it->name() == name)
- {
- it->value(value);
- }
- else
- {
- it = members_.insert(it,value_type(std::move(name),value));
- }
- return iterator(it);
- }
-
- iterator set(iterator hint, const string_type& name, JsonT&& value)
- {
- return set(hint,name.data(),name.length(),std::move(value));
- }
-
- iterator set(iterator hint, string_type&& name, JsonT&& value)
- {
- typename std::vector<value_type,allocator_type>::iterator it;
- if (hint.get() != members_.end() && hint.get()->name() <= name)
- {
- it = std::lower_bound(hint.get(),members_.end(),name.data() ,member_lt_string<value_type,char_type>(name.length()));
- }
- else
- {
- it = std::lower_bound(members_.begin(),members_.end(),name.data() ,member_lt_string<value_type,char_type>(name.length()));
- }
-
- if (it == members_.end())
- {
- members_.push_back(value_type(std::move(name), std::move(value)));
- it = members_.begin() + (members_.size() - 1);
- }
- else if (it->name() == name)
- {
- it->value(std::move(value));
- }
- else
- {
- it = members_.insert(it,value_type(std::move(name),std::move(value)));
- }
- return iterator(it);
- }
-
- bool operator==(const json_object<StringT,JsonT,Alloc>& rhs) const
- {
- if (size() != rhs.size())
- {
- return false;
- }
- for (auto it = members_.begin(); it != members_.end(); ++it)
- {
-
- auto rhs_it = std::lower_bound(rhs.members_.begin(), rhs.members_.end(), *it, member_lt_member<value_type>());
- // member_lt_member actually only compares keys, so we need to check the value separately
- if (rhs_it == rhs.members_.end() || rhs_it->name() != it->name() || rhs_it->value() != it->value())
- {
- return false;
- }
- }
- return true;
- }
-private:
- json_object<StringT,JsonT,Alloc>& operator=(const json_object<StringT,JsonT,Alloc>&);
-};
-
-
-
-}
-
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons/json_type_traits.hpp b/vendor/jsoncons-0.99.2/jsoncons/json_type_traits.hpp
deleted file mode 100644
index aeda7a0b..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/json_type_traits.hpp
+++ /dev/null
@@ -1,594 +0,0 @@
-// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_JSON_TYPE_TRAITS_HPP
-#define JSONCONS_JSON_TYPE_TRAITS_HPP
-
-#include <string>
-#include <vector>
-#include <exception>
-#include <cstdlib>
-#include <cstring>
-#include <utility>
-#include <algorithm>
-#include <fstream>
-#include <limits>
-#include "jsoncons/jsoncons.hpp"
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wswitch"
-#endif
-
-namespace jsoncons {
-
-template <class JsonT, typename T>
-class json_type_traits
-{
-public:
- static bool is(const JsonT&)
- {
- return false;
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, typename JsonT::string_type>
-{
-public:
- typedef typename JsonT::string_type string_type;
- typedef typename string_type::allocator_type string_allocator;
-
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- return rhs.is_string();
- }
- static string_type as(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- return rhs.as_string();
- }
- static string_type as(const JsonT& rhs, const string_allocator& allocator) JSONCONS_NOEXCEPT
- {
- return rhs.as_string(allocator);
- }
- static void assign(JsonT& lhs, const string_type& rhs)
- {
- lhs.assign_string(rhs);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, typename JsonT::any>
-{
-public:
- static bool is(const JsonT& lhs) JSONCONS_NOEXCEPT
- {
- return lhs.is_any();
- }
- static typename JsonT::any as(const JsonT& rhs)
- {
- return rhs.any_value();
- }
- static void assign(JsonT& lhs, typename JsonT::any rhs)
- {
- lhs.assign_any(rhs);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, typename type_wrapper<typename JsonT::char_type>::const_pointer_type>
-{
-public:
- typedef typename JsonT::char_type char_type;
-
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- return rhs.is_string();
- }
- static const char_type* as(const JsonT& rhs)
- {
- return rhs.as_cstring();
- }
- static void assign(JsonT& lhs, const char_type *rhs)
- {
- size_t length = std::char_traits<char_type>::length(rhs);
- lhs.assign_string(rhs,length);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, typename type_wrapper<typename JsonT::char_type>::pointer_type>
-{
-public:
- typedef typename JsonT::char_type char_type;
-
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- return rhs.is_string();
- }
- static const char_type* as(const JsonT& rhs)
- {
- return rhs.as_cstring();
- }
- static void assign(JsonT& lhs, const char_type *rhs)
- {
- size_t length = std::char_traits<char_type>::length(rhs);
- lhs.assign_string(rhs,length);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, char>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- if (rhs.is_integer())
- {
- return rhs.as_integer() >= std::numeric_limits<char>::min JSONCONS_NO_MACRO_EXP() && rhs.as_integer() <= std::numeric_limits<char>::max JSONCONS_NO_MACRO_EXP();
- }
- else
- {
- return false;
- }
- }
- static char as(const JsonT& rhs)
- {
- return static_cast<char>(rhs.as_integer());
- }
- static void assign(JsonT& lhs, char ch)
- {
- lhs.assign_integer(ch);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, unsigned char>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- if (rhs.is_integer())
- {
- return rhs.as_integer() >= 0 && static_cast<unsigned long long>(rhs.as_integer()) <= std::numeric_limits<unsigned char>::max JSONCONS_NO_MACRO_EXP();
- }
- else if (rhs.is_uinteger())
- {
- return rhs.as_uinteger() <= std::numeric_limits<unsigned char>::max JSONCONS_NO_MACRO_EXP();
- }
- else
- {
- return false;
- }
- }
- static unsigned char as(const JsonT& rhs)
- {
- return static_cast<unsigned char>(rhs.as_uinteger());
- }
- static void assign(JsonT& lhs, unsigned char ch)
- {
- lhs.assign_uinteger(ch);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, signed char>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- if (rhs.is_integer())
- {
- return rhs.as_integer() >= std::numeric_limits<char>::min JSONCONS_NO_MACRO_EXP() && rhs.as_integer() <= std::numeric_limits<char>::max JSONCONS_NO_MACRO_EXP();
- }
- else if (rhs.is_uinteger())
- {
- return rhs.as_uinteger() <= static_cast<unsigned long long>(std::numeric_limits<char>::max JSONCONS_NO_MACRO_EXP());
- }
- else
- {
- return false;
- }
- }
- static signed char as(const JsonT& rhs)
- {
- return static_cast<signed char>(rhs.as_integer());
- }
- static void assign(JsonT& lhs, signed char ch)
- {
- lhs.assign_integer(ch);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, wchar_t>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- if (rhs.is_integer())
- {
- return rhs.as_integer() >= std::numeric_limits<wchar_t>::min JSONCONS_NO_MACRO_EXP() && rhs.as_integer() <= std::numeric_limits<wchar_t>::max JSONCONS_NO_MACRO_EXP();
- }
- else if (rhs.is_uinteger())
- {
- return rhs.as_uinteger() <= static_cast<unsigned long long>(std::numeric_limits<wchar_t>::max JSONCONS_NO_MACRO_EXP());
- }
- else
- {
- return false;
- }
- }
- static wchar_t as(const JsonT& rhs)
- {
- return static_cast<wchar_t>(rhs.as_integer());
- }
- static void assign(JsonT& lhs, wchar_t ch)
- {
- lhs.assign_integer(ch);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, typename JsonT::object>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- return rhs.is_object();
- }
- static typename JsonT::object as(JsonT rhs)
- {
- JSONCONS_ASSERT(rhs.is_object());
- return rhs.object_value();
- }
- static void assign(JsonT& lhs, typename JsonT::object rhs)
- {
- lhs.assign_object(rhs);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, typename JsonT::array>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- return rhs.is_array();
- }
- static typename JsonT::array as(const JsonT& rhs)
- {
- JSONCONS_ASSERT(rhs.is_array());
- return rhs.array_value();
- }
- static void assign(JsonT& lhs, typename JsonT::array rhs)
- {
- lhs.assign_array(rhs);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, jsoncons::null_type>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- return rhs.is_null();
- }
- static typename jsoncons::null_type as(const JsonT& rhs)
- {
- JSONCONS_ASSERT(rhs.is_null());
- return jsoncons::null_type();
- }
- static void assign(JsonT& lhs, null_type)
- {
- lhs.assign_null();
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, bool>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- return rhs.is_bool();
- }
- static bool as(const JsonT& rhs)
- {
- return rhs.as_bool();
- }
- static void assign(JsonT& lhs, bool rhs)
- {
- lhs.assign_bool(rhs);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, short>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- if (rhs.is_integer())
- {
- return rhs.as_integer() >= std::numeric_limits<short>::min JSONCONS_NO_MACRO_EXP() && rhs.as_integer() <= std::numeric_limits<short>::max JSONCONS_NO_MACRO_EXP();
- }
- else if (rhs.is_uinteger())
- {
- return rhs.as_uinteger() <= static_cast<unsigned long long>(std::numeric_limits<short>::max JSONCONS_NO_MACRO_EXP());
- }
- else
- {
- return false;
- }
- }
- static short as(const JsonT& rhs)
- {
- return static_cast<short>(rhs.as_integer());
- }
- static void assign(JsonT& lhs, short rhs)
- {
- lhs.assign_integer(rhs);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, unsigned short>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- if (rhs.is_integer())
- {
- return rhs.as_integer() >= 0 && static_cast<unsigned long long>(rhs.as_integer()) <= std::numeric_limits<unsigned short>::max JSONCONS_NO_MACRO_EXP();
- }
- else if (rhs.is_uinteger())
- {
- return rhs.as_uinteger() <= std::numeric_limits<unsigned short>::max JSONCONS_NO_MACRO_EXP();
- }
- else
- {
- return false;
- }
- }
- static unsigned short as(const JsonT& rhs)
- {
- return (unsigned short)rhs.as_uinteger();
- }
- static void assign(JsonT& lhs, unsigned short rhs)
- {
- lhs.assign_uinteger(rhs);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, int>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- if (rhs.is_integer())
- {
- return rhs.as_integer() >= std::numeric_limits<int>::min JSONCONS_NO_MACRO_EXP() && rhs.as_integer() <= std::numeric_limits<int>::max JSONCONS_NO_MACRO_EXP();
- }
- else if (rhs.is_uinteger())
- {
- return rhs.as_uinteger() <= static_cast<unsigned long long>(std::numeric_limits<int>::max JSONCONS_NO_MACRO_EXP());
- }
- else
- {
- return false;
- }
- }
- static int as(const JsonT& rhs)
- {
- return static_cast<int>(rhs.as_integer());
- }
- static void assign(JsonT& lhs, int rhs)
- {
- lhs.assign_integer(rhs);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, unsigned int>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- if (rhs.is_integer())
- {
- return rhs.as_integer() >= 0 && static_cast<unsigned long long>(rhs.as_integer()) <= std::numeric_limits<unsigned int>::max JSONCONS_NO_MACRO_EXP();
- }
- else if (rhs.is_uinteger())
- {
- return rhs.as_uinteger() <= std::numeric_limits<unsigned int>::max JSONCONS_NO_MACRO_EXP();
- }
- else
- {
- return false;
- }
- }
- static unsigned int as(const JsonT& rhs)
- {
- return static_cast<unsigned int>(rhs.as_uinteger());
- }
- static void assign(JsonT& lhs, unsigned int rhs)
- {
- lhs.assign_uinteger(rhs);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, long>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- if (rhs.is_integer())
- {
- return rhs.as_integer() >= std::numeric_limits<long>::min JSONCONS_NO_MACRO_EXP() && rhs.as_integer() <= std::numeric_limits<long>::max JSONCONS_NO_MACRO_EXP();
- }
- else if (rhs.is_uinteger())
- {
- return rhs.as_uinteger() <= static_cast<unsigned long long>(std::numeric_limits<long>::max JSONCONS_NO_MACRO_EXP());
- }
- else
- {
- return false;
- }
- }
- static long as(const JsonT& rhs)
- {
- return static_cast<long>(rhs.as_integer());
- }
- static void assign(JsonT& lhs, long rhs)
- {
- lhs.assign_integer(rhs);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, unsigned long>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- if (rhs.is_integer())
- {
- return rhs.as_integer() >= 0 && static_cast<unsigned long long>(rhs.as_integer()) <= std::numeric_limits<unsigned long>::max JSONCONS_NO_MACRO_EXP();
- }
- else if (rhs.is_uinteger())
- {
- return rhs.as_uinteger() <= std::numeric_limits<unsigned long>::max JSONCONS_NO_MACRO_EXP();
- }
- else
- {
- return false;
- }
- }
- static unsigned long as(const JsonT& rhs)
- {
- return static_cast<unsigned long>(rhs.as_uinteger());
- }
- static void assign(JsonT& lhs, unsigned long rhs)
- {
- lhs.assign_uinteger(rhs);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, long long>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- return rhs.is_integer();
- }
- static long long as(const JsonT& rhs)
- {
- return rhs.as_integer();
- }
- static void assign(JsonT& lhs, long long rhs)
- {
- lhs.assign_integer(rhs);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, unsigned long long>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- return rhs.is_uinteger();
- }
- static unsigned long long as(const JsonT& rhs)
- {
- return rhs.as_uinteger();
- }
- static void assign(JsonT& lhs, unsigned long long rhs)
- {
- lhs.assign_uinteger(rhs);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, double>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- return rhs.is_double();
- }
-
- static double as(const JsonT& rhs)
- {
- return rhs.as_double();
- }
- static void assign(JsonT& lhs, double rhs)
- {
- lhs.assign_double(rhs);
- }
-};
-
-template<class JsonT>
-class json_type_traits<JsonT, float>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- return rhs.is_double();
- }
- static double as(const JsonT& rhs)
- {
- return static_cast<float>(rhs.as_double());
- }
- static void assign(JsonT& lhs, float rhs)
- {
- lhs.assign_double(static_cast<double>(rhs));
- }
-};
-
-template<class JsonT, typename T>
-class json_type_traits<JsonT, std::vector<T>>
-{
-public:
- static bool is(const JsonT& rhs) JSONCONS_NOEXCEPT
- {
- bool result = rhs.is_array();
- for (size_t i = 0; result && i < rhs.size(); ++i)
- {
- if (!rhs[i].template is<T>())
- {
- result = false;
- }
- }
- return result;
- }
- static std::vector<T> as(const JsonT& rhs)
- {
- std::vector<T> v(rhs.size());
- for (size_t i = 0; i < v.size(); ++i)
- {
- v[i] = rhs[i].template as<T>();
- }
- return v;
- }
- static void assign(JsonT& lhs, const std::vector<T>& rhs)
- {
- lhs = JsonT(rhs.begin(), rhs.end());
- }
-};
-
-}
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
-
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons/jsoncons.hpp b/vendor/jsoncons-0.99.2/jsoncons/jsoncons.hpp
deleted file mode 100644
index a45e4f8c..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/jsoncons.hpp
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_JSONCONS_HPP
-#define JSONCONS_JSONCONS_HPP
-
-#include <locale>
-#include <string>
-#include <vector>
-#include <cstdlib>
-#include <cwchar>
-#include <cstdint>
-#include <iostream>
-#include <vector>
-#include "jsoncons/jsoncons_config.hpp"
-#include "jsoncons/jsoncons_io.hpp"
-
-namespace jsoncons {
-
-// null_type
-
-struct null_type
-{
-};
-
-// json_exception
-
-class json_exception
-{
-public:
- virtual const char* what() const JSONCONS_NOEXCEPT = 0;
-};
-
-template <typename Base>
-class json_exception_0 : public Base, public virtual json_exception
-{
-public:
- json_exception_0(std::string s) JSONCONS_NOEXCEPT
- : Base(""), message_(s)
- {
- }
- ~json_exception_0() JSONCONS_NOEXCEPT
- {
- }
- const char* what() const JSONCONS_NOEXCEPT
- {
- return message_.c_str();
- }
-private:
- std::string message_;
-};
-
-template <typename Base>
-class json_exception_1 : public Base, public virtual json_exception
-{
-public:
- json_exception_1(const std::string& format, const std::string& arg1) JSONCONS_NOEXCEPT
- : Base(""), format_(format), arg1_(arg1)
- {
- }
- json_exception_1(const std::string& format, const std::wstring& arg1) JSONCONS_NOEXCEPT
- : Base(""), format_(format)
- {
- char buf[255];
- size_t retval;
-#if defined(JSONCONS_HAS_WCSTOMBS_S)
- wcstombs_s(&retval, buf, sizeof(buf), arg1.c_str(), arg1.size());
-#else
- retval = wcstombs(buf, arg1.c_str(), sizeof(buf));
-#endif
- if (retval != static_cast<std::size_t>(-1))
- {
- arg1_ = buf;
- }
- }
- ~json_exception_1() JSONCONS_NOEXCEPT
- {
- }
- const char* what() const JSONCONS_NOEXCEPT
- {
- c99_snprintf(const_cast<char*>(message_),255, format_.c_str(),arg1_.c_str());
- return message_;
- }
-private:
- std::string format_;
- std::string arg1_;
- char message_[255];
-};
-
-#define JSONCONS_STR2(x) #x
-#define JSONCONS_STR(x) JSONCONS_STR2(x)
-
-#define JSONCONS_THROW_EXCEPTION(Base,x) throw jsoncons::json_exception_0<Base>((x))
-#define JSONCONS_THROW_EXCEPTION_1(Base,fmt,arg1) throw jsoncons::json_exception_1<Base>((fmt),(arg1))
-#define JSONCONS_ASSERT(x) if (!(x)) { \
- throw jsoncons::json_exception_0<std::runtime_error>("assertion '" #x "' failed at " __FILE__ ":" \
- JSONCONS_STR(__LINE__)); }
-
-// json_char_traits
-
-const uint16_t min_lead_surrogate = 0xD800;
-const uint16_t max_lead_surrogate = 0xDBFF;
-const uint16_t min_trail_surrogate = 0xDC00;
-const uint16_t max_trail_surrogate = 0xDFFF;
-
-template <typename CharT>
-struct json_literals
-{
-};
-
-template <>
-struct json_literals<char>
-{
- static std::pair<const char*,size_t> null_literal()
- {
- static const char* value = "null";
- return std::pair<const char*,size_t>(value,4);
- }
-
- static std::pair<const char*,size_t> true_literal()
- {
- static const char* value = "true";
- return std::pair<const char*,size_t>(value,4);
- }
-
- static std::pair<const char*,size_t> false_literal()
- {
- static const char* value = "false";
- return std::pair<const char*,size_t>(value,5);
- }
-};
-
-template <>
-struct json_literals<wchar_t>
-{
- static std::pair<const wchar_t*,size_t> null_literal()
- {
- static const wchar_t* value = L"null";
- return std::pair<const wchar_t*,size_t>(value,4);
- }
-
- static std::pair<const wchar_t*,size_t> true_literal()
- {
- static const wchar_t* value = L"true";
- return std::pair<const wchar_t*,size_t>(value,4);
- }
-
- static std::pair<const wchar_t*,size_t> false_literal()
- {
- static const wchar_t* value = L"false";
- return std::pair<const wchar_t*,size_t>(value,5);
- }
-};
-
-template <typename CharT,size_t Size>
-struct json_char_traits
-{
-};
-
-template <>
-struct json_char_traits<char,1>
-{
- static uint32_t convert_char_to_codepoint(const char*& it,
- const char*)
- {
- char c = *it;
- uint32_t u(c >= 0 ? c : 256 + c );
- uint32_t cp = u;
- if (u < 0x80)
- {
- }
- else if ((u >> 5) == 0x6)
- {
- c = *(++it);
- u = (c >= 0 ? c : 256 + c );
- cp = ((cp << 6) & 0x7ff) + (u & 0x3f);
- }
- else if ((u >> 4) == 0xe)
- {
- c = *(++it);
- u = (c >= 0 ? c : 256 + c );
- cp = ((cp << 12) & 0xffff) + ((static_cast<uint32_t>(0xff & u) << 6) & 0xfff);
- c = *(++it);
- u = (c >= 0 ? c : 256 + c );
- cp += (u) & 0x3f;
- }
- else if ((u >> 3) == 0x1e)
- {
- c = *(++it);
- u = (c >= 0 ? c : 256 + c );
- cp = ((cp << 18) & 0x1fffff) + ((static_cast<uint32_t>(0xff & u) << 12) & 0x3ffff);
- c = *(++it);
- u = (c >= 0 ? c : 256 + c );
- cp += (static_cast<uint32_t>(0xff & u) << 6) & 0xfff;
- c = *(++it);
- u = (c >= 0 ? c : 256 + c );
- cp += (u) & 0x3f;
- }
- else
- {
- }
- return cp;
- }
-
- static void append_codepoint_to_string(uint32_t cp, std::string& s)
- {
- if (cp <= 0x7f)
- {
- s.push_back(static_cast<char>(cp));
- }
- else if (cp <= 0x7FF)
- {
- s.push_back(static_cast<char>(0xC0 | (0x1f & (cp >> 6))));
- s.push_back(static_cast<char>(0x80 | (0x3f & cp)));
- }
- else if (cp <= 0xFFFF)
- {
- s.push_back(0xE0 | static_cast<char>((0xf & (cp >> 12))));
- s.push_back(0x80 | static_cast<char>((0x3f & (cp >> 6))));
- s.push_back(static_cast<char>(0x80 | (0x3f & cp)));
- }
- else if (cp <= 0x10FFFF)
- {
- s.push_back(static_cast<char>(0xF0 | (0x7 & (cp >> 18))));
- s.push_back(static_cast<char>(0x80 | (0x3f & (cp >> 12))));
- s.push_back(static_cast<char>(0x80 | (0x3f & (cp >> 6))));
- s.push_back(static_cast<char>(0x80 | (0x3f & cp)));
- }
- }
-
-};
-
-template <>
-struct json_char_traits<wchar_t,2> // assume utf16
-{
- static void append_codepoint_to_string(uint32_t cp, std::wstring& s)
- {
- if (cp <= 0xFFFF)
- {
- s.push_back(static_cast<wchar_t>(cp));
- }
- else if (cp <= 0x10FFFF)
- {
- s.push_back(static_cast<wchar_t>((cp >> 10) + min_lead_surrogate - (0x10000 >> 10)));
- s.push_back(static_cast<wchar_t>((cp & 0x3ff) + min_trail_surrogate));
- }
- }
-
- static uint32_t convert_char_to_codepoint(const wchar_t*& it, const wchar_t*)
- {
- uint32_t cp = (0xffff & *it);
- if ((cp >= min_lead_surrogate && cp <= max_lead_surrogate)) // surrogate pair
- {
- uint32_t trail_surrogate = 0xffff & *(++it);
- cp = (cp << 10) + trail_surrogate + 0x10000u - (min_lead_surrogate << 10) - min_trail_surrogate;
- }
- return cp;
- }
-};
-
-template <>
-struct json_char_traits<wchar_t,4> // assume utf32
-{
- static void append_codepoint_to_string(uint32_t cp, std::wstring& s)
- {
- if (cp <= 0xFFFF)
- {
- s.push_back(static_cast<wchar_t>(cp));
- }
- else if (cp <= 0x10FFFF)
- {
- s.push_back(static_cast<wchar_t>(cp));
- }
- }
-
- static uint32_t convert_char_to_codepoint(const wchar_t*& it, const wchar_t*)
- {
- uint32_t cp = static_cast<uint32_t>(*it);
- return cp;
- }
-};
-
-inline
-bool is_control_character(uint32_t c)
-{
- return c <= 0x1F || c == 0x7f;
-}
-
-inline
-char to_hex_character(unsigned char c)
-{
- JSONCONS_ASSERT(c <= 0xF);
-
- return (c < 10) ? ('0' + c) : ('A' - 10 + c);
-}
-
-inline
-bool is_non_ascii_character(uint32_t c)
-{
- return c >= 0x80;
-}
-
-template <typename T>
-struct type_wrapper
-{
- typedef T* pointer_type;
- typedef const T* const_pointer_type;
- typedef T value_type;
- typedef T& reference;
- typedef const T& const_reference;
-};
-
-template <typename T>
-struct type_wrapper<const T>
-{
- typedef T* pointer_type;
- typedef const T* const_pointer_type;
- typedef T value_type;
- typedef T& reference;
- typedef const T& const_reference;
-};
-
-template <typename T>
-struct type_wrapper<T&>
-{
- typedef T* pointer_type;
- typedef const T* const_pointer_type;
- typedef T value_type;
- typedef T& reference;
- typedef const T& const_reference;
-};
-
-template <typename T>
-struct type_wrapper<const T&>
-{
- typedef T* pointer_type;
- typedef const T* const_pointer_type;
- typedef T value_type;
- typedef T& reference;
- typedef const T& const_reference;
-};
-
-}
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons/jsoncons_config.hpp b/vendor/jsoncons-0.99.2/jsoncons/jsoncons_config.hpp
deleted file mode 100644
index 7d261ec0..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/jsoncons_config.hpp
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_JSONCONS_CONFIG_HPP
-#define JSONCONS_JSONCONS_CONFIG_HPP
-
-#include <stdexcept>
-#include <string>
-#include <sstream>
-#include <vector>
-#include <istream>
-#include <ostream>
-#include <iomanip>
-#include <cstdlib>
-#include <cmath>
-#include <cstdarg>
-#include <limits> // std::numeric_limits
-
-// Uncomment the following line to suppress deprecated names (recommended for new code)
-// #define JSONCONS_NO_DEPRECATED
-
-#define JSONCONS_NO_MACRO_EXP
-
-namespace jsoncons
-{
-
-// Follow boost
-
-#if defined (__clang__)
-#if defined(_GLIBCXX_USE_NOEXCEPT)
-#define JSONCONS_NOEXCEPT _GLIBCXX_USE_NOEXCEPT
-#else
-#define JSONCONS_NOEXCEPT noexcept
-#endif
-#elif defined(__GNUC__)
-#define JSONCONS_NOEXCEPT _GLIBCXX_USE_NOEXCEPT
-#elif defined(_MSC_VER)
-#if _MSC_VER >= 1900
-#define JSONCONS_NOEXCEPT noexcept
-#else
-#define JSONCONS_NOEXCEPT
-#endif
-#else
-#define JSONCONS_NOEXCEPT
-#endif
-
-#if defined(_MSC_VER)
-#define JSONCONS_HAS_FOPEN_S
-#define JSONCONS_HAS_WCSTOMBS_S
-#if _MSC_VER < 1800 // VS2013
-#define JSONCONS_NO_RAW_STRING_LITERALS
-#define JSONCONS_NO_FOR_RANGE
-#endif
-#if _MSC_VER >= 1900
-#define JSONCONS_ALIGNOF alignof
-#else
-#define JSONCONS_ALIGNOF __alignof
-#endif
-#else
-#define JSONCONS_ALIGNOF alignof
-#endif
-
-#ifdef _MSC_VER
-#pragma warning( disable : 4290 )
-inline bool is_nan(double x) { return _isnan(x) != 0; }
-inline bool is_inf(double x)
-{
- return !_finite(x) && !_isnan(x);
-}
-inline bool is_pos_inf(double x)
-{
- return is_inf(x) && x > 0;
-}
-inline bool is_neg_inf(double x)
-{
- return is_inf(x) && x < 0;
-}
-
-inline
-int c99_vsnprintf(char *str, size_t size, const char *format, va_list ap)
-{
- int count = -1;
-
- if (size != 0) count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
- if (count == -1) count = _vscprintf(format, ap);
-
- return count;
-}
-
-inline
-int c99_snprintf(char *str, size_t size, const char *format, ...)
-{
- int count;
- va_list ap;
-
- va_start(ap, format);
- count = c99_vsnprintf(str, size, format, ap);
- va_end(ap);
-
- return count;
-}
-#else
-inline bool is_nan(double x)
-{ return std::isnan( x ); }
-inline bool is_pos_inf(double x)
-{return std::isinf(x) && x > 0;}
-inline bool is_neg_inf(double x)
-{return std::isinf(x) && x > 0;}
-
-#if __cplusplus >= 201103L
-#define c99_snprintf snprintf
-#else
-#define c99_snprintf std::snprintf
-#endif
-
-#endif
-
-}
-
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons/jsoncons_io.hpp b/vendor/jsoncons-0.99.2/jsoncons/jsoncons_io.hpp
deleted file mode 100644
index 27c90fa1..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/jsoncons_io.hpp
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_JSONCONS_IO_HPP
-#define JSONCONS_JSONCONS_IO_HPP
-
-#include <stdexcept>
-#include <string>
-#include <sstream>
-#include <vector>
-#include <istream>
-#include <ostream>
-#include <iomanip>
-#include <cstdlib>
-#include <cmath>
-#include <cstdarg>
-#include <limits> // std::numeric_limits
-#include "jsoncons_config.hpp"
-#include "ovectorstream.hpp"
-
-namespace jsoncons
-{
-
-template <typename CharT>
-class buffered_ostream
-{
- static const size_t default_buffer_length = 16384;
-
- std::basic_ostream<CharT>* os_;
- std::vector<CharT> buffer_;
- CharT * const begin_buffer_;
- const CharT* const end_buffer_;
- CharT* p_;
-public:
- buffered_ostream(std::basic_ostream<CharT>& os)
- : os_(std::addressof(os)), buffer_(default_buffer_length), begin_buffer_(buffer_.data()), end_buffer_(buffer_.data()+default_buffer_length), p_(buffer_.data())
- {
- }
- ~buffered_ostream()
- {
- os_->write(begin_buffer_, (p_ - begin_buffer_));
- os_->flush();
- }
-
- void flush()
- {
- os_->write(begin_buffer_, (p_ - begin_buffer_));
- p_ = begin_buffer_;
- os_->flush();
- }
-
- void write(const CharT* s, size_t length)
- {
- size_t diff = end_buffer_ - p_;
- if (diff >= length)
- {
- std::memcpy(p_, s, length*sizeof(CharT));
- p_ += length;
- }
- else
- {
- os_->write(begin_buffer_, (p_ - begin_buffer_));
- os_->write(s, length);
- p_ = begin_buffer_;
- }
- }
-
- void write(const std::basic_string<CharT>& s)
- {
- write(s.data(),s.length());
- }
-
- void put(CharT c)
- {
- if (p_ < end_buffer_)
- {
- *p_++ = c;
- }
- else
- {
- os_->write(begin_buffer_, (p_-begin_buffer_));
- p_ = begin_buffer_;
- *p_++ = c;
- }
- }
-
-};
-
-#ifdef _MSC_VER
-
-template <typename CharT>
-class float_printer
-{
- uint8_t precision_;
-public:
- float_printer(int precision)
- : precision_(precision)
- {
- }
-
- void print(double val, uint8_t precision, buffered_ostream<CharT>& os)
- {
- char buf[_CVTBUFSIZE];
- int decimal_point = 0;
- int sign = 0;
-
- int prec = (precision == 0) ? precision_ : precision;
-
- int err = _ecvt_s(buf, _CVTBUFSIZE, val, prec, &decimal_point, &sign);
- if (err != 0)
- {
- throw std::runtime_error("Failed attempting double to string conversion");
- }
- char* s = buf;
- char* se = s + prec;
-
- int i, k;
- int j;
-
- if (sign)
- {
- os.put('-');
- }
- if (decimal_point <= -4 || decimal_point > se - s + 5)
- {
- os.put(*s++);
- if (s < se)
- {
- os.put('.');
- while ((se-1) > s && *(se-1) == '0')
- {
- --se;
- }
-
- while(s < se)
- {
- os.put(*s++);
- }
- }
- os.put('e');
- /* sprintf(b, "%+.2d", decimal_point - 1); */
- if (--decimal_point < 0) {
- os.put('-');
- decimal_point = -decimal_point;
- }
- else
- os.put('+');
- for(j = 2, k = 10; 10*k <= decimal_point; j++, k *= 10);
- for(;;)
- {
- i = decimal_point / k;
- os.put(i + '0');
- if (--j <= 0)
- break;
- decimal_point -= i*k;
- decimal_point *= 10;
- }
- }
- else if (decimal_point <= 0)
- {
- os.put('0');
- os.put('.');
- while ((se-1) > s && *(se-1) == '0')
- {
- --se;
- }
- for(; decimal_point < 0; decimal_point++)
- {
- os.put('0');
- }
- while(s < se)
- {
- os.put(*s++);
- }
- }
- else {
- while(s < se)
- {
- os.put(*s++);
- if ((--decimal_point == 0) && s < se)
- {
- os.put('.');
- while ((se-1) > s && *(se-1) == '0')
- {
- --se;
- }
- }
- }
- for(; decimal_point > 0; decimal_point--)
- {
- os.put('0');
- }
- }
- }
-};
-
-#else
-
-template <typename CharT>
-class float_printer
-{
- jsoncons::basic_ovectorstream<CharT> vs_;
- uint8_t precision_;
-public:
- float_printer(uint8_t precision)
- : vs_(255), precision_(precision)
- {
- vs_.set_locale(std::locale::classic());
- vs_.precision(precision);
- }
-
- void print(double val, uint8_t precision, buffered_ostream<CharT>& os)
- {
- vs_.reset();
- vs_.precision(precision == 0 ? precision_ : precision);
- vs_ << val;
-
- const CharT* s = vs_.data();
- const CharT* se = s + vs_.length();
-
- bool dot = false;
- while (s < se)
- {
- if (*s == '.')
- {
- dot = true;
- }
- else if (*s == 'e')
- {
- if (!dot)
- {
- os.put('.');
- os.put('0');
- dot = true;
- }
- }
- os.put(*s);
- ++s;
- }
- if (!dot)
- {
- os.put('.');
- os.put('0');
- }
- }
-};
-
-#endif
-
-// string_to_float only requires narrow char
-#ifdef _MSC_VER
-class float_reader
-{
-private:
- _locale_t locale_;
-public:
- float_reader()
- {
- locale_ = _create_locale(LC_NUMERIC, "C");
- }
- ~float_reader()
- {
- _free_locale(locale_);
- }
-
- double read(const char* s, size_t length)
- {
- const char *begin = s;
- char *end = nullptr;
- double val = _strtod_l(begin, &end, locale_);
- if (begin == end)
- {
- throw std::invalid_argument("Invalid float value");
- }
- return val;
- }
-
- float_reader(const float_reader& fr) = delete;
- float_reader& operator=(const float_reader& fr) = delete;
-};
-
-#else
-class float_reader
-{
-private:
- std::vector<char> buffer_;
- std::string decimal_point_;
- bool is_dot_;
-public:
- float_reader()
- : buffer_()
- {
- struct lconv * lc = localeconv();
- if (lc != nullptr)
- {
- decimal_point_ = std::string(lc->decimal_point);
- }
- else
- {
- decimal_point_ = std::string(".");
- }
- buffer_.reserve(100);
- is_dot_ = decimal_point_ == ".";
- }
-
- double read(const char* s, size_t length)
- {
- double val;
- if (is_dot_)
- {
- const char *begin = s;
- char *end = nullptr;
- val = strtod(begin, &end);
- if (begin == end)
- {
- throw std::invalid_argument("Invalid float value");
- }
- }
- else
- {
- buffer_.clear();
- size_t j = 0;
- const char* pe = s + length;
- for (const char* p = s; p < pe; ++p)
- {
- if (*p == '.')
- {
- buffer_.insert(buffer_.begin() + j, decimal_point_.begin(), decimal_point_.end());
- j += decimal_point_.length();
- }
- else
- {
- buffer_.push_back(*p);
- ++j;
- }
- }
- const char *begin = buffer_.data();
- char *end = nullptr;
- val = strtod(begin, &end);
- if (begin == end)
- {
- throw std::invalid_argument("Invalid float value");
- }
- }
- return val;
- }
-
- float_reader(const float_reader& fr) = delete;
- float_reader& operator=(const float_reader& fr) = delete;
-};
-#endif
-
-}
-
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons/output_format.hpp b/vendor/jsoncons-0.99.2/jsoncons/output_format.hpp
deleted file mode 100644
index 54e74874..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/output_format.hpp
+++ /dev/null
@@ -1,330 +0,0 @@
-// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_OUTPUT_FORMAT_HPP
-#define JSONCONS_OUTPUT_FORMAT_HPP
-
-#include <string>
-#include <sstream>
-#include <vector>
-#include <istream>
-#include <ostream>
-#include <cstdlib>
-#include <limits>
-#include <cwchar>
-
-namespace jsoncons {
-
-enum class block_options {next_line,same_line};
-
-template <typename CharT>
-class buffered_ostream;
-
-template <typename CharT>
-class basic_output_format
-{
- int indent_;
- uint8_t precision_;
- bool replace_nan_;
- bool replace_pos_inf_;
- bool replace_neg_inf_;
- std::basic_string<CharT> nan_replacement_;
- std::basic_string<CharT> pos_inf_replacement_;
- std::basic_string<CharT> neg_inf_replacement_;
- bool escape_all_non_ascii_;
- bool escape_solidus_;
- block_options object_array_block_option_;
- block_options array_array_block_option_;
- block_options object_object_block_option_;
- block_options array_object_block_option_;
-public:
- static const size_t default_indent = 4;
-
-// Constructors
-
- basic_output_format()
- :
- indent_(default_indent),
- precision_(16),
- replace_nan_(true),
- replace_pos_inf_(true),
- replace_neg_inf_(true),
- nan_replacement_(json_literals<CharT>::null_literal().first),
- pos_inf_replacement_(json_literals<CharT>::null_literal().first),
- neg_inf_replacement_(json_literals<CharT>::null_literal().first),
- escape_all_non_ascii_(false),
- escape_solidus_(false),
- object_array_block_option_(block_options::same_line),
- array_array_block_option_(block_options::next_line),
- object_object_block_option_(block_options::same_line),
- array_object_block_option_(block_options::next_line)
- {
- }
-
-// Accessors
-
- block_options object_array_block_option()
- {
- return object_array_block_option_;
- }
-
- basic_output_format<CharT>& object_array_block_option(block_options value)
- {
- object_array_block_option_ = value;
- return *this;
- }
-
- block_options object_object_block_option()
- {
- return object_object_block_option_;
- }
-
- basic_output_format<CharT>& object_object_block_option(block_options value)
- {
- object_object_block_option_ = value;
- return *this;
- }
-
- block_options array_array_block_option()
- {
- return array_array_block_option_;
- }
-
- basic_output_format<CharT>& array_array_block_option(block_options value)
- {
- array_array_block_option_ = value;
- return *this;
- }
-
- block_options array_object_block_option()
- {
- return array_object_block_option_;
- }
-
- basic_output_format<CharT>& array_object_block_option(block_options value)
- {
- array_object_block_option_ = value;
- return *this;
- }
-
- int indent() const
- {
- return indent_;
- }
-
- uint8_t precision() const
- {
- return precision_;
- }
-
- bool escape_all_non_ascii() const
- {
- return escape_all_non_ascii_;
- }
-
- bool escape_solidus() const
- {
- return escape_solidus_;
- }
-
- bool replace_nan() const {return replace_nan_;}
-
- bool replace_pos_inf() const {return replace_pos_inf_;}
-
- bool replace_neg_inf() const {return replace_neg_inf_;}
-
- std::basic_string<CharT> nan_replacement() const
- {
- return nan_replacement_;
- }
-
- std::basic_string<CharT> pos_inf_replacement() const
- {
- return pos_inf_replacement_;
- }
-
- std::basic_string<CharT> neg_inf_replacement() const
- {
- return neg_inf_replacement_;
- }
-
-// Modifiers
-
- basic_output_format<CharT>& precision(uint8_t prec)
- {
- precision_ = prec;
- return *this;
- }
-
- basic_output_format<CharT>& escape_all_non_ascii(bool value)
- {
- escape_all_non_ascii_ = value;
- return *this;
- }
-
- basic_output_format<CharT>& escape_solidus(bool value)
- {
- escape_solidus_ = value;
- return *this;
- }
-
- basic_output_format<CharT>& replace_nan(bool replace)
- {
- replace_nan_ = replace;
- return *this;
- }
-
- basic_output_format<CharT>& replace_inf(bool replace)
- {
- replace_pos_inf_ = replace;
- replace_neg_inf_ = replace;
- return *this;
- }
-
- basic_output_format<CharT>& replace_pos_inf(bool replace)
- {
- replace_pos_inf_ = replace;
- return *this;
- }
-
- basic_output_format<CharT>& replace_neg_inf(bool replace)
- {
- replace_neg_inf_ = replace;
- return *this;
- }
-
- basic_output_format<CharT>& nan_replacement(const std::basic_string<CharT>& replacement)
- {
- nan_replacement_ = replacement;
- return *this;
- }
-
- basic_output_format<CharT>& pos_inf_replacement(const std::basic_string<CharT>& replacement)
- {
- pos_inf_replacement_ = replacement;
- return *this;
- }
-
- basic_output_format<CharT>& neg_inf_replacement(const std::basic_string<CharT>& replacement)
- {
- neg_inf_replacement_ = replacement;
- return *this;
- }
-
- basic_output_format<CharT>& indent(int value)
- {
- indent_ = value;
- return *this;
- }
-};
-
-template<typename CharT>
-void escape_string(const CharT* s,
- size_t length,
- const basic_output_format<CharT>& format,
- buffered_ostream<CharT>& os)
-{
- const CharT* begin = s;
- const CharT* end = s + length;
- for (const CharT* it = begin; it != end; ++it)
- {
- CharT c = *it;
- switch (c)
- {
- case '\\':
- os.put('\\');
- os.put('\\');
- break;
- case '"':
- os.put('\\');
- os.put('\"');
- break;
- case '\b':
- os.put('\\');
- os.put('b');
- break;
- case '\f':
- os.put('\\');
- os.put('f');
- break;
- case '\n':
- os.put('\\');
- os.put('n');
- break;
- case '\r':
- os.put('\\');
- os.put('r');
- break;
- case '\t':
- os.put('\\');
- os.put('t');
- break;
- default:
- uint32_t u(c >= 0 ? c : 256 + c);
- if (format.escape_solidus() && c == '/')
- {
- os.put('\\');
- os.put('/');
- }
- else if (is_control_character(u) || format.escape_all_non_ascii())
- {
- // convert utf8 to codepoint
- uint32_t cp = json_char_traits<CharT, sizeof(CharT)>::convert_char_to_codepoint(it, end);
- if (is_non_ascii_character(cp) || is_control_character(u))
- {
- if (cp > 0xFFFF)
- {
- cp -= 0x10000;
- uint32_t first = (cp >> 10) + 0xD800;
- uint32_t second = ((cp & 0x03FF) + 0xDC00);
-
- os.put('\\');
- os.put('u');
- os.put(to_hex_character(first >> 12 & 0x000F));
- os.put(to_hex_character(first >> 8 & 0x000F));
- os.put(to_hex_character(first >> 4 & 0x000F));
- os.put(to_hex_character(first & 0x000F));
- os.put('\\');
- os.put('u');
- os.put(to_hex_character(second >> 12 & 0x000F));
- os.put(to_hex_character(second >> 8 & 0x000F));
- os.put(to_hex_character(second >> 4 & 0x000F));
- os.put(to_hex_character(second & 0x000F));
- }
- else
- {
- os.put('\\');
- os.put('u');
- os.put(to_hex_character(cp >> 12 & 0x000F));
- os.put(to_hex_character(cp >> 8 & 0x000F));
- os.put(to_hex_character(cp >> 4 & 0x000F));
- os.put(to_hex_character(cp & 0x000F));
- }
- }
- else
- {
- os.put(c);
- }
- }
- else if (format.escape_solidus() && c == '/')
- {
- os.put('\\');
- os.put('/');
- }
- else
- {
- os.put(c);
- }
- break;
- }
- }
-}
-
-typedef basic_output_format<char> output_format;
-typedef basic_output_format<wchar_t> woutput_format;
-
-}
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons/ovectorstream.hpp b/vendor/jsoncons-0.99.2/jsoncons/ovectorstream.hpp
deleted file mode 100644
index e19f5085..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/ovectorstream.hpp
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright 2016 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_OVECTORSTREAM_HPP
-#define JSONCONS_OVECTORSTREAM_HPP
-
-#include <ios>
-#include <ostream>
-#include <string>
-#include <cstddef>
-#include <vector>
-#include "jsoncons/jsoncons_config.hpp"
-
-namespace jsoncons {
-
-template<
- class CharT,
- class Traits = std::char_traits<CharT>
-> class basic_ovectorstream;
-
-template<class CharT, class CharTraits>
-class basic_ovectorbuf
- : public std::basic_streambuf<CharT, CharTraits>
-{
-private:
- std::ios_base::openmode mode_;
- std::vector<CharT> buf_;
-
-public:
- typedef CharT char_type;
- typedef typename CharTraits::int_type int_type;
- typedef typename CharTraits::pos_type pos_type;
- typedef typename CharTraits::off_type off_type;
- typedef CharTraits traits_type;
- typedef std::basic_streambuf<char_type, traits_type> base_streambuf;
-
-public:
-
- explicit basic_ovectorbuf(std::size_t length) JSONCONS_NOEXCEPT
- : base_streambuf(),
- mode_(std::ios_base::out | std::ios_base::binary),
- buf_(length)
- {
- // Set write position to beginning of buffer.
- this->setp(buf_.data(), buf_.data() + buf_.size());
- }
-
- virtual ~basic_ovectorbuf() {}
-
- const CharT* data() const
- {
- return buf_.data();
- }
-
-protected:
- int_type underflow() override
- {
- return this->gptr() != this->egptr() ?
- CharTraits::to_int_type(*this->gptr()) : CharTraits::eof();
- }
-
- int_type pbackfail(int_type c = CharTraits::eof()) override
- {
- if (this->gptr() != this->eback())
- {
- if (!CharTraits::eq_int_type(c, CharTraits::eof()))
- {
- if (CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1]))
- {
- this->gbump(-1);
- return c;
- }
- this->gbump(-1);
- *this->gptr() = c;
- return c;
- }
- else
- {
- this->gbump(-1);
- return CharTraits::not_eof(c);
- }
- }
- else
- {
- return CharTraits::eof();
- }
- }
-
- int_type overflow(int_type c = CharTraits::eof()) override
- {
- if (!CharTraits::eq_int_type(c, CharTraits::eof()))
- {
- size_t pos = buf_.size();
- buf_.resize(pos*2);
- this->setp(buf_.data(), buf_.data() + buf_.size());
- this->pubseekpos(pos, std::ios_base::out);
- *this->pptr() = CharTraits::to_char_type(c);
- this->pbump(1);
- this->pubsync();
- return c;
- }
- else
- {
- return CharTraits::not_eof(c);
- }
- }
-
- pos_type seekoff(off_type off, std::ios_base::seekdir dir,
- std::ios_base::openmode mode = std::ios_base::out) override
- {
- (void)mode; // Always out
-
- std::streamoff newoff;
- switch (dir)
- {
- case std::ios_base::beg:
- newoff = 0;
- break;
- case std::ios_base::end:
- newoff = static_cast<std::streamoff>(buf_.size());
- break;
- case std::ios_base::cur:
- newoff = static_cast<std::streamoff>(this->pptr() - this->pbase());
- break;
- default:
- return pos_type(off_type(-1));
- }
-
- off += newoff;
-
- std::ptrdiff_t n = this->epptr() - this->pbase();
-
- if (off < 0 || off > n) return pos_type(off_type(-1));
- else
- {
- this->setp(this->pbase(), this->pbase() + n);
- this->pbump(static_cast<int>(off));
- }
-
- return pos_type(off);
- }
-
- pos_type seekoff_beg(off_type off)
- {
- std::ptrdiff_t n = this->epptr() - this->pbase();
-
- if (off < 0 || off > n)
- {
- return pos_type(off_type(-1));
- }
- else
- {
- this->setp(this->pbase(), this->pbase() + n);
- this->pbump(static_cast<int>(off));
- }
-
- return pos_type(off);
- }
-
- pos_type seekpos(pos_type pos, std::ios_base::openmode mode
- = std::ios_base::out) override
- {
- (void)mode; // Always out
-
- return seekoff_beg(pos - pos_type(off_type(0)));
- }
-};
-
-template<class CharT, class CharTraits>
-class basic_ovectorstream :
- private basic_ovectorbuf<CharT, CharTraits>,
- public std::basic_ostream<CharT, CharTraits>
-{
-public:
- typedef typename std::basic_ios
- <CharT, CharTraits>::char_type char_type;
- typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
- typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
- typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
- typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
-
-private:
- typedef basic_ovectorbuf<CharT, CharTraits> base_ouputbuf;
- typedef std::basic_ios<char_type, CharTraits> base_ios;
- typedef std::basic_ostream<char_type, CharTraits> base_streambuf;
- base_ouputbuf& get_buf() {return *this;}
- const base_ouputbuf& get_buf() const {return *this;}
-
-public:
- basic_ovectorstream(std::size_t length) JSONCONS_NOEXCEPT
- : base_ouputbuf(length),
- base_streambuf(&get_buf())
- {}
-
- ~basic_ovectorstream() {}
-
-public:
-
- size_t length()
- {
- return this->pptr() - this->pbase();
- }
-
- void set_locale(const std::locale& loc)
- {
- std::locale result = std::basic_ostream<CharT, CharTraits>::imbue(loc);
- this->pubimbue(loc);
- }
-
- void reset()
- {
- this->clear();
- this->seekp(0, std::ios::beg);
- }
-
- const CharT* data() const
- {
- return get_buf().data();
- }
-};
-
-}
-
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons/parse_error_handler.hpp b/vendor/jsoncons-0.99.2/jsoncons/parse_error_handler.hpp
deleted file mode 100644
index 9081fc95..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/parse_error_handler.hpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_PARSE_ERROR_HANDLER_HPP
-#define JSONCONS_PARSE_ERROR_HANDLER_HPP
-
-#include "jsoncons/jsoncons.hpp"
-#include <system_error>
-
-namespace jsoncons {
-
-class parse_exception : public std::exception, public virtual json_exception
-{
-public:
- parse_exception(std::error_code ec,
- size_t line,
- size_t column)
- : error_code_(ec),
- line_number_(line),
- column_number_(column)
- {
- }
- parse_exception(const parse_exception& other)
- : error_code_(other.error_code_),
- line_number_(other.line_number_),
- column_number_(other.column_number_)
- {
- }
- const char* what() const JSONCONS_NOEXCEPT
- {
- std::ostringstream os;
- os << error_code_.message() << " at line " << line_number_ << " and column " << column_number_;
- const_cast<std::string&>(buffer_) = os.str();
- return buffer_.c_str();
- }
-
- const std::error_code code() const
- {
- return error_code_;
- }
-
- size_t line_number() const
- {
- return line_number_;
- }
-
- size_t column_number() const
- {
- return column_number_;
- }
-private:
- std::error_code error_code_;
- std::string buffer_;
- size_t line_number_;
- size_t column_number_;
-};
-
-typedef parse_exception json_parse_exception;
-
-template<typename CharT>
-class basic_parsing_context
-{
-public:
- virtual ~basic_parsing_context() {}
-
- size_t line_number() const
- {
- return do_line_number();
- }
- size_t column_number() const
- {
- return do_column_number();
- }
- CharT current_char() const
- {
- return do_current_char();
- }
-
-#if !defined(JSONCONS_NO_DEPRECATED)
- CharT last_char() const
- {
- return do_current_char();
- }
-#endif
-
-private:
- virtual size_t do_line_number() const = 0;
- virtual size_t do_column_number() const = 0;
- virtual CharT do_current_char() const = 0;
-};
-
-typedef basic_parsing_context<char> parsing_context;
-typedef basic_parsing_context<wchar_t> wparsing_context;
-
-template <typename CharT>
-class basic_parse_error_handler
-{
-public:
- virtual ~basic_parse_error_handler()
- {
- }
-
- void warning(std::error_code ec,
- const basic_parsing_context<CharT>& context) throw (parse_exception)
- {
- do_warning(ec,context);
- }
-
- void error(std::error_code ec,
- const basic_parsing_context<CharT>& context) throw (parse_exception)
- {
- do_error(ec,context);
- }
-
- void fatal_error(std::error_code ec,
- const basic_parsing_context<CharT>& context) throw (parse_exception)
- {
- do_fatal_error(ec,context);
- throw parse_exception(ec,context.line_number(),context.column_number());
- }
-
-private:
- virtual void do_warning(std::error_code,
- const basic_parsing_context<CharT>& context) throw (parse_exception) = 0;
-
- virtual void do_error(std::error_code,
- const basic_parsing_context<CharT>& context) throw (parse_exception) = 0;
-
- virtual void do_fatal_error(std::error_code,
- const basic_parsing_context<CharT>& context) throw (parse_exception)
- {
- (void)context;
- }
-};
-
-template <typename CharT>
-class basic_default_parse_error_handler : public basic_parse_error_handler<CharT>
-{
-public:
- static basic_parse_error_handler<CharT>& instance()
- {
- static basic_default_parse_error_handler<CharT> instance;
- return instance;
- }
-private:
- virtual void do_warning(std::error_code,
- const basic_parsing_context<CharT>& context) throw (parse_exception)
- {
- (void)context;
- }
-
- virtual void do_error(std::error_code ec,
- const basic_parsing_context<CharT>& context) throw (parse_exception)
- {
- throw parse_exception(ec,context.line_number(),context.column_number());
- }
-};
-
-typedef basic_parse_error_handler<char> parse_error_handler;
-typedef basic_parse_error_handler<wchar_t> wparse_error_handler;
-
-typedef basic_default_parse_error_handler<char> default_parse_error_handler;
-typedef basic_default_parse_error_handler<wchar_t> wdefault_parse_error_handler;
-
-typedef basic_parsing_context<char> parsing_context;
-typedef basic_parsing_context<wchar_t> wparsing_context;
-
-}
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons_ext/boost/type_extensions.hpp b/vendor/jsoncons-0.99.2/jsoncons_ext/boost/type_extensions.hpp
deleted file mode 100644
index 59936cd7..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons_ext/boost/type_extensions.hpp
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_EXT_TYPE_EXTENSIONS_HPP
-#define JSONCONS_EXT_TYPE_EXTENSIONS_HPP
-
-#include "jsoncons/json.hpp"
-#include "boost/date_time/gregorian/gregorian.hpp"
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wswitch"
-#endif
-
-namespace jsoncons
-{
- template <typename JsonT>
- class json_type_traits<JsonT,boost::gregorian::date>
- {
- public:
- static bool is(const JsonT& val) JSONCONS_NOEXCEPT
- {
- if (!val.is_string())
- {
- return false;
- }
- std::string s = val.template as<std::string>();
- try
- {
- boost::gregorian::date_from_iso_string(s);
- return true;
- }
- catch (...)
- {
- return false;
- }
- }
-
- static boost::gregorian::date as(const JsonT& val)
- {
- std::string s = val.template as<std::string>();
- return boost::gregorian::from_simple_string(s);
- }
-
- static void assign(JsonT& lhs, boost::gregorian::date val)
- {
- lhs = to_iso_extended_string(val);
- }
- };
-}
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
-
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_parameters.hpp b/vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_parameters.hpp
deleted file mode 100644
index 099a154f..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_parameters.hpp
+++ /dev/null
@@ -1,341 +0,0 @@
-// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_CSV_CSV_PARAMETERS_HPP
-#define JSONCONS_CSV_CSV_PARAMETERS_HPP
-
-#include <string>
-#include <sstream>
-#include <vector>
-#include <istream>
-#include <ostream>
-#include <cstdlib>
-#include <limits>
-#include <cwchar>
-
-namespace jsoncons { namespace csv {
-
-enum class quote_styles
-{
- all,minimal,none,nonnumeric
-};
-
-template <typename CharT>
-class basic_csv_parameters
-{
-public:
- static const size_t default_indent = 4;
-
-// Constructors
-
- basic_csv_parameters()
- :
- assume_header_(false),
- ignore_empty_values_(false),
- trim_leading_(false),
- trim_trailing_(false),
- trim_leading_inside_quotes_(false),
- trim_trailing_inside_quotes_(false),
- unquoted_empty_value_is_null_(false),
- field_delimiter_(','),
- quote_char_('\"'),
- quote_escape_char_('\"'),
- comment_starter_('\0'),
- quote_style_(quote_styles::minimal),
- max_lines_(std::numeric_limits<unsigned long>::max JSONCONS_NO_MACRO_EXP()),
- header_lines_(0)
- {
- line_delimiter_.push_back('\n');
- }
-
-// Properties
-
- size_t header_lines() const
- {
- return (assume_header_ && header_lines_ <= 1) ? 1 : header_lines_;
- }
-
- basic_csv_parameters<CharT>& header_lines(size_t value)
- {
- header_lines_ = value;
- return *this;
- }
-
- bool assume_header() const
- {
- return assume_header_;
- }
-
- basic_csv_parameters<CharT>& assume_header(bool value)
- {
- assume_header_ = value;
- return *this;
- }
-
- bool ignore_empty_values() const
- {
- return ignore_empty_values_;
- }
-
- basic_csv_parameters<CharT>& ignore_empty_values(bool value)
- {
- ignore_empty_values_ = value;
- return *this;
- }
-
- bool trim_leading() const
- {
- return trim_leading_;
- }
-
- basic_csv_parameters<CharT>& trim_leading(bool value)
- {
- trim_leading_ = value;
- return *this;
- }
-
- bool trim_trailing() const
- {
- return trim_trailing_;
- }
-
- basic_csv_parameters<CharT>& trim_trailing(bool value)
- {
- trim_trailing_ = value;
- return *this;
- }
-
- bool trim_leading_inside_quotes() const
- {
- return trim_leading_inside_quotes_;
- }
-
- basic_csv_parameters<CharT>& trim_leading_inside_quotes(bool value)
- {
- trim_leading_inside_quotes_ = value;
- return *this;
- }
-
- bool trim_trailing_inside_quotes() const
- {
- return trim_trailing_inside_quotes_;
- }
-
- basic_csv_parameters<CharT>& trim_trailing_inside_quotes(bool value)
- {
- trim_trailing_inside_quotes_ = value;
- return *this;
- }
-
- bool trim() const
- {
- return trim_leading_ && trim_trailing_;
- }
-
- basic_csv_parameters<CharT>& trim(bool value)
- {
- trim_leading_ = value;
- trim_trailing_ = value;
- return *this;
- }
-
- bool trim_inside_quotes() const
- {
- return trim_leading_inside_quotes_ && trim_trailing_inside_quotes_;
- }
-
- basic_csv_parameters<CharT>& trim_inside_quotes(bool value)
- {
- trim_leading_inside_quotes_ = value;
- trim_trailing_inside_quotes_ = value;
- return *this;
- }
-
- bool unquoted_empty_value_is_null() const
- {
- return unquoted_empty_value_is_null_;
- }
-
- basic_csv_parameters<CharT>& unquoted_empty_value_is_null(bool value)
- {
- unquoted_empty_value_is_null_ = value;
- return *this;
- }
-
- std::vector<std::basic_string<CharT>> column_names() const
- {
- return column_names_;
- }
-
- basic_csv_parameters<CharT>& column_names(const std::vector<std::basic_string<CharT>>& value)
- {
- column_names_ = value;
- return *this;
- }
-
- std::vector<std::basic_string<CharT>> column_types() const
- {
- return column_types_;
- }
-
- basic_csv_parameters<CharT>& column_types(const std::vector<std::basic_string<CharT>>& value)
- {
- column_types_ = value;
- return *this;
- }
-
- std::vector<std::basic_string<CharT>> column_defaults() const
- {
- return column_defaults_;
- }
-
- basic_csv_parameters<CharT>& column_defaults(const std::vector<std::basic_string<CharT>>& value)
- {
- column_defaults_ = value;
- return *this;
- }
-
- CharT field_delimiter() const
- {
- return field_delimiter_;
- }
-
- basic_csv_parameters<CharT>& field_delimiter(CharT value)
- {
- field_delimiter_ = value;
- return *this;
- }
-
- std::basic_string<CharT> line_delimiter() const
- {
- return line_delimiter_;
- }
-
- basic_csv_parameters<CharT>& line_delimiter(std::basic_string<CharT> value)
- {
- line_delimiter_ = value;
- return *this;
- }
-
- CharT quote_char() const
- {
- return quote_char_;
- }
-
- basic_csv_parameters<CharT>& quote_char(CharT value)
- {
- quote_char_ = value;
- return *this;
- }
-
- CharT quote_escape_char() const
- {
- return quote_escape_char_;
- }
-
- basic_csv_parameters<CharT>& quote_escape_char(CharT value)
- {
- quote_escape_char_ = value;
- return *this;
- }
-
- CharT comment_starter() const
- {
- return comment_starter_;
- }
-
- basic_csv_parameters<CharT>& comment_starter(CharT value)
- {
- comment_starter_ = value;
- return *this;
- }
-
- quote_styles quote_style() const
- {
- return quote_style_;
- }
-
- basic_csv_parameters<CharT>& assume_header(quote_styles value)
- {
- quote_style_ = value;
- return *this;
- }
-
- unsigned long max_lines() const
- {
- return max_lines_;
- }
-
- basic_csv_parameters<CharT>& max_lines(unsigned long value)
- {
- max_lines_ = value;
- return *this;
- }
-
-#if !defined(JSONCONS_NO_DEPRECATED)
-
- std::basic_string<CharT> header() const
- {
- return header_;
- }
-
- basic_csv_parameters<CharT>& header(const std::basic_string<CharT>& value)
- {
- header_ = value;
- return *this;
- }
-
- std::basic_string<CharT> data_types() const
- {
- return data_types_;
- }
-
- basic_csv_parameters<CharT>& data_types(const std::basic_string<CharT>& value)
- {
- data_types_ = value;
- return *this;
- }
-
- std::basic_string<CharT> default_values() const
- {
- return default_values_;
- }
-
- basic_csv_parameters<CharT>& default_values(const std::basic_string<CharT>& value)
- {
- default_values_ = value;
- return *this;
- }
-#endif
-private:
- bool assume_header_;
- bool ignore_empty_values_;
- bool trim_leading_;
- bool trim_trailing_;
- bool trim_leading_inside_quotes_;
- bool trim_trailing_inside_quotes_;
- bool unquoted_empty_value_is_null_;
- CharT field_delimiter_;
- CharT quote_char_;
- CharT quote_escape_char_;
- CharT comment_starter_;
- quote_styles quote_style_;
- unsigned long max_lines_;
- size_t header_lines_;
- std::basic_string<CharT> line_delimiter_;
- std::basic_string<CharT> header_;
- std::basic_string<CharT> data_types_;
- std::basic_string<CharT> default_values_;
- std::vector<std::basic_string<CharT>> column_names_;
- std::vector<std::basic_string<CharT>> column_types_;
- std::vector<std::basic_string<CharT>> column_defaults_;
-};
-
-typedef basic_csv_parameters<char> csv_parameters;
-typedef basic_csv_parameters<wchar_t> wcsv_parameters;
-
-}}
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_parser.hpp b/vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_parser.hpp
deleted file mode 100644
index 14323666..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_parser.hpp
+++ /dev/null
@@ -1,903 +0,0 @@
-// Copyright 2015 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_CSV_CSV_PARSER_HPP
-#define JSONCONS_CSV_CSV_PARSER_HPP
-
-#include <memory>
-#include <string>
-#include <sstream>
-#include <vector>
-#include <istream>
-#include <cstdlib>
-#include <stdexcept>
-#include <system_error>
-#include <cctype>
-#include "jsoncons/jsoncons.hpp"
-#include "jsoncons/json_input_handler.hpp"
-#include "jsoncons/parse_error_handler.hpp"
-#include "jsoncons/json_parser.hpp"
-#include "jsoncons/json_filter.hpp"
-#include "jsoncons_ext/csv/csv_error_category.hpp"
-#include "jsoncons_ext/csv/csv_parameters.hpp"
-
-namespace jsoncons { namespace csv {
-
-template <typename CharT>
-struct json_csv_parser_traits
-{
-};
-
-template <>
-struct json_csv_parser_traits<char>
-{
- static const std::string string_literal() {return "string";};
-
- static const std::string integer_literal() {return "integer";};
-
- static const std::string float_literal() {return "float";};
-
- static const std::string boolean_literal() {return "boolean";};
-};
-
-template <>
-struct json_csv_parser_traits<wchar_t> // assume utf16
-{
- static const std::wstring string_literal() {return L"string";};
-
- static const std::wstring integer_literal() {return L"integer";};
-
- static const std::wstring float_literal() {return L"float";};
-
- static const std::wstring boolean_literal() {return L"boolean";};
-};
-
-enum class csv_modes {
- done,
- header,
- array,
- object
-};
-
-enum class csv_states
-{
- start,
- comment,
- expect_value,
- between_fields,
- quoted_string,
- unquoted_string,
- escaped_value,
- minus,
- zero,
- integer,
- fraction,
- exp1,
- exp2,
- exp3,
- done
-};
-
-enum class data_types
-{
- string_t,integer_t,float_t,boolean_t
-};
-
-template<typename CharT>
-class basic_csv_parser : private basic_parsing_context<CharT>
-{
- static const int default_depth = 3;
-
- csv_states state_;
- int top_;
- std::vector<csv_modes> stack_;
- basic_json_input_handler<CharT> *handler_;
- basic_parse_error_handler<CharT> *err_handler_;
- bool is_negative_;
- uint32_t cp_;
- size_t index_;
- unsigned long column_;
- unsigned long line_;
- int curr_char_;
- int prev_char_;
- std::basic_string<CharT> string_buffer_;
- csv_states saved_state_;
- int depth_;
- basic_csv_parameters<CharT> parameters_;
- std::vector<std::basic_string<CharT>> column_names_;
- std::vector<data_types> column_types_;
- std::vector<std::basic_string<CharT>> column_defaults_;
- size_t column_index_;
- basic_begin_end_json_filter<CharT> filter_;
- basic_json_parser<CharT> parser_;
-
-public:
- basic_csv_parser(basic_json_input_handler<CharT>& handler)
- : top_(-1),
- stack_(default_depth),
- handler_(std::addressof(handler)),
- err_handler_(std::addressof(basic_default_parse_error_handler<CharT>::instance())),
- is_negative_(false),
- cp_(0),
- index_(0),
- filter_(handler),
- parser_(filter_)
- {
- depth_ = default_depth;
- state_ = csv_states::start;
- top_ = -1;
- line_ = 1;
- column_ = 0;
- column_index_ = 0;
- }
-
- basic_csv_parser(basic_json_input_handler<CharT>& handler,
- basic_csv_parameters<CharT> params)
- : top_(-1),
- stack_(default_depth),
- handler_(std::addressof(handler)),
- err_handler_(std::addressof(basic_default_parse_error_handler<CharT>::instance())),
- is_negative_(false),
- cp_(0),
- index_(0),
- parameters_(params),
- filter_(handler),
- parser_(filter_)
- {
- depth_ = default_depth;
- state_ = csv_states::start;
- top_ = -1;
- line_ = 1;
- column_ = 0;
- column_index_ = 0;
- }
-
- basic_csv_parser(basic_json_input_handler<CharT>& handler,
- basic_parse_error_handler<CharT>& err_handler)
- : top_(-1),
- stack_(default_depth),
- handler_(std::addressof(handler)),
- err_handler_(std::addressof(err_handler)),
- is_negative_(false),
- cp_(0),
- index_(0),
- filter_(handler),
- parser_(filter_)
- {
- depth_ = default_depth;
- state_ = csv_states::start;
- top_ = -1;
- line_ = 1;
- column_ = 0;
- column_index_ = 0;
- }
-
- basic_csv_parser(basic_json_input_handler<CharT>& handler,
- basic_parse_error_handler<CharT>& err_handler,
- basic_csv_parameters<CharT> params)
- : top_(-1),
- stack_(default_depth),
- handler_(std::addressof(handler)),
- err_handler_(std::addressof(err_handler)),
- is_negative_(false),
- cp_(0),
- index_(0),
- parameters_(params),
- filter_(handler),
- parser_(filter_)
- {
- depth_ = default_depth;
- state_ = csv_states::start;
- top_ = -1;
- line_ = 1;
- column_ = 0;
- column_index_ = 0;
- }
-
- ~basic_csv_parser()
- {
- }
-
- const basic_parsing_context<CharT>& parsing_context() const
- {
- return *this;
- }
-
- bool done() const
- {
- return state_ == csv_states::done;
- }
-
- const std::vector<std::basic_string<CharT>>& column_labels() const
- {
- return column_names_;
- }
-
- void after_field()
- {
- ++column_index_;
- }
-
- void before_record()
- {
- if (column_index_ == 0)
- {
- switch (stack_[top_])
- {
- case csv_modes::array:
- handler_->begin_array(*this);
- break;
- case csv_modes::object:
- handler_->begin_object(*this);
- break;
- default:
- break;
- }
- }
- }
-
- void after_record()
- {
- switch (stack_[top_])
- {
- case csv_modes::array:
- handler_->end_array(*this);
- break;
- case csv_modes::object:
- handler_->end_object(*this);
- break;
- case csv_modes::header:
- if (line_ >= parameters_.header_lines())
- {
- if (column_names_.size() > 0)
- {
- flip(csv_modes::header, csv_modes::object);
- }
- else
- {
- flip(csv_modes::header, csv_modes::array);
- }
- }
- break;
- default:
- break;
- }
- column_index_ = 0;
- }
-
- void begin_parse()
- {
- push(csv_modes::done);
- handler_->begin_json();
-
- if (parameters_.column_names().size() > 0)
- {
- column_names_ = parameters_.column_names();
- }
-#if !defined(JSONCONS_NO_DEPRECATED)
- else if (parameters_.header().length() > 0)
- {
- basic_empty_json_input_handler<CharT> ih;
- basic_csv_parameters<CharT> params;
- params.field_delimiter(parameters_.field_delimiter());
- params.quote_char(parameters_.quote_char());
- params.quote_escape_char(parameters_.quote_escape_char());
- params.assume_header(true);
- basic_csv_parser<CharT> p(ih,params);
- p.begin_parse();
- p.parse(parameters_.header().data(),0,parameters_.header().length());
- p.end_parse();
- column_names_ = p.column_labels();
- }
-#endif
- if (parameters_.column_types().size() > 0)
- {
- column_types_.resize(parameters_.column_types().size());
- for (size_t i = 0; i < parameters_.column_types().size(); ++i)
- {
- if (parameters_.column_types()[i] == json_csv_parser_traits<CharT>::string_literal())
- {
- column_types_[i] = data_types::string_t;
- }
- else if (parameters_.column_types()[i] == json_csv_parser_traits<CharT>::integer_literal())
- {
- column_types_[i] = data_types::integer_t;
- }
- else if (parameters_.column_types()[i] == json_csv_parser_traits<CharT>::float_literal())
- {
- column_types_[i] = data_types::float_t;
- }
- else if (parameters_.column_types()[i] == json_csv_parser_traits<CharT>::boolean_literal())
- {
- column_types_[i] = data_types::boolean_t;
- }
- }
- }
-#if !defined(JSONCONS_NO_DEPRECATED)
- else if (parameters_.data_types().length() > 0)
- {
- basic_empty_json_input_handler<CharT> ih;
- basic_csv_parameters<CharT> params;
- params.field_delimiter(parameters_.field_delimiter());
- params.assume_header(true);
- basic_csv_parser<CharT> p(ih,params);
- p.begin_parse();
- p.parse(parameters_.data_types().data(),0,parameters_.data_types().length());
- p.end_parse();
- column_types_.resize(p.column_labels().size());
- for (size_t i = 0; i < p.column_labels().size(); ++i)
- {
- if (p.column_labels()[i] == json_csv_parser_traits<CharT>::string_literal())
- {
- column_types_[i] = data_types::string_t;
- }
- else if (p.column_labels()[i] == json_csv_parser_traits<CharT>::integer_literal())
- {
- column_types_[i] = data_types::integer_t;
- }
- else if (p.column_labels()[i] == json_csv_parser_traits<CharT>::float_literal())
- {
- column_types_[i] = data_types::float_t;
- }
- else if (p.column_labels()[i] == json_csv_parser_traits<CharT>::boolean_literal())
- {
- column_types_[i] = data_types::boolean_t;
- }
- }
- }
-#endif
- if (parameters_.column_defaults().size() > 0)
- {
- column_defaults_ = parameters_.column_defaults();
- }
-#if !defined(JSONCONS_NO_DEPRECATED)
- else if (parameters_.default_values().length() > 0)
- {
- basic_empty_json_input_handler<CharT> ih;
- basic_csv_parameters<CharT> params;
- params.field_delimiter(parameters_.field_delimiter());
- params.assume_header(true);
- basic_csv_parser<CharT> p(ih,params);
- p.begin_parse();
- p.parse(parameters_.default_values().data(),0,parameters_.default_values().length());
- p.end_parse();
- column_defaults_.resize(p.column_labels().size());
- for (size_t i = 0; i < p.column_labels().size(); ++i)
- {
- column_defaults_[i] = p.column_labels()[i];
- }
- }
-#endif
- if (parameters_.header_lines() > 0)
- {
- push(csv_modes::header);
- }
- else
- {
- push(csv_modes::array);
- }
- handler_->begin_array(*this);
- state_ = csv_states::expect_value;
- column_index_ = 0;
- prev_char_ = 0;
- curr_char_ = 0;
- column_ = 1;
- }
-
- void parse(const CharT* p, size_t start, size_t length)
- {
- index_ = start;
- for (; index_ < length && state_ != csv_states::done; ++index_)
- {
- curr_char_ = p[index_];
-all_csv_states:
- switch (state_)
- {
- case csv_states::comment:
- if (curr_char_ == '\n')
- {
- state_ = csv_states::expect_value;
- }
- else if (prev_char_ == '\r')
- {
- state_ = csv_states::expect_value;
- goto all_csv_states;
- }
- break;
- case csv_states::expect_value:
- if (column_ == 1 && curr_char_ == parameters_.comment_starter())
- {
- state_ = csv_states::comment;
- }
- else
- {
- state_ = csv_states::unquoted_string;
- goto all_csv_states;
- }
- break;
- case csv_states::between_fields:
- if (curr_char_ == '\r' || (prev_char_ != '\r' && curr_char_ == '\n'))
- {
- after_record();
- state_ = csv_states::expect_value;
- }
- else if (curr_char_ == parameters_.field_delimiter())
- {
- state_ = csv_states::expect_value;
- }
- break;
- case csv_states::escaped_value:
- {
- if (curr_char_ == parameters_.quote_char())
- {
- string_buffer_.push_back(curr_char_);
- state_ = csv_states::quoted_string;
- }
- else if (parameters_.quote_escape_char() == parameters_.quote_char())
- {
- before_record();
- end_quoted_string_value();
- after_field();
- state_ = csv_states::between_fields;
- goto all_csv_states;
- }
- }
- break;
- case csv_states::quoted_string:
- {
- if (curr_char_ == parameters_.quote_escape_char())
- {
- state_ = csv_states::escaped_value;
- }
- else if (curr_char_ == parameters_.quote_char())
- {
- before_record();
- end_quoted_string_value();
- after_field();
- state_ = csv_states::between_fields;
- }
- else
- {
- string_buffer_.push_back(curr_char_);
- }
- }
- break;
- case csv_states::unquoted_string:
- {
- if (curr_char_ == '\r' || (prev_char_ != '\r' && curr_char_ == '\n'))
- {
- before_record();
- end_unquoted_string_value();
- after_field();
- after_record();
- state_ = csv_states::expect_value;
- }
- else if (curr_char_ == '\n')
- {
- if (prev_char_ != '\r')
- {
- before_record();
- end_unquoted_string_value();
- after_field();
- after_record();
- state_ = csv_states::expect_value;
- }
- }
- else if (curr_char_ == parameters_.field_delimiter())
- {
- before_record();
- end_unquoted_string_value();
- after_field();
- state_ = csv_states::expect_value;
- }
- else if (curr_char_ == parameters_.quote_char())
- {
- string_buffer_.clear();
- state_ = csv_states::quoted_string;
- }
- else
- {
- string_buffer_.push_back(curr_char_);
- }
- }
- break;
- default:
- err_handler_->error(std::error_code(csv_parser_errc::invalid_state, csv_error_category()), *this);
- break;
- }
- if (line_ > parameters_.max_lines())
- {
- state_ = csv_states::done;
- }
- switch (curr_char_)
- {
- case '\r':
- ++line_;
- column_ = 1;
- break;
- case '\n':
- if (prev_char_ != '\r')
- {
- ++line_;
- }
- column_ = 1;
- break;
- default:
- ++column_;
- break;
- }
- prev_char_ = curr_char_;
- }
- }
-
- void end_parse()
- {
- switch (state_)
- {
- case csv_states::unquoted_string:
- before_record();
- end_unquoted_string_value();
- after_field();
- break;
- case csv_states::escaped_value:
- if (parameters_.quote_escape_char() == parameters_.quote_char())
- {
- before_record();
- end_quoted_string_value();
- after_field();
- }
- break;
- default:
- break;
- }
- if (column_index_ > 0)
- {
- after_record();
- }
- switch (stack_[top_])
- {
- case csv_modes::array:
- if (!pop(csv_modes::array))
- {
- err_handler_->error(std::error_code(csv_parser_errc::unexpected_eof, csv_error_category()), *this);
- }
- break;
- case csv_modes::object:
- if (!pop(csv_modes::object))
- {
- err_handler_->error(std::error_code(csv_parser_errc::unexpected_eof, csv_error_category()), *this);
- }
- break;
- case csv_modes::header:
- if (!pop(csv_modes::header))
- {
- err_handler_->error(std::error_code(csv_parser_errc::unexpected_eof, csv_error_category()), *this);
- }
- break;
- default:
- break;
- }
- handler_->end_array(*this);
- if (!pop(csv_modes::done))
- {
- err_handler_->error(std::error_code(csv_parser_errc::unexpected_eof, csv_error_category()), *this);
- }
- handler_->end_json();
- }
-
- csv_states state() const
- {
- return state_;
- }
-
- size_t index() const
- {
- return index_;
- }
-private:
-
- void trim_string_buffer(bool trim_leading, bool trim_trailing)
- {
- size_t start = 0;
- size_t length = string_buffer_.length();
- if (trim_leading)
- {
- bool done = false;
- while (!done && start < string_buffer_.length())
- {
- if ((string_buffer_[start] < 256) && std::isspace(string_buffer_[start]))
- {
- ++start;
- }
- else
- {
- done = true;
- }
- }
- }
- if (trim_trailing)
- {
- bool done = false;
- while (!done && length > 0)
- {
- if ((string_buffer_[length-1] < 256) && std::isspace(string_buffer_[length-1]))
- {
- --length;
- }
- else
- {
- done = true;
- }
- }
- }
- if (start != 0 || length != string_buffer_.size())
- {
- string_buffer_ = string_buffer_.substr(start,length-start);
- }
- }
-
- void end_unquoted_string_value()
- {
- if (parameters_.trim_leading() | parameters_.trim_trailing())
- {
- trim_string_buffer(parameters_.trim_leading(),parameters_.trim_trailing());
- }
- switch (stack_[top_])
- {
- case csv_modes::header:
- if (parameters_.assume_header() && line_ == 1)
- {
- column_names_.push_back(string_buffer_);
- }
- break;
- case csv_modes::object:
- if (!(parameters_.ignore_empty_values() && string_buffer_.size() == 0))
- {
- if (column_index_ < column_names_.size())
- {
- handler_->name(column_names_[column_index_].data(), column_names_[column_index_].length(), *this);
- if (parameters_.unquoted_empty_value_is_null() && string_buffer_.length() == 0)
- {
- handler_->value(jsoncons::null_type(),*this);
- }
- else
- {
- end_value();
- }
- }
- }
- break;
- case csv_modes::array:
- if (parameters_.unquoted_empty_value_is_null() && string_buffer_.length() == 0)
- {
- handler_->value(jsoncons::null_type(),*this);
- }
- else
- {
- end_value();
- }
- break;
- default:
- err_handler_->error(std::error_code(csv_parser_errc::invalid_csv_text, csv_error_category()), *this);
- break;
- }
- state_ = csv_states::expect_value;
- string_buffer_.clear();
- }
-
- void end_quoted_string_value()
- {
- if (parameters_.trim_leading_inside_quotes() | parameters_.trim_trailing_inside_quotes())
- {
- trim_string_buffer(parameters_.trim_leading_inside_quotes(),parameters_.trim_trailing_inside_quotes());
- }
- switch (stack_[top_])
- {
- case csv_modes::header:
- if (parameters_.assume_header() && line_ == 1)
- {
- column_names_.push_back(string_buffer_);
- }
- break;
- case csv_modes::object:
- if (!(parameters_.ignore_empty_values() && string_buffer_.size() == 0))
- {
- if (column_index_ < column_names_.size())
- {
- handler_->name(column_names_[column_index_].data(), column_names_[column_index_].length(), *this);
- end_value();
- }
- }
- break;
- case csv_modes::array:
- end_value();
- break;
- default:
- err_handler_->error(std::error_code(csv_parser_errc::invalid_csv_text, csv_error_category()), *this);
- break;
- }
- state_ = csv_states::expect_value;
- string_buffer_.clear();
- }
-
- void end_value()
- {
- if (column_index_ < column_types_.size())
- {
- switch (column_types_[column_index_])
- {
- case data_types::integer_t:
- {
- std::istringstream iss(string_buffer_);
- long long val;
- iss >> val;
- if (!iss.fail())
- {
- handler_->value(val, *this);
- }
- else
- {
- if (column_index_ < column_defaults_.size() && column_defaults_[column_index_].length() > 0)
- {
- parser_.begin_parse();
- parser_.parse(column_defaults_[column_index_].data(),0,column_defaults_[column_index_].length());
- parser_.end_parse();
- }
- else
- {
- handler_->value(null_type(), *this);
- }
- }
- }
- break;
- case data_types::float_t:
- {
- std::istringstream iss(string_buffer_);
- double val;
- iss >> val;
- if (!iss.fail())
- {
- handler_->value(val, 0, *this);
- }
- else
- {
- if (column_index_ < column_defaults_.size() && column_defaults_[column_index_].length() > 0)
- {
- parser_.begin_parse();
- parser_.parse(column_defaults_[column_index_].data(),0,column_defaults_[column_index_].length());
- parser_.end_parse();
- }
- else
- {
- handler_->value(null_type(), *this);
- }
- }
- }
- break;
- case data_types::boolean_t:
- {
- if (string_buffer_.length() == 1 && string_buffer_[0] == '0')
- {
- handler_->value(false, *this);
- }
- else if (string_buffer_.length() == 1 && string_buffer_[0] == '1')
- {
- handler_->value(true, *this);
- }
- else if (string_buffer_.length() == 5 && ((string_buffer_[0] == 'f' || string_buffer_[0] == 'F') && (string_buffer_[1] == 'a' || string_buffer_[1] == 'A') && (string_buffer_[2] == 'l' || string_buffer_[2] == 'L') && (string_buffer_[3] == 's' || string_buffer_[3] == 'S') && (string_buffer_[4] == 'e' || string_buffer_[4] == 'E')))
- {
- handler_->value(false, *this);
- }
- else if (string_buffer_.length() == 4 && ((string_buffer_[0] == 't' || string_buffer_[0] == 'T') && (string_buffer_[1] == 'r' || string_buffer_[1] == 'R') && (string_buffer_[2] == 'u' || string_buffer_[2] == 'U') && (string_buffer_[3] == 'e' || string_buffer_[3] == 'E')))
- {
- handler_->value(true, *this);
- }
- else
- {
- if (column_index_ < column_defaults_.size() && column_defaults_[column_index_].length() > 0)
- {
- parser_.begin_parse();
- parser_.parse(column_defaults_[column_index_].data(),0,column_defaults_[column_index_].length());
- parser_.end_parse();
- }
- else
- {
- handler_->value(null_type(), *this);
- }
- }
- }
- break;
- default:
- if (string_buffer_.length() > 0)
- {
- handler_->value(string_buffer_.data(), string_buffer_.length(), *this);
- }
- else
- {
- if (column_index_ < column_defaults_.size() && column_defaults_[column_index_].length() > 0)
- {
- parser_.begin_parse();
- parser_.parse(column_defaults_[column_index_].data(),0,column_defaults_[column_index_].length());
- parser_.end_parse();
- }
- else
- {
- handler_->value("", *this);
- }
- }
- break;
- }
- }
- else
- {
- handler_->value(string_buffer_.data(), string_buffer_.length(), *this);
- }
- }
-
- size_t do_line_number() const override
- {
- return line_;
- }
-
- size_t do_column_number() const override
- {
- return column_;
- }
-
- CharT do_current_char() const override
- {
- return (CharT)prev_char_;
- }
-
- void push(csv_modes mode)
- {
- ++top_;
- if (top_ >= depth_)
- {
- depth_ *= 2;
- stack_.resize(depth_);
- }
- stack_[top_] = mode;
- }
-
- int peek()
- {
- return stack_[top_];
- }
-
- bool peek(csv_modes mode)
- {
- return stack_[top_] == mode;
- }
-
- bool flip(csv_modes mode1, csv_modes mode2)
- {
- if (top_ < 0 || stack_[top_] != mode1)
- {
- return false;
- }
- stack_[top_] = mode2;
- return true;
- }
-
- bool pop(csv_modes mode)
- {
- if (top_ < 0 || stack_[top_] != mode)
- {
- return false;
- }
- --top_;
- return true;
- }
-};
-
-typedef basic_csv_parser<char> csv_parser;
-typedef basic_csv_parser<wchar_t> wcsv_parser;
-
-}}
-
-#endif
-
diff --git a/vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_reader.hpp b/vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_reader.hpp
deleted file mode 100644
index 38213e25..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_reader.hpp
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_CSV_CSV_READER_HPP
-#define JSONCONS_CSV_CSV_READER_HPP
-
-#include <string>
-#include <sstream>
-#include <vector>
-#include <istream>
-#include <cstdlib>
-#include <stdexcept>
-#include "jsoncons/jsoncons.hpp"
-#include "jsoncons/json_input_handler.hpp"
-#include "jsoncons/parse_error_handler.hpp"
-#include "jsoncons_ext/csv/csv_error_category.hpp"
-#include "jsoncons_ext/csv/csv_parser.hpp"
-#include "jsoncons/json.hpp"
-
-namespace jsoncons { namespace csv {
-
-template<typename CharT>
-class basic_csv_reader
-{
- struct stack_item
- {
- stack_item()
- : array_begun_(false)
- {
- }
-
- bool array_begun_;
- };
-public:
- // Structural characters
- static const size_t default_max_buffer_length = 16384;
- //! Parse an input stream of CSV text into a json object
- /*!
- \param is The input stream to read from
- */
-
- basic_csv_reader(std::basic_istream<CharT>& is,
- basic_json_input_handler<CharT>& handler)
-
- : parser_(handler),
- is_(std::addressof(is)),
- buffer_(default_max_buffer_length),
- buffer_capacity_(default_max_buffer_length),
- buffer_position_(0),
- buffer_length_(0),
- eof_(false),
- index_(0)
- {
- }
-
- basic_csv_reader(std::basic_istream<CharT>& is,
- basic_json_input_handler<CharT>& handler,
- basic_csv_parameters<CharT> params)
-
- : parser_(handler,params),
- is_(std::addressof(is)),
- buffer_(default_max_buffer_length),
- buffer_capacity_(default_max_buffer_length),
- buffer_position_(0),
- buffer_length_(0),
- eof_(false),
- index_(0)
- {
- }
-
- basic_csv_reader(std::basic_istream<CharT>& is,
- basic_json_input_handler<CharT>& handler,
- basic_parse_error_handler<CharT>& err_handler)
- :
- parser_(handler,err_handler),
- is_(std::addressof(is)),
- buffer_(),
- buffer_capacity_(default_max_buffer_length),
- buffer_position_(0),
- buffer_length_(0),
- eof_(false),
- index_(0)
-
-
- {
- }
-
- basic_csv_reader(std::basic_istream<CharT>& is,
- basic_json_input_handler<CharT>& handler,
- basic_parse_error_handler<CharT>& err_handler,
- basic_csv_parameters<CharT> params)
- :
- parser_(handler,err_handler,params),
- is_(std::addressof(is)),
- buffer_(),
- buffer_capacity_(default_max_buffer_length),
- buffer_position_(0),
- buffer_length_(0),
- eof_(false),
- index_(0)
- {
- }
-
- ~basic_csv_reader()
- {
- }
-
- void read()
- {
- parser_.begin_parse();
- while (!eof_ && !parser_.done())
- {
- if (!(index_ < buffer_length_))
- {
- if (!is_->eof())
- {
- is_->read(buffer_.data(), buffer_capacity_);
- buffer_length_ = static_cast<size_t>(is_->gcount());
- if (buffer_length_ == 0)
- {
- eof_ = true;
- }
- index_ = 0;
- }
- else
- {
- eof_ = true;
- }
- }
- if (!eof_)
- {
- parser_.parse(buffer_.data(),index_,buffer_length_);
- index_ = parser_.index();
- }
- }
- parser_.end_parse();
- }
-
- bool eof() const
- {
- return eof_;
- }
-
- size_t buffer_capacity() const
- {
- return buffer_capacity_;
- }
-
- void buffer_capacity(size_t buffer_capacity)
- {
- buffer_capacity_ = buffer_capacity;
- }
-
-private:
- basic_csv_reader(const basic_csv_reader&) = delete;
- basic_csv_reader& operator = (const basic_csv_reader&) = delete;
-
- basic_csv_parser<CharT> parser_;
- std::basic_istream<CharT>* is_;
- std::vector<CharT> buffer_;
- size_t buffer_capacity_;
- size_t buffer_position_;
- size_t buffer_length_;
- bool eof_;
- size_t index_;
-};
-
-typedef basic_csv_reader<char> csv_reader;
-
-}}
-
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_serializer.hpp b/vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_serializer.hpp
deleted file mode 100644
index f331b629..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_serializer.hpp
+++ /dev/null
@@ -1,445 +0,0 @@
-// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_CSV_CSV_SERIALIZER_HPP
-#define JSONCONS_CSV_CSV_SERIALIZER_HPP
-
-#include <string>
-#include <sstream>
-#include <vector>
-#include <ostream>
-#include <cstdlib>
-#include <map>
-#include "jsoncons/jsoncons.hpp"
-#include "jsoncons/output_format.hpp"
-#include "jsoncons/json_output_handler.hpp"
-#include <limits> // std::numeric_limits
-
-namespace jsoncons { namespace csv {
-
-template <typename CharT>
-struct csv_char_traits
-{
-};
-
-template <>
-struct csv_char_traits<char>
-{
- static const std::string all_literal() {return "all";};
-
- static const std::string minimal_literal() {return "minimal";};
-
- static const std::string none_literal() {return "none";};
-
- static const std::string nonnumeric_literal() {return "nonumeric";};
-};
-
-template <>
-struct csv_char_traits<wchar_t>
-{
- static const std::wstring all_literal() {return L"all";};
-
- static const std::wstring minimal_literal() {return L"minimal";};
-
- static const std::wstring none_literal() {return L"none";};
-
- static const std::wstring nonnumeric_literal() {return L"nonumeric";};
-};
-
-template <typename CharT>
-void escape_string(const CharT* s,
- size_t length,
- CharT quote_char, CharT quote_escape_char,
- buffered_ostream<CharT>& os)
-{
- const CharT* begin = s;
- const CharT* end = s + length;
- for (const CharT* it = begin; it != end; ++it)
- {
- CharT c = *it;
- if (c == quote_char)
- {
- os.put(quote_escape_char);
- os.put(quote_char);
- }
- else
- {
- os.put(c);
- }
- }
-}
-
-template<typename CharT>
-class basic_csv_serializer : public basic_json_output_handler<CharT>
-{
- struct stack_item
- {
- stack_item(bool is_object)
- : is_object_(is_object), count_(0), skip_(false)
- {
- }
- bool is_object() const
- {
- return is_object_;
- }
-
- bool is_object_;
- size_t count_;
- bool skip_;
- };
- buffered_ostream<CharT> os_;
- basic_csv_parameters<CharT> parameters_;
- basic_output_format<CharT> format_;
- std::vector<stack_item> stack_;
- std::streamsize original_precision_;
- std::ios_base::fmtflags original_format_flags_;
- std::basic_ostringstream<CharT> header_oss_;
- buffered_ostream<CharT> header_os_;
- std::map<std::basic_string<CharT>,size_t> header_;
- float_printer<CharT> fp_;
-public:
- basic_csv_serializer(std::basic_ostream<CharT>& os)
- :
- os_(os),
- format_(),
- stack_(),
- original_precision_(),
- original_format_flags_(),
- header_os_(header_oss_),
- header_(),
- fp_(format_.precision())
- {
- }
-
- basic_csv_serializer(std::basic_ostream<CharT>& os,
- basic_csv_parameters<CharT> params)
- :
- os_(os),
- parameters_(params),
- format_(),
- stack_(),
- original_precision_(),
- original_format_flags_(),
- header_os_(header_oss_),
- header_(),
- fp_(format_.precision())
- {
- }
-
- ~basic_csv_serializer()
- {
- }
-
-private:
-
- void do_begin_json() override
- {
- }
-
- void do_end_json() override
- {
- }
-
- void do_begin_object() override
- {
- stack_.push_back(stack_item(true));
- }
-
- void do_end_object() override
- {
- if (stack_.size() == 2)
- {
- os_.write(parameters_.line_delimiter());
- if (stack_[0].count_ == 0)
- {
- os_.write(header_oss_.str());
- os_.write(parameters_.line_delimiter());
- }
- }
- stack_.pop_back();
-
- end_value();
- }
-
- void do_begin_array() override
- {
- stack_.push_back(stack_item(false));
- }
-
- void do_end_array() override
- {
- if (stack_.size() == 2)
- {
- os_.write(parameters_.line_delimiter());
- }
- stack_.pop_back();
-
- end_value();
- }
-
- void do_name(const CharT* name, size_t length) override
- {
- if (stack_.size() == 2)
- {
- if (stack_[0].count_ == 0)
- {
- if (stack_.back().count_ > 0)
- {
- os_.put(parameters_.field_delimiter());
- }
- bool quote = false;
- if (parameters_.quote_style() == quote_styles::all || parameters_.quote_style() == quote_styles::nonnumeric ||
- (parameters_.quote_style() == quote_styles::minimal && std::char_traits<CharT>::find(name,length,parameters_.field_delimiter()) != nullptr))
- {
- quote = true;
- os_.put(parameters_.quote_char());
- }
- jsoncons::csv::escape_string<CharT>(name, length, parameters_.quote_char(), parameters_.quote_escape_char(), os_);
- if (quote)
- {
- os_.put(parameters_.quote_char());
- }
- header_[name] = stack_.back().count_;
- }
- else
- {
- typename std::map<std::basic_string<CharT>,size_t>::iterator it = header_.find(std::basic_string<CharT>(name,length));
- if (it == header_.end())
- {
- stack_.back().skip_ = true;
- //std::cout << " Not found ";
- }
- else
- {
- stack_.back().skip_ = false;
- while (stack_.back().count_ < it->second)
- {
- os_.put(parameters_.field_delimiter());
- ++stack_.back().count_;
- }
- // std::cout << " (" << it->value() << " " << stack_.back().count_ << ") ";
- }
- }
- }
- }
-
- void do_null_value() override
- {
- if (stack_.size() == 2 && !stack_.back().skip_)
- {
- if (stack_.back().is_object() && stack_[0].count_ == 0)
- {
- do_null_value(header_os_);
- }
- else
- {
- do_null_value(os_);
- }
- }
- }
-
- void do_string_value(const CharT* val, size_t length) override
- {
- if (stack_.size() == 2 && !stack_.back().skip_)
- {
- if (stack_.back().is_object() && stack_[0].count_ == 0)
- {
- value(val,length,header_os_);
- }
- else
- {
- value(val,length,os_);
- }
- }
- }
-
- void do_double_value(double val, uint8_t precision) override
- {
- if (stack_.size() == 2 && !stack_.back().skip_)
- {
- if (stack_.back().is_object() && stack_[0].count_ == 0)
- {
- value(val,header_os_);
- }
- else
- {
- value(val,os_);
- }
- }
- }
-
- void do_integer_value(int64_t val) override
- {
- if (stack_.size() == 2 && !stack_.back().skip_)
- {
- if (stack_.back().is_object() && stack_[0].count_ == 0)
- {
- value(val,header_os_);
- }
- else
- {
- value(val,os_);
- }
- }
- }
-
- void do_uinteger_value(uint64_t val) override
- {
- if (stack_.size() == 2 && !stack_.back().skip_)
- {
- if (stack_.back().is_object() && stack_[0].count_ == 0)
- {
- value(val,header_os_);
- }
- else
- {
- value(val,os_);
- }
- }
- }
-
- void do_bool_value(bool val) override
- {
- if (stack_.size() == 2 && !stack_.back().skip_)
- {
- if (stack_.back().is_object() && stack_[0].count_ == 0)
- {
- value(val,header_os_);
- }
- else
- {
- value(val,os_);
- }
- }
- }
-
- void value(const CharT* val, size_t length, buffered_ostream<CharT>& os)
- {
- begin_value(os);
-
- bool quote = false;
- if (parameters_.quote_style() == quote_styles::all || parameters_.quote_style() == quote_styles::nonnumeric ||
- (parameters_.quote_style() == quote_styles::minimal && std::char_traits<CharT>::find(val, length, parameters_.field_delimiter()) != nullptr))
- {
- quote = true;
- os.put(parameters_.quote_char());
- }
- jsoncons::csv::escape_string<CharT>(val, length, parameters_.quote_char(), parameters_.quote_escape_char(), os);
- if (quote)
- {
- os.put(parameters_.quote_char());
- }
-
- end_value();
- }
-
- void value(double val, buffered_ostream<CharT>& os)
- {
- begin_value(os);
-
- if (is_nan(val) && format_.replace_nan())
- {
- os.write(format_.nan_replacement());
- }
- else if (is_pos_inf(val) && format_.replace_pos_inf())
- {
- os.write(format_.pos_inf_replacement());
- }
- else if (is_neg_inf(val) && format_.replace_neg_inf())
- {
- os.write(format_.neg_inf_replacement());
- }
- //else if (format_.floatfield() != 0)
- //{
- // std::basic_ostringstream<CharT> ss;
- // ss.imbue(std::locale::classic());
- // ss.setf(format_.floatfield(), std::ios::floatfield);
- // ss << std::showpoint << std::setprecision(format_.precision()) << val;
- // os.write(ss.str());
- //}
- else
- {
- fp_.print(val,format_.precision(),os);
- }
-
- end_value();
-
- }
-
- void value(int64_t val, buffered_ostream<CharT>& os)
- {
- begin_value(os);
-
- std::basic_ostringstream<CharT> ss;
- ss << val;
- os.write(ss.str());
-
- end_value();
- }
-
- void value(uint64_t val, buffered_ostream<CharT>& os)
- {
- begin_value(os);
-
- std::basic_ostringstream<CharT> ss;
- ss << val;
- os.write(ss.str());
-
- end_value();
- }
-
- void value(bool val, buffered_ostream<CharT>& os)
- {
- begin_value(os);
-
- if (val)
- {
- auto buf = json_literals<CharT>::true_literal();
- os.write(buf.first,buf.second);
- }
- else
- {
- auto buf = json_literals<CharT>::false_literal();
- os.write(buf.first,buf.second);
- }
-
- end_value();
- }
-
- void do_null_value(buffered_ostream<CharT>& os)
- {
- begin_value(os);
- auto buf = json_literals<CharT>::null_literal();
- os.write(buf.first,buf.second);
- end_value();
-
- }
-
- void begin_value(buffered_ostream<CharT>& os)
- {
- if (!stack_.empty())
- {
- if (stack_.back().count_ > 0)
- {
- os.put(parameters_.field_delimiter());
- }
- }
- }
-
- void end_value()
- {
- if (!stack_.empty())
- {
- ++stack_.back().count_;
- }
- }
-};
-
-typedef basic_csv_serializer<char> csv_serializer;
-
-}}
-
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons_ext/jsonpath/json_query.hpp b/vendor/jsoncons-0.99.2/jsoncons_ext/jsonpath/json_query.hpp
deleted file mode 100644
index 7e530abd..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons_ext/jsonpath/json_query.hpp
+++ /dev/null
@@ -1,921 +0,0 @@
-// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_JSONPATH_JSONQUERY_HPP
-#define JSONCONS_JSONPATH_JSONQUERY_HPP
-
-#include <string>
-#include <sstream>
-#include <vector>
-#include <istream>
-#include <cstdlib>
-#include <memory>
-#include "jsoncons/json.hpp"
-#include "jsonpath_filter.hpp"
-#include "jsonpath_error_category.hpp"
-
-namespace jsoncons { namespace jsonpath {
-
- template<typename CharT>
- bool try_string_to_index(const CharT *s, size_t length, size_t* value)
- {
- static const size_t max_value = std::numeric_limits<size_t>::max JSONCONS_NO_MACRO_EXP();
- static const size_t max_value_div_10 = max_value / 10;
-
- size_t n = 0;
- for (size_t i = 0; i < length; ++i)
- {
- CharT c = s[i];
- switch (c)
- {
- case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
- {
- size_t x = c - '0';
- if (n > max_value_div_10)
- {
- return false;
- }
- n = n * 10;
- if (n > max_value - x)
- {
- return false;
- }
-
- n += x;
- }
- break;
- default:
- return false;
- break;
- }
- }
- *value = n;
- return true;
- }
-
- template <typename CharT>
- struct json_jsonpath_traits
- {
- };
-
- template <>
- struct json_jsonpath_traits<char>
- {
- static const std::string length_literal() {return "length";};
- };
-
- template <>
- struct json_jsonpath_traits<wchar_t> // assume utf16
- {
- static const std::wstring length_literal() {return L"length";};
- };
-
-// here
-
-template<class JsonT>
-JsonT json_query(const JsonT& root, const typename JsonT::char_type* path, size_t length)
-{
- jsonpath_evaluator<JsonT> evaluator;
- evaluator.evaluate(root,path,length);
- return evaluator.get_values();
-}
-
-template<class JsonT>
-JsonT json_query(const JsonT& root, const typename JsonT::string_type& path)
-{
- return json_query(root,path.data(),path.length());
-}
-
-template<class JsonT>
-JsonT json_query(const JsonT& root, const typename JsonT::char_type* path)
-{
- return json_query(root,path,std::char_traits<typename JsonT::char_type>::length(path));
-}
-
-enum class states
-{
- start,
- cr,
- lf,
- expect_separator,
- expect_unquoted_name,
- unquoted_name,
- single_quoted_name,
- double_quoted_name,
- left_bracket,
- left_bracket_start,
- left_bracket_end,
- left_bracket_end2,
- left_bracket_step,
- left_bracket_step2,
- expect_right_bracket,
- dot
-};
-
-template<class JsonT>
-class jsonpath_evaluator : private basic_parsing_context<typename JsonT::char_type>
-{
-private:
- typedef typename JsonT::char_type char_type;
- typedef typename JsonT::string_type string_type;
- typedef const JsonT* cjson_ptr;
- typedef std::vector<cjson_ptr> node_set;
-
- basic_parse_error_handler<char_type> *err_handler_;
- states state_;
- string_type buffer_;
- size_t start_;
- size_t end_;
- size_t step_;
- bool positive_start_;
- bool positive_end_;
- bool positive_step_;
- bool end_undefined_;
- std::vector<node_set> stack_;
- bool recursive_descent_;
- std::vector<cjson_ptr> nodes_;
- std::vector<std::shared_ptr<JsonT>> temp_;
- size_t line_;
- size_t column_;
- const char_type* begin_input_;
- const char_type* end_input_;
- const char_type* p_;
- states pre_line_break_state_;
-
- void transfer_nodes()
- {
- stack_.push_back(nodes_);
- nodes_.clear();
- }
-
-public:
- jsonpath_evaluator()
- : err_handler_(std::addressof(basic_default_parse_error_handler<char_type>::instance()))
- {
- }
-
- JsonT get_values() const
- {
- JsonT result = JsonT::make_array();
-
- if (stack_.size() > 0)
- {
- for (size_t i = 0; i < stack_.back().size(); ++i)
- {
- cjson_ptr p = stack_.back()[i];
- result.add(*p);
- }
- }
- return result;
- }
-
- void evaluate(const JsonT& root, const string_type& path)
- {
- evaluate(root,path.data(),path.length());
- }
- void evaluate(const JsonT& root, const char_type* path)
- {
- evaluate(root,path,std::char_traits<char_type>::length(path));
- }
-
- void evaluate(const JsonT& root, const char_type* path, size_t length)
- {
- begin_input_ = path;
- end_input_ = path + length;
- p_ = begin_input_;
-
- line_ = 1;
- column_ = 1;
- state_ = states::start;
- buffer_.clear();
- start_ = 0;
- end_ = 0;
- step_ = 1;
- recursive_descent_ = false;
- positive_start_ = true;
- positive_end_ = true;
- positive_step_ = true;
- end_undefined_ = false;
-
- while (p_ < end_input_)
- {
- switch (state_)
- {
- case states::cr:
- ++line_;
- column_ = 1;
- switch (*p_)
- {
- case '\n':
- state_ = pre_line_break_state_;
- ++p_;
- ++column_;
- break;
- default:
- state_ = pre_line_break_state_;
- break;
- }
- break;
- case states::lf:
- ++line_;
- column_ = 1;
- state_ = pre_line_break_state_;
- break;
- case states::start:
- switch (*p_)
- {
- case '\r':
- pre_line_break_state_ = state_;
- state_ = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- break;
- case ' ':case '\t':
- ++p_;
- ++column_;
- break;
- case '$':
- case '@':
- {
- node_set v;
- v.push_back(std::addressof(root));
- stack_.push_back(v);
- state_ = states::expect_separator;
- }
- break;
- default:
- err_handler_->fatal_error(std::error_code(jsonpath_parser_errc::expected_root, jsonpath_error_category()), *this);
- break;
- };
- ++p_;
- ++column_;
- break;
- case states::dot:
- switch (*p_)
- {
- case '.':
- recursive_descent_ = true;
- ++p_;
- ++column_;
- state_ = states::expect_unquoted_name;
- break;
- default:
- state_ = states::expect_unquoted_name;
- break;
- }
- break;
- case states::expect_unquoted_name:
- switch (*p_)
- {
- case '\r':
- pre_line_break_state_ = state_;
- state_ = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- break;
- case '.':
- err_handler_->fatal_error(std::error_code(jsonpath_parser_errc::expected_name, jsonpath_error_category()), *this);
- ++p_;
- ++column_;
- break;
- case '*':
- end_all();
- transfer_nodes();
- state_ = states::expect_separator;
- ++p_;
- ++column_;
- break;
- default:
- state_ = states::unquoted_name;
- break;
- }
- break;
- case states::expect_separator:
- switch (*p_)
- {
- case '\r':
- pre_line_break_state_ = state_;
- state_ = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- break;
- case ' ':case '\t':
- ++p_;
- ++column_;
- break;
- case '.':
- state_ = states::dot;
- break;
- case '[':
- state_ = states::left_bracket;
- break;
- default:
- err_handler_->fatal_error(std::error_code(jsonpath_parser_errc::expected_separator, jsonpath_error_category()), *this);
- break;
- };
- ++p_;
- ++column_;
- break;
- case states::expect_right_bracket:
- switch (*p_)
- {
- case '\r':
- pre_line_break_state_ = state_;
- state_ = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- break;
- case ',':
- state_ = states::left_bracket;
- break;
- case ']':
- transfer_nodes();
- state_ = states::expect_separator;
- break;
- case ' ':case '\t':
- break;
- default:
- err_handler_->fatal_error(std::error_code(jsonpath_parser_errc::expected_right_bracket, jsonpath_error_category()), *this);
- break;
- }
- ++p_;
- ++column_;
- break;
- case states::left_bracket_step:
- switch (*p_)
- {
- case '\r':
- pre_line_break_state_ = state_;
- state_ = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- break;
- case '-':
- positive_step_ = false;
- state_ = states::left_bracket_step2;
- break;
- case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
- step_ = static_cast<size_t>(*p_-'0');
- state_ = states::left_bracket_step2;
- break;
- case ']':
- end_array_slice();
- transfer_nodes();
- state_ = states::expect_separator;
- break;
- }
- ++p_;
- ++column_;
- break;
- case states::left_bracket_step2:
- switch (*p_)
- {
- case '\r':
- pre_line_break_state_ = state_;
- state_ = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- break;
- case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
- step_ = step_*10 + static_cast<size_t>(*p_-'0');
- break;
- case ']':
- end_array_slice();
- transfer_nodes();
- state_ = states::expect_separator;
- break;
- }
- ++p_;
- ++column_;
- break;
- case states::left_bracket_end:
- switch (*p_)
- {
- case '\r':
- pre_line_break_state_ = state_;
- state_ = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- break;
- case '-':
- positive_end_ = false;
- state_ = states::left_bracket_end2;
- break;
- case ':':
- step_ = 0;
- state_ = states::left_bracket_step;
- break;
- case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
- end_undefined_ = false;
- end_ = static_cast<size_t>(*p_-'0');
- state_ = states::left_bracket_end2;
- break;
- case ']':
- end_array_slice();
- transfer_nodes();
- state_ = states::expect_separator;
- break;
- }
- ++p_;
- ++column_;
- break;
- case states::left_bracket_end2:
- switch (*p_)
- {
- case '\r':
- pre_line_break_state_ = state_;
- state_ = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- break;
- case ':':
- step_ = 0;
- state_ = states::left_bracket_step;
- break;
- case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
- end_undefined_ = false;
- end_ = end_*10 + static_cast<size_t>(*p_-'0');
- break;
- case ']':
- end_array_slice();
- transfer_nodes();
- state_ = states::expect_separator;
- break;
- }
- ++p_;
- ++column_;
- break;
- case states::left_bracket_start:
- switch (*p_)
- {
- case '\r':
- pre_line_break_state_ = state_;
- state_ = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- break;
- case ':':
- step_ = 1;
- end_undefined_ = true;
- state_ = states::left_bracket_end;
- break;
- case ',':
- find_elements();
- break;
- case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
- start_ = start_*10 + static_cast<size_t>(*p_-'0');
- break;
- case ']':
- find_elements();
- transfer_nodes();
- state_ = states::expect_separator;
- break;
- }
- ++p_;
- ++column_;
- break;
- case states::left_bracket:
- switch (*p_)
- {
- case '\r':
- pre_line_break_state_ = state_;
- state_ = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- break;
- case ' ':case '\t':
- ++p_;
- ++column_;
- break;
- case '(':
- {
- if (stack_.back().size() == 1)
- {
- jsonpath_filter_parser<JsonT> parser(&p_,&line_,&column_);
- parser.parse(p_,end_input_);
- auto index = parser.eval(*(stack_.back()[0]));
- if (index.template is<size_t>())
- {
- start_ = index. template as<size_t>();
- find_elements();
- }
- else if (index.is_string())
- {
- find(index.as_string());
- }
- }
- else
- {
- ++p_;
- ++column_;
- }
- }
- break;
- case '?':
- {
- jsonpath_filter_parser<JsonT> parser(&p_,&line_,&column_);
- parser.parse(p_,end_input_);
- nodes_.clear();
- for (size_t j = 0; j < stack_.back().size(); ++j)
- {
- accept(*(stack_.back()[j]),parser);
- }
- }
- break;
-
- case ':':
- step_ = 1;
- end_undefined_ = true;
- state_ = states::left_bracket_end;
- ++p_;
- ++column_;
- break;
- case ',':
- find_elements();
- ++p_;
- ++column_;
- break;
- case '-':
- positive_start_ = false;
- state_ = states::left_bracket_start;
- ++p_;
- ++column_;
- break;
- case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
- start_ = static_cast<size_t>(*p_-'0');
- state_ = states::left_bracket_start;
- ++p_;
- ++column_;
- break;
- case ']':
- //find_elements();
- transfer_nodes();
- state_ = states::expect_separator;
- ++p_;
- ++column_;
- break;
- case '*':
- end_all();
- //transfer_nodes();
- state_ = states::expect_right_bracket;
- ++p_;
- ++column_;
- break;
- case '\'':
- state_ = states::single_quoted_name;
- ++p_;
- ++column_;
- break;
- case '\"':
- state_ = states::double_quoted_name;
- ++p_;
- ++column_;
- break;
- default:
- ++p_;
- ++column_;
- break;
- }
- break;
- case states::unquoted_name:
- switch (*p_)
- {
- case '\r':
- pre_line_break_state_ = state_;
- state_ = states::cr;
- break;
- case '\n':
- pre_line_break_state_ = state_;
- state_ = states::lf;
- break;
- case '[':
- find(buffer_);
- buffer_.clear();
- transfer_nodes();
- start_ = 0;
- state_ = states::left_bracket;
- break;
- case '.':
- find(buffer_);
- buffer_.clear();
- transfer_nodes();
- state_ = states::dot;
- break;
- case ' ':case '\t':
- break;
- default:
- buffer_.push_back(*p_);
- break;
- };
- ++p_;
- ++column_;
- break;
- case states::single_quoted_name:
- switch (*p_)
- {
- case '\'':
- find(buffer_);
- buffer_.clear();
- state_ = states::expect_right_bracket;
- break;
- case '\\':
- buffer_.push_back(*p_);
- if (p_+1 < end_input_)
- {
- ++p_;
- ++column_;
- buffer_.push_back(*p_);
- }
- break;
- default:
- buffer_.push_back(*p_);
- break;
- };
- ++p_;
- ++column_;
- break;
- case states::double_quoted_name:
- switch (*p_)
- {
- case '\"':
- find(buffer_);
- buffer_.clear();
- state_ = states::expect_right_bracket;
- break;
- case '\\':
- buffer_.push_back(*p_);
- if (p_+1 < end_input_)
- {
- ++p_;
- ++column_;
- buffer_.push_back(*p_);
- }
- break;
- default:
- buffer_.push_back(*p_);
- break;
- };
- ++p_;
- ++column_;
- break;
- default:
- ++p_;
- ++column_;
- break;
- }
- }
- switch (state_)
- {
- case states::unquoted_name:
- {
- find(buffer_);
- buffer_.clear();
- transfer_nodes();
- }
- break;
- default:
- break;
- }
- }
-
- void accept(const JsonT& val,
- jsonpath_filter_parser<JsonT>& filter)
- {
- if (val.is_object())
- {
- if (recursive_descent_ && val.is_object())
- {
- for (auto it = val.members().begin(); it != val.members().end(); ++it)
- {
- accept(it->value(),filter);
- }
- }
- if (filter.exists(val))
- {
- nodes_.push_back(std::addressof(val));
- }
- }
- else if (val.is_array())
- {
- for (auto it = val.elements().begin(); it != val.elements().end(); ++it)
- {
- accept(*it,filter);
- }
- }
- }
-
-
-
- void end_all()
- {
- for (size_t i = 0; i < stack_.back().size(); ++i)
- {
- cjson_ptr p = stack_.back()[i];
- if (p->is_array())
- {
- for (auto it = p->elements().begin(); it != p->elements().end(); ++it)
- {
- nodes_.push_back(std::addressof(*it));
- }
- }
- else if (p->is_object())
- {
- for (auto it = p->members().begin(); it != p->members().end(); ++it)
- {
- nodes_.push_back(std::addressof(it->value()));
- }
- }
-
- }
- start_ = 0;
- }
-
- void find_elements()
- {
- for (size_t i = 0; i < stack_.back().size(); ++i)
- {
- cjson_ptr p = stack_.back()[i];
- if (p->is_array() && start_ < p->size())
- {
- nodes_.push_back(std::addressof((*p)[start_]));
- }
- }
- start_ = 0;
- }
-
- void end_array_slice()
- {
- if (positive_step_)
- {
- end_array_slice1();
- }
- else
- {
- end_array_slice2();
- }
- start_ = 0;
- end_ = 0;
- step_ = 1;
- positive_start_ = positive_end_ = positive_step_ = true;
- end_undefined_ = true;
- }
-
- void end_array_slice1()
- {
- for (size_t i = 0; i < stack_.back().size(); ++i)
- {
- cjson_ptr p = stack_.back()[i];
- if (p->is_array())
- {
- size_t start = positive_start_ ? start_ : p->size() - start_;
- size_t end;
- if (!end_undefined_)
- {
- end = positive_end_ ? end_ : p->size() - end_;
- }
- else
- {
- end = p->size();
- }
- for (size_t j = start; j < end; j += step_)
- {
- if (p->is_array() && j < p->size())
- {
- nodes_.push_back(std::addressof((*p)[j]));
- }
- }
- }
- }
- }
-
- void end_array_slice2()
- {
- for (size_t i = 0; i < stack_.back().size(); ++i)
- {
- cjson_ptr p = stack_.back()[i];
- size_t start = positive_start_ ? start_ : p->size() - start_;
- size_t end;
- if (!end_undefined_)
- {
- end = positive_end_ ? end_ : p->size() - end_;
- }
- else
- {
- end = p->size();
- }
-
- size_t j = end + step_ - 1;
- while (j > (start+step_-1))
- {
- j -= step_;
- if (p->is_array() && j < p->size())
- {
- nodes_.push_back(std::addressof((*p)[j]));
- }
- }
- }
- }
-
- void find(const string_type& name)
- {
- if (name.length() > 0)
- {
- for (size_t i = 0; i < stack_.back().size(); ++i)
- {
- find1(*(stack_.back()[i]), name);
- }
- recursive_descent_ = false;
- }
- }
-
- void find1(const JsonT& context_val, const string_type& name)
- {
- if (context_val.is_object())
- {
- if (context_val.count(name) > 0)
- {
- nodes_.push_back(std::addressof(context_val.at(name)));
- }
- if (recursive_descent_)
- {
- for (auto it = context_val.members().begin(); it != context_val.members().end(); ++it)
- {
- if (it->value().is_object() || it->value().is_array())
- {
- find1(it->value(), name);
- }
- }
- }
- }
- else if (context_val.is_array())
- {
- size_t index = 0;
- if (try_string_to_index(name.data(),name.size(),&index))
- {
- if (index < context_val.size())
- {
- nodes_.push_back(std::addressof(context_val[index]));
- }
- }
- else if (name == json_jsonpath_traits<char_type>::length_literal() && context_val.size() > 0)
- {
- auto q = std::make_shared<JsonT>(context_val.size());
- temp_.push_back(q);
- nodes_.push_back(q.get());
- }
- if (recursive_descent_)
- {
- for (auto it = context_val.elements().begin(); it != context_val.elements().end(); ++it)
- {
- if (it->is_object() || it->is_array())
- {
- find1(*it, name);
- }
- }
- }
- }
- }
-
- size_t do_line_number() const override
- {
- return line_;
- }
-
- size_t do_column_number() const override
- {
- return column_;
- }
-
- char_type do_current_char() const override
- {
- return 0; //p_ < end_input_? *p_ : 0;
- }
-
-};
-
-}}
-
-#endif
diff --git a/vendor/jsoncons-0.99.2/jsoncons_ext/jsonpath/jsonpath_filter.hpp b/vendor/jsoncons-0.99.2/jsoncons_ext/jsonpath/jsonpath_filter.hpp
deleted file mode 100644
index b0ac51c6..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons_ext/jsonpath/jsonpath_filter.hpp
+++ /dev/null
@@ -1,1495 +0,0 @@
-// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_JSONPATH_FILTER_HPP
-#define JSONCONS_JSONPATH_FILTER_HPP
-
-#include <string>
-#include <sstream>
-#include <vector>
-#include <istream>
-#include <cstdlib>
-#include <memory>
-#include <regex>
-#include "jsoncons/json.hpp"
-#include "jsonpath_error_category.hpp"
-
-namespace jsoncons { namespace jsonpath {
-
-template <class JsonT>
-class jsonpath_evaluator;
-
-enum class filter_states
-{
- start,
- cr,
- lf,
- expect_right_round_bracket,
- expect_oper_or_right_round_bracket,
- expect_path_or_value,
- expect_regex,
- regex,
- single_quoted_text,
- double_quoted_text,
- unquoted_text,
- path,
- value,
- oper
-};
-
-enum class token_types
-{
- left_paren,
- right_paren,
- term,
- eq,
- ne,
- regex,
- ampamp,
- pipepipe,
- lt,
- gt,
- lte,
- gte,
- plus,
- minus,
- exclaim,
- done
-};
-
-template <class JsonT>
-class term
-{
-public:
- typedef typename JsonT::string_type string_type;
- typedef typename JsonT::char_type char_type;
-
- virtual void initialize(const JsonT& context_node)
- {
- }
- virtual bool accept_single_node() const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual JsonT evaluate_single_node() const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual bool exclaim() const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual bool eq(const term& rhs) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual bool eq(const JsonT& rhs) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual bool ne(const term& rhs) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual bool ne(const JsonT& rhs) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual bool regex(const term& rhs) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual bool regex2(const string_type& subject) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual bool ampamp(const term& rhs) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual bool ampamp(const JsonT& rhs) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual bool pipepipe(const term& rhs) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual bool pipepipe(const JsonT& rhs) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual bool lt(const term& rhs) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual bool lt(const JsonT& rhs) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual bool gt(const term& rhs) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual bool gt(const JsonT& rhs) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual JsonT minus(const term& rhs) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual JsonT minus(const JsonT& rhs) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual JsonT unary_minus() const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual JsonT plus(const term& rhs) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
- virtual JsonT plus(const JsonT& rhs) const
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unsupported_operator, jsonpath_error_category()),1,1);
- }
-};
-
-template <class JsonT>
-class token
-{
- token_types type_;
- std::shared_ptr<term<JsonT>> term_ptr_;
-public:
- token(token_types type)
- : type_(type)
- {
- }
- token(token_types type, std::shared_ptr<term<JsonT>> term_ptr)
- : type_(type), term_ptr_(term_ptr)
- {
- }
- token(const token& t)
- : type_(t.type_), term_ptr_(t.term_ptr_)
- {
- }
-
- token_types type() const
- {
- return type_;
- }
-
- std::shared_ptr<term<JsonT>> term_ptr()
- {
- return term_ptr_;
- }
-
- void initialize(const JsonT& context_node)
- {
- if (term_ptr_.get() != nullptr)
- {
- term_ptr_->initialize(context_node);
- }
- }
-};
-
-template <class JsonT>
-class token_stream
-{
- std::vector<token<JsonT>>& tokens_;
- size_t index_;
-public:
- token_stream(std::vector<token<JsonT>>& tokens)
- : tokens_(tokens), index_(0)
- {
- }
-
- token<JsonT> get()
- {
- static token<JsonT> done = token<JsonT>(token_types::done);
- return index_ < tokens_.size() ? tokens_[index_++] : done;
- }
- void putback()
- {
- --index_;
- }
-};
-
-template <class JsonT>
-bool ampamp(const JsonT& lhs, const JsonT& rhs)
-{
- return lhs.as_bool() && rhs.as_bool();
-}
-
-template <class JsonT>
-bool pipepipe(const JsonT& lhs, const JsonT& rhs)
-{
- return lhs.as_bool() || rhs.as_bool();
-}
-
-template <class JsonT>
-bool lt(const JsonT& lhs, const JsonT& rhs)
-{
- bool result = false;
- if (lhs. template is<unsigned long long>() && rhs. template is<unsigned long long>())
- {
- result = lhs. template as<unsigned long long>() < rhs. template as<unsigned long long>();
- }
- else if (lhs. template is<long long>() && rhs. template is<long long>())
- {
- result = lhs. template as<long long>() < rhs. template as<long long>();
- }
- else if ((lhs.is_number() && rhs.is_double()) || (lhs.is_double() && rhs.is_number()))
- {
- result = lhs.as_double() < rhs.as_double();
- }
- else if (lhs.is_string() && rhs.is_string())
- {
- result = lhs.as_string() < rhs.as_string();
- }
- return result;
-}
-
-template <class JsonT>
-bool gt(const JsonT& lhs, const JsonT& rhs)
-{
- return lt(rhs,lhs);
-}
-
-template <class JsonT>
-JsonT plus(const JsonT& lhs, const JsonT& rhs)
-{
- JsonT result = jsoncons::null_type();
- if (lhs.is_integer() && rhs.is_integer())
- {
- result = ((lhs.as_integer() + rhs.as_integer()));
- }
- else if ((lhs.is_number() && rhs.is_double()) || (lhs.is_double() && rhs.is_number()))
- {
- result = (lhs.as_double() + rhs.as_double());
- }
- else if (lhs.is_uinteger() && rhs.is_uinteger())
- {
- result = (lhs.as_uinteger() + rhs.as_uinteger());
- }
- return result;
-}
-
-template <class JsonT>
-JsonT unary_minus(const JsonT& lhs)
-{
- JsonT result = jsoncons::null_type();
- if (lhs.is_integer())
- {
- result = -lhs.as_integer();
- }
- else if (lhs.is_double())
- {
- result = -lhs.as_double();
- }
- return result;
-}
-
-template <class JsonT>
-JsonT minus(const JsonT& lhs, const JsonT& rhs)
-{
- JsonT result = jsoncons::null_type();
- if (lhs.is_integer() && rhs.is_integer())
- {
- result = ((lhs.as_integer() - rhs.as_integer()));
- }
- else if ((lhs.is_number() && rhs.is_double()) || (lhs.is_double() && rhs.is_number()))
- {
- result = (lhs.as_double() - rhs.as_double());
- }
- else if (lhs.is_uinteger() && rhs.is_uinteger() && lt(rhs,lhs))
- {
- result = (lhs.as_uinteger() - rhs.as_uinteger());
- }
- return result;
-}
-
-template <class JsonT>
-class value_term : public term<JsonT>
-{
- JsonT value_;
-public:
- template <class T>
- value_term(const T& value)
- : value_(value)
- {
- }
-
- bool accept_single_node() const override
- {
- return value_.as_bool();
- }
-
- JsonT evaluate_single_node() const override
- {
- return value_;
- }
-
- bool exclaim() const override
- {
- return !value_.as_bool();
- }
-
- bool eq(const term<JsonT>& rhs) const override
- {
- return rhs.eq(value_);
- }
-
- bool eq(const JsonT& rhs) const override
- {
- return value_ == rhs;
- }
-
- bool ne(const term<JsonT>& rhs) const override
- {
- return rhs.ne(value_);
- }
- bool ne(const JsonT& rhs) const override
- {
- return value_ != rhs;
- }
- bool regex(const term<JsonT>& rhs) const override
- {
- return rhs.regex2(value_.as_string());
- }
- bool ampamp(const term<JsonT>& rhs) const override
- {
- return rhs.ampamp(value_);
- }
- bool ampamp(const JsonT& rhs) const override
- {
- return jsoncons::jsonpath::ampamp(value_,rhs);
- }
- bool pipepipe(const term<JsonT>& rhs) const override
- {
- return rhs.pipepipe(value_);
- }
- bool pipepipe(const JsonT& rhs) const override
- {
- return jsoncons::jsonpath::pipepipe(value_,rhs);
- }
-
- bool lt(const term<JsonT>& rhs) const override
- {
- return rhs.gt(value_);
- }
-
- bool lt(const JsonT& rhs) const override
- {
- return jsoncons::jsonpath::lt(value_,rhs);
- }
-
- bool gt(const term<JsonT>& rhs) const override
- {
- return rhs.lt(value_);
- }
-
- bool gt(const JsonT& rhs) const override
- {
- return jsoncons::jsonpath::gt(value_,rhs);
- }
-
- JsonT minus(const term<JsonT>& rhs) const override
- {
- return jsoncons::jsonpath::plus(rhs.unary_minus(),value_);
- }
-
- JsonT minus(const JsonT& rhs) const override
- {
- return jsoncons::jsonpath::minus(value_,rhs);
- }
-
- JsonT unary_minus() const override
- {
- return jsoncons::jsonpath::unary_minus(value_);
- }
-
- JsonT plus(const term<JsonT>& rhs) const override
- {
- return rhs.plus(value_);
- }
-
- JsonT plus(const JsonT& rhs) const override
- {
- return jsoncons::jsonpath::plus(value_,rhs);
- }
-};
-
-template <class JsonT>
-class regex_term : public term<JsonT>
-{
- typedef typename JsonT::char_type char_type;
- typedef typename JsonT::string_type string_type;
- string_type pattern_;
- std::regex::flag_type flags_;
-public:
- regex_term(const string_type& pattern, std::regex::flag_type flags)
- : pattern_(pattern), flags_(flags)
- {
- }
-
- bool regex2(const string_type& subject) const override
- {
- std::basic_regex<char_type> pattern(pattern_,
- flags_);
- return std::regex_match(subject, pattern);
- }
-};
-
-template <class JsonT>
-class path_term : public term<JsonT>
-{
- typedef typename JsonT::string_type string_type;
-
- string_type path_;
- JsonT nodes_;
-public:
- path_term(const string_type& path)
- : path_(path)
- {
- }
-
- void initialize(const JsonT& context_node) override
- {
- jsonpath_evaluator<JsonT> evaluator;
- evaluator.evaluate(context_node,path_);
- nodes_ = evaluator.get_values();
- }
-
- bool accept_single_node() const override
- {
- return nodes_.size() != 0;
- }
-
- JsonT evaluate_single_node() const override
- {
- return nodes_.size() == 1 ? nodes_[0] : nodes_;
- }
-
- bool exclaim() const override
- {
- return nodes_.size() == 0;
- }
-
- bool eq(const term<JsonT>& rhs) const override
- {
- bool result = false;
- if (nodes_.size() > 0)
- {
- result = true;
- for (size_t i = 0; result && i < nodes_.size(); ++i)
- {
- result = rhs.eq(nodes_[i]);
- }
- }
- return result;
- }
-
- bool eq(const JsonT& rhs) const override
- {
- bool result = false;
- if (nodes_.size() > 0)
- {
- result = true;
- for (size_t i = 0; result && i < nodes_.size(); ++i)
- {
- result = nodes_[i] == rhs;
- }
- }
- return result;
- }
-
- bool ne(const term<JsonT>& rhs) const override
- {
- bool result = false;
- if (nodes_.size() > 0)
- {
- result = true;
- for (size_t i = 0; result && i < nodes_.size(); ++i)
- {
- result = rhs.ne(nodes_[i]);
- }
- }
- return result;
-
- }
- bool ne(const JsonT& rhs) const override
- {
- bool result = false;
- if (nodes_.size() > 0)
- {
- result = true;
- for (size_t i = 0; result && i < nodes_.size(); ++i)
- {
- result = nodes_[i] != rhs;
- }
- }
- return result;
- }
- bool regex(const term<JsonT>& rhs) const override
- {
- bool result = false;
- if (nodes_.size() > 0)
- {
- result = true;
- for (size_t i = 0; result && i < nodes_.size(); ++i)
- {
- result = rhs.regex2(nodes_[i].as_string());
- }
- }
- return result;
- }
- bool ampamp(const term<JsonT>& rhs) const override
- {
- bool result = false;
- if (nodes_.size() > 0)
- {
- result = true;
- for (size_t i = 0; result && i < nodes_.size(); ++i)
- {
- result = rhs.ampamp(nodes_[i]);
- }
- }
- return result;
- }
- bool ampamp(const JsonT& rhs) const override
- {
- bool result = false;
- if (nodes_.size() > 0)
- {
- result = true;
- for (size_t i = 0; result && i < nodes_.size(); ++i)
- {
- result = jsoncons::jsonpath::ampamp(nodes_[i],rhs);
- }
- }
- return result;
- }
- bool pipepipe(const term<JsonT>& rhs) const override
- {
- bool result = false;
- if (nodes_.size() > 0)
- {
- result = true;
- for (size_t i = 0; result && i < nodes_.size(); ++i)
- {
- result = rhs.pipepipe(nodes_[i]);
- }
- }
- return result;
- }
- bool pipepipe(const JsonT& rhs) const override
- {
- bool result = false;
- if (nodes_.size() > 0)
- {
- result = true;
- for (size_t i = 0; result && i < nodes_.size(); ++i)
- {
- result = jsoncons::jsonpath::pipepipe(nodes_[i],rhs);
- }
- }
- return result;
- }
-
- bool lt(const JsonT& rhs) const override
- {
- bool result = false;
- if (nodes_.size() > 0)
- {
- result = true;
- for (size_t i = 0; result && i < nodes_.size(); ++i)
- {
- result = jsoncons::jsonpath::lt(nodes_[i],rhs);
- }
- }
- return result;
- }
-
- bool lt(const term<JsonT>& rhs) const override
- {
- bool result = false;
- if (nodes_.size() > 0)
- {
- result = true;
- for (size_t i = 0; result && i < nodes_.size(); ++i)
- {
- result = rhs.gt(nodes_[i]);
- }
- }
- return result;
- }
-
- bool gt(const JsonT& rhs) const override
- {
- bool result = false;
- if (nodes_.size() > 0)
- {
- result = true;
- for (size_t i = 0; result && i < nodes_.size(); ++i)
- {
- result = jsoncons::jsonpath::gt(nodes_[i],rhs);
- }
- }
- return result;
- }
-
- bool gt(const term<JsonT>& rhs) const override
- {
- bool result = false;
- if (nodes_.size() > 0)
- {
- result = true;
- for (size_t i = 0; result && i < nodes_.size(); ++i)
- {
- result = rhs.lt(nodes_[i]);
- }
- }
- return result;
- }
-
- JsonT minus(const JsonT& rhs) const override
- {
- return nodes_.size() == 1 ? jsoncons::jsonpath::minus(nodes_[0],rhs) : jsoncons::null_type();
- }
-
- JsonT minus(const term<JsonT>& rhs) const override
- {
-
- return nodes_.size() == 1 ? jsoncons::jsonpath::plus(rhs.unary_minus(),nodes_[0]) : jsoncons::null_type();
- }
-
- JsonT unary_minus() const override
- {
- return nodes_.size() == 1 ? jsoncons::jsonpath::unary_minus(nodes_[0]) : jsoncons::null_type();
- }
-
- JsonT plus(const JsonT& rhs) const override
- {
- static auto a_null = jsoncons::null_type();
- return nodes_.size() == 1 ? jsoncons::jsonpath::plus(nodes_[0],rhs) : a_null;
- }
-
- JsonT plus(const term<JsonT>& rhs) const override
- {
- static auto a_null = jsoncons::null_type();
- return nodes_.size() == 1 ? rhs.plus(nodes_[0]) : a_null;
- }
-};
-
-template <class JsonT>
-class jsonpath_filter_parser
-{
- typedef typename JsonT::string_type string_type;
- typedef typename JsonT::char_type char_type;
-
- size_t& line_;
- size_t& column_;
- filter_states state_;
- string_type buffer_;
- std::vector<token<JsonT>> tokens_;
- int depth_;
- const char_type* begin_input_;
- const char_type* end_input_;
- const char_type*& p_;
- filter_states pre_line_break_state_;
-public:
- jsonpath_filter_parser(const char_type** expr, size_t* line,size_t* column)
- : line_(*line), column_(*column),p_(*expr)
- {
- }
-
- bool exists(const JsonT& context_node)
- {
- for (auto it=tokens_.begin(); it != tokens_.end(); ++it)
- {
- it->initialize(context_node);
- }
- bool result = false;
-
- token_stream<JsonT> ts(tokens_);
- auto e = expression(ts);
- result = e->accept_single_node();
-
- return result;
- }
-
- JsonT eval(const JsonT& context_node)
- {
- try
- {
- for (auto it=tokens_.begin(); it != tokens_.end(); ++it)
- {
- it->initialize(context_node);
- }
-
- token_stream<JsonT> ts(tokens_);
- auto e = expression(ts);
- JsonT result = e->evaluate_single_node();
-
- return result;
- }
- catch (const parse_exception& e)
- {
- throw parse_exception(e.code(),line_,column_);
- }
- }
-
- std::shared_ptr<term<JsonT>> primary(token_stream<JsonT>& ts)
- {
- auto t = ts.get();
-
- switch (t.type())
- {
- case token_types::left_paren:
- {
- auto expr = expression(ts);
- t = ts.get();
- if (t.type() != token_types::right_paren)
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_expected_right_brace, jsonpath_error_category()),line_,column_);
- }
- return expr;
- }
- case token_types::term:
- return t.term_ptr();
- case token_types::exclaim:
- {
- JsonT val = primary(ts)->exclaim();
- auto expr = std::make_shared<value_term<JsonT>>(val);
- return expr;
- }
- case token_types::minus:
- {
- JsonT val = primary(ts)->unary_minus();
- auto expr = std::make_shared<value_term<JsonT>>(val);
- return expr;
- }
- default:
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_expected_primary, jsonpath_error_category()),line_,column_);
- }
- }
-
- std::shared_ptr<term<JsonT>> expression(token_stream<JsonT>& ts)
- {
- auto left = make_term(ts);
- auto t = ts.get();
- while (true)
- {
- switch (t.type())
- {
- case token_types::plus:
- {
- JsonT val = left->plus(*(make_term(ts)));
- left = std::make_shared<value_term<JsonT>>(val);
- t = ts.get();
- }
- break;
- case token_types::minus:
- {
- JsonT val = left->minus(*(make_term(ts)));
- left = std::make_shared<value_term<JsonT>>(val);
- t = ts.get();
- }
- break;
- default:
- ts.putback();
- return left;
- }
- }
- return left;
- }
-
- std::shared_ptr<term<JsonT>> make_term(token_stream<JsonT>& ts)
- {
- auto left = primary(ts);
- auto t = ts.get();
- while (true)
- {
- switch (t.type())
- {
- case token_types::eq:
- {
- bool e = left->eq(*(primary(ts)));
- JsonT val(e);
- left = std::make_shared<value_term<JsonT>>(val);
- t = ts.get();
- }
- break;
- case token_types::ne:
- {
- bool e = left->ne(*(primary(ts)));
- JsonT val(e);
- left = std::make_shared<value_term<JsonT>>(val);
- t = ts.get();
- }
- break;
- case token_types::regex:
- {
- bool e = left->regex(*(primary(ts)));
- JsonT val(e);
- left = std::make_shared<value_term<JsonT>>(val);
- t = ts.get();
- }
- break;
- case token_types::ampamp:
- {
- bool e = left->ampamp(*(primary(ts)));
- JsonT val(e);
- left = std::make_shared<value_term<JsonT>>(val);
- t = ts.get();
- }
- break;
- case token_types::pipepipe:
- {
- bool e = left->pipepipe(*(primary(ts)));
- JsonT val(e);
- left = std::make_shared<value_term<JsonT>>(val);
- t = ts.get();
- }
- break;
- case token_types::lt:
- {
- bool e = left->lt(*(primary(ts)));
- JsonT val(e);
- left = std::make_shared<value_term<JsonT>>(val);
- t = ts.get();
- }
- break;
- case token_types::gt:
- {
- bool e = left->gt(*(primary(ts)));
- JsonT val(e);
- left = std::make_shared<value_term<JsonT>>(val);
- t = ts.get();
- }
- break;
- case token_types::lte:
- {
- bool e = left->lt(*(primary(ts))) || left->eq(*(primary(ts)));
- JsonT val(e);
- left = std::make_shared<value_term<JsonT>>(val);
- t = ts.get();
- }
- break;
- case token_types::gte:
- {
- bool e = left->gt(*(primary(ts))) || left->eq(*(primary(ts)));
- JsonT val(e);
- left = std::make_shared<value_term<JsonT>>(val);
- t = ts.get();
- }
- break;
- default:
- ts.putback();
- return left;
- }
- }
- }
-
- void parse(const char_type* expr, size_t length)
- {
- parse(expr,expr+length);
- }
-
- void parse(const char_type* expr, const char_type* end_expr)
- {
- p_ = expr;
- end_input_ = end_expr;
- depth_ = 0;
- tokens_.clear();
- state_ = filter_states::start;
- bool done = false;
- while (!done && p_ < end_input_)
- {
- switch (state_)
- {
- case filter_states::cr:
- ++line_;
- column_ = 1;
- switch (*p_)
- {
- case '\n':
- state_ = pre_line_break_state_;
- ++p_;
- ++column_;
- break;
- default:
- state_ = pre_line_break_state_;
- break;
- }
- break;
- case filter_states::lf:
- ++line_;
- column_ = 1;
- state_ = pre_line_break_state_;
- break;
- case filter_states::start:
- switch (*p_)
- {
- case '\r':
- case '\n':
- pre_line_break_state_ = state_;
- state_ = filter_states::lf;
- break;
- case '(':
- state_ = filter_states::expect_path_or_value;
- ++depth_;
- tokens_.push_back(token<JsonT>(token_types::left_paren));
- break;
- case ')':
- tokens_.push_back(token<JsonT>(token_types::right_paren));
- if (--depth_ == 0)
- {
- done = true;
- }
- break;
- }
- ++p_;
- ++column_;
- break;
- case filter_states::oper:
- switch (*p_)
- {
- case '\r':
- case '\n':
- ++line_;
- column_ = 1;
- state_ = pre_line_break_state_;
- break;
- case '!':
- if (p_+1 < end_input_ && *(p_+1) == '=')
- {
- ++p_;
- ++column_;
- state_ = filter_states::expect_path_or_value;
- tokens_.push_back(token<JsonT>(token_types::ne));
- }
- else
- {
- state_ = filter_states::expect_path_or_value;
- tokens_.push_back(token<JsonT>(token_types::exclaim));
- }
- break;
- case '&':
- if (p_+1 < end_input_ && *(p_+1) == '&')
- {
- ++p_;
- ++column_;
- state_ = filter_states::expect_path_or_value;
- tokens_.push_back(token<JsonT>(token_types::ampamp));
- }
- break;
- case '|':
- if (p_+1 < end_input_ && *(p_+1) == '|')
- {
- ++p_;
- ++column_;
- state_ = filter_states::expect_path_or_value;
- tokens_.push_back(token<JsonT>(token_types::pipepipe));
- }
- break;
- case '=':
- if (p_+1 < end_input_ && *(p_+1) == '=')
- {
- ++p_;
- ++column_;
- state_ = filter_states::expect_path_or_value;
- tokens_.push_back(token<JsonT>(token_types::eq));
- }
- else if (p_+1 < end_input_ && *(p_+1) == '~')
- {
- ++p_;
- ++column_;
- state_ = filter_states::expect_regex;
- tokens_.push_back(token<JsonT>(token_types::regex));
- }
- break;
- case '>':
- if (p_+1 < end_input_ && *(p_+1) == '=')
- {
- ++p_;
- ++column_;
- state_ = filter_states::expect_path_or_value;
- tokens_.push_back(token<JsonT>(token_types::gte));
- }
- else
- {
- state_ = filter_states::expect_path_or_value;
- tokens_.push_back(token<JsonT>(token_types::gt));
- }
- break;
- case '<':
- if (p_+1 < end_input_ && *(p_+1) == '=')
- {
- ++p_;
- ++column_;
- state_ = filter_states::expect_path_or_value;
- tokens_.push_back(token<JsonT>(token_types::lte));
- }
- else
- {
- state_ = filter_states::expect_path_or_value;
- tokens_.push_back(token<JsonT>(token_types::lt));
- }
- break;
- case '+':
- state_ = filter_states::expect_path_or_value;
- tokens_.push_back(token<JsonT>(token_types::plus));
- break;
- case '-':
- state_ = filter_states::expect_path_or_value;
- tokens_.push_back(token<JsonT>(token_types::minus));
- break;
- case ' ':case '\t':
- break;
- default:
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter, jsonpath_error_category()),line_,column_);
- break;
-
- }
- ++p_;
- ++column_;
- break;
- case filter_states::unquoted_text:
- {
- switch (*p_)
- {
- case '\r':
- case '\n':
- ++line_;
- column_ = 1;
- state_ = pre_line_break_state_;
- break;
- case '<':
- case '>':
- case '!':
- case '=':
- case '&':
- case '|':
- case '+':
- case '-':
- {
- if (buffer_.length() > 0)
- {
- try
- {
- auto val = JsonT::parse(buffer_);
- tokens_.push_back(token<JsonT>(token_types::term,std::make_shared<value_term<JsonT>>(val)));
- }
- catch (const parse_exception& e)
- {
- throw parse_exception(e.code(),line_,column_);
- }
- buffer_.clear();
- }
- state_ = filter_states::oper;
- }
- break;
- case ')':
- if (buffer_.length() > 0)
- {
- try
- {
- auto val = JsonT::parse(buffer_);
- tokens_.push_back(token<JsonT>(token_types::term,std::make_shared<value_term<JsonT>>(val)));
- }
- catch (const parse_exception& e)
- {
- throw parse_exception(e.code(),line_,column_);
- }
- buffer_.clear();
- }
- tokens_.push_back(token<JsonT>(token_types::right_paren));
- if (--depth_ == 0)
- {
- state_ = filter_states::start;
- done = true;
- }
- else
- {
- state_ = filter_states::expect_path_or_value;
- }
- ++p_;
- ++column_;
- break;
- case ' ':case '\t':
- if (buffer_.length() > 0)
- {
- try
- {
- auto val = JsonT::parse(buffer_);
- tokens_.push_back(token<JsonT>(token_types::term,std::make_shared<value_term<JsonT>>(val)));
- }
- catch (const parse_exception& e)
- {
- throw parse_exception(e.code(),line_,column_);
- }
- buffer_.clear();
- }
- ++p_;
- ++column_;
- break;
- default:
- buffer_.push_back(*p_);
- ++p_;
- ++column_;
- break;
- }
- }
- break;
- case filter_states::single_quoted_text:
- {
- switch (*p_)
- {
- case '\r':
- case '\n':
- ++line_;
- column_ = 1;
- state_ = pre_line_break_state_;
- break;
- case '\\':
- buffer_.push_back(*p_);
- if (p_+1 < end_input_)
- {
- ++p_;
- ++column_;
- buffer_.push_back(*p_);
- }
- break;
- case '\'':
- buffer_.push_back('\"');
- //if (buffer_.length() > 0)
- {
- try
- {
- auto val = JsonT::parse(buffer_);
- tokens_.push_back(token<JsonT>(token_types::term,std::make_shared<value_term<JsonT>>(val)));
- }
- catch (const parse_exception& e)
- {
- throw parse_exception(e.code(),line_,column_);
- }
- buffer_.clear();
- }
- state_ = filter_states::expect_path_or_value;
- break;
-
- default:
- buffer_.push_back(*p_);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case filter_states::double_quoted_text:
- {
- switch (*p_)
- {
- case '\r':
- case '\n':
- ++line_;
- column_ = 1;
- state_ = pre_line_break_state_;
- break;
- case '\\':
- buffer_.push_back(*p_);
- if (p_+1 < end_input_)
- {
- ++p_;
- ++column_;
- buffer_.push_back(*p_);
- }
- break;
- case '\"':
- buffer_.push_back(*p_);
- //if (buffer_.length() > 0)
- {
- try
- {
- auto val = JsonT::parse(buffer_);
- tokens_.push_back(token<JsonT>(token_types::term,std::make_shared<value_term<JsonT>>(val)));
- }
- catch (const parse_exception& e)
- {
- throw parse_exception(e.code(),line_,column_);
- }
- buffer_.clear();
- }
- state_ = filter_states::expect_path_or_value;
- break;
-
- default:
- buffer_.push_back(*p_);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case filter_states::expect_path_or_value:
- switch (*p_)
- {
- case '\r':
- case '\n':
- ++line_;
- column_ = 1;
- state_ = pre_line_break_state_;
- break;
- case '<':
- case '>':
- case '!':
- case '=':
- case '&':
- case '|':
- case '+':
- case '-':
- state_ = filter_states::oper;
- // don't increment
- break;
- case '@':
- buffer_.push_back(*p_);
- state_ = filter_states::path;
- ++p_;
- ++column_;
- break;
- case ' ':case '\t':
- ++p_;
- ++column_;
- break;
- case '\'':
- buffer_.push_back('\"');
- state_ = filter_states::single_quoted_text;
- ++p_;
- ++column_;
- break;
- case '\"':
- buffer_.push_back(*p_);
- state_ = filter_states::double_quoted_text;
- ++p_;
- ++column_;
- break;
- case '(':
- ++depth_;
- tokens_.push_back(token<JsonT>(token_types::left_paren));
- ++p_;
- ++column_;
- break;
- case ')':
- tokens_.push_back(token<JsonT>(token_types::right_paren));
- if (--depth_ == 0)
- {
- done = true;
- state_ = filter_states::start;
- }
- ++p_;
- ++column_;
- break;
- default:
- // don't increment
- state_ = filter_states::unquoted_text;
- break;
- };
- break;
- case filter_states::expect_oper_or_right_round_bracket:
- switch (*p_)
- {
- case '\r':
- case '\n':
- ++line_;
- column_ = 1;
- state_ = pre_line_break_state_;
- break;
- case ' ':case '\t':
- break;
- case ')':
- tokens_.push_back(token<JsonT>(token_types::right_paren));
- if (--depth_ == 0)
- {
- done = true;
- state_ = filter_states::start;
- }
- break;
- case '<':
- case '>':
- case '!':
- case '=':
- case '&':
- case '|':
- case '+':
- case '-':
- {
- state_ = filter_states::oper;
- // don't increment p
- }
- break;
- default:
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter, jsonpath_error_category()),line_,column_);
- break;
- };
- break;
- case filter_states::expect_right_round_bracket:
- switch (*p_)
- {
- case '\r':
- case '\n':
- ++line_;
- column_ = 1;
- state_ = pre_line_break_state_;
- break;
- case ' ':case '\t':
- break;
- case ')':
- tokens_.push_back(token<JsonT>(token_types::right_paren));
- if (--depth_ == 0)
- {
- done = true;
- state_ = filter_states::start;
- }
- else
- {
- state_ = filter_states::expect_oper_or_right_round_bracket;
- }
- break;
- default:
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter, jsonpath_error_category()),line_,column_);
- break;
- };
- ++p_;
- ++column_;
- break;
- case filter_states::path:
- switch (*p_)
- {
- case '\r':
- case '\n':
- ++line_;
- column_ = 1;
- state_ = pre_line_break_state_;
- break;
- case '<':
- case '>':
- case '!':
- case '=':
- case '&':
- case '|':
- case '+':
- case '-':
- {
- if (buffer_.length() > 0)
- {
- tokens_.push_back(token<JsonT>(token_types::term,std::make_shared<path_term<JsonT>>(buffer_)));
- buffer_.clear();
- }
- state_ = filter_states::oper;
- // don't increment
- }
- break;
- case ')':
- if (buffer_.length() > 0)
- {
- tokens_.push_back(token<JsonT>(token_types::term,std::make_shared<path_term<JsonT>>(buffer_)));
- tokens_.push_back(token<JsonT>(token_types::right_paren));
- buffer_.clear();
- }
- if (--depth_ == 0)
- {
- state_ = filter_states::start;
- done = true;
- }
- else
- {
- state_ = filter_states::expect_path_or_value;
- }
- ++p_;
- ++column_;
- break;
- default:
- buffer_.push_back(*p_);
- ++p_;
- ++column_;
- break;
- };
- break;
- case filter_states::expect_regex:
- switch (*p_)
- {
- case '\r':
- case '\n':
- ++line_;
- column_ = 1;
- state_ = pre_line_break_state_;
- break;
- case '/':
- state_ = filter_states::regex;
- break;
- case ' ':case '\t':
- break;
- default:
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_expected_slash, jsonpath_error_category()),line_,column_);
- break;
- };
- ++p_;
- ++column_;
- break;
- case filter_states::regex:
- {
- switch (*p_)
- {
- case '\r':
- case '\n':
- ++line_;
- column_ = 1;
- state_ = pre_line_break_state_;
- break;
- case '/':
- //if (buffer_.length() > 0)
- {
- std::regex::flag_type flags = std::regex_constants::ECMAScript;
- if (p_+1 < end_input_ && *(p_+1) == 'i')
- {
- ++p_;
- ++column_;
- flags |= std::regex_constants::icase;
- }
- tokens_.push_back(token<JsonT>(token_types::term,std::make_shared<regex_term<JsonT>>(buffer_,flags)));
- buffer_.clear();
- }
- state_ = filter_states::expect_path_or_value;
- break;
-
- default:
- buffer_.push_back(*p_);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- default:
- ++p_;
- ++column_;
- break;
- }
- }
- if (depth_ != 0)
- {
- throw parse_exception(std::error_code(jsonpath_parser_errc::invalid_filter_unbalanced_paren, jsonpath_error_category()),line_,column_);
- }
- }
-};
-
-
-}}
-#endif \ No newline at end of file