forked from University/epr24pr42-ojanssen2
big bang v2
This commit is contained in:
parent
d48e9d7b28
commit
27589cc385
18 changed files with 2847 additions and 378 deletions
112
Entities/Entity.cpp
Normal file
112
Entities/Entity.cpp
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "../Environment/Maze.h"
|
||||||
|
|
||||||
|
namespace game {
|
||||||
|
Entity::Entity(const Vector2d starting_position, const char display_character): pos(starting_position), display_character(display_character), move_left(true){}
|
||||||
|
|
||||||
|
bool Entity::is_at_position(const Vector2d& position) const {
|
||||||
|
return this->pos.eq(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::tick(const Maze& maze, const Vector2d& player_position){
|
||||||
|
switch (this->display_character) {
|
||||||
|
case 'A':
|
||||||
|
// No thoughts, head empty :P
|
||||||
|
return;
|
||||||
|
case 'B':
|
||||||
|
this->handle_bowie(maze);
|
||||||
|
return;
|
||||||
|
case 'C':
|
||||||
|
this->handle_connelly(maze, player_position);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
cout << "ERR: THIS IS NOT A GHOST!";
|
||||||
|
/// This case will never happen
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::handle_bowie(const Maze& maze) {
|
||||||
|
Vector2d target_position = this->pos;
|
||||||
|
if (this->move_left)
|
||||||
|
target_position.change_x(-1);
|
||||||
|
else
|
||||||
|
target_position.change_x(1);
|
||||||
|
if (maze.is_pos_free(target_position, false))
|
||||||
|
this->pos = target_position;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->move_left = !this->move_left;
|
||||||
|
if (this->move_left)
|
||||||
|
target_position.change_x(-1);
|
||||||
|
else
|
||||||
|
target_position.change_x(1);
|
||||||
|
if (maze.is_pos_free(target_position, false))
|
||||||
|
this->pos = target_position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Entity::connelly_move_up(const Maze& maze) {
|
||||||
|
Vector2d top = this->pos.get_new_updated(0, 1);
|
||||||
|
if (maze.is_pos_free(top, false)) {
|
||||||
|
this->pos = top;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Entity::connelly_move_down(const Maze& maze) {
|
||||||
|
Vector2d bottom = this->pos.get_new_updated(0, -1);
|
||||||
|
if (maze.is_pos_free(bottom, false)) {
|
||||||
|
this-> pos = bottom;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Entity::connelly_move_left(const Maze& maze) {
|
||||||
|
Vector2d left = this->pos.get_new_updated(-1, 0);
|
||||||
|
if (maze.is_pos_free(left, false)) {
|
||||||
|
this->pos = left;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Entity::connelly_move_right(const Maze& maze) {
|
||||||
|
Vector2d right = this->pos.get_new_updated(1, 0);
|
||||||
|
if (maze.is_pos_free(right, false)) {
|
||||||
|
this->pos = right;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::handle_connelly(const Maze& maze, const Vector2d& player_position) {
|
||||||
|
Vector2d diff = maze.get_delta_vector(player_position, this->pos);
|
||||||
|
Vector2d normalized = diff.normalize();
|
||||||
|
|
||||||
|
if ((normalized.y == normalized.x || normalized.y > normalized.x) && normalized.y != 0) {
|
||||||
|
if (diff.y > 0 ) {
|
||||||
|
if (this->connelly_move_up(maze))
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if (this->connelly_move_down(maze))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (normalized.x != 0) {
|
||||||
|
if (diff.x > 0){
|
||||||
|
if (this->connelly_move_right(maze))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bool _ = this->connelly_move_left(maze);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char Entity::get_display_character() const {
|
||||||
|
return this->display_character;
|
||||||
|
}
|
||||||
|
}
|
66
Entities/Entity.h
Normal file
66
Entities/Entity.h
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
#include "../Util/Vector2d.h"
|
||||||
|
|
||||||
|
#ifndef ENTITY_H
|
||||||
|
#define ENTITY_H
|
||||||
|
|
||||||
|
namespace game
|
||||||
|
{
|
||||||
|
class Maze;
|
||||||
|
/// Eine Entität, z.B. ein Geist
|
||||||
|
class Entity {
|
||||||
|
private:
|
||||||
|
/// Die aktuelle Position des Geistes
|
||||||
|
Vector2d pos;
|
||||||
|
/// Wie der Geist dargestellt werden sollte
|
||||||
|
char display_character;
|
||||||
|
/// Ist wahr, wenn der Bowie nach Links läuft, falsch, wenn er nach Rechts läuft.
|
||||||
|
bool move_left;
|
||||||
|
|
||||||
|
/// Behandle Bowie Bewegungen
|
||||||
|
/// @param maze Das Labyrinth
|
||||||
|
void handle_bowie(const Maze& maze);
|
||||||
|
|
||||||
|
/// Behandle Connelly Bewegungen
|
||||||
|
/// @param maze Das Labyrinth
|
||||||
|
/// @param player_position Die Position des Spielers
|
||||||
|
void handle_connelly(const Maze& maze, const Vector2d& player_position);
|
||||||
|
|
||||||
|
/// Versuche den Connelly nach oben zu bewegen
|
||||||
|
/// @param maze Das Labyrinth
|
||||||
|
/// @returns Ob die Bewegung geglückt hat
|
||||||
|
bool connelly_move_up(const Maze& maze);
|
||||||
|
|
||||||
|
/// Versuche den Connelly nach unten zu bewegen
|
||||||
|
/// @param maze Das Labyrinth
|
||||||
|
/// @returns Ob die Bewegung geglückt hat
|
||||||
|
bool connelly_move_down(const Maze& maze);
|
||||||
|
|
||||||
|
/// Versuche den Connelly nach links zu bewegen
|
||||||
|
/// @param maze Das Labyrinth
|
||||||
|
/// @returns Ob die Bewegung geglückt hat
|
||||||
|
bool connelly_move_left(const Maze& maze);
|
||||||
|
|
||||||
|
/// Versuche den Connelly nach Rechts zu bewegen
|
||||||
|
/// @param maze Das Labyrinth
|
||||||
|
/// @returns Ob die Bewegung geglückt hat
|
||||||
|
bool connelly_move_right(const Maze& maze);
|
||||||
|
public:
|
||||||
|
Entity(Vector2d starting_position, char display_character);
|
||||||
|
|
||||||
|
/// Halte den Entität bzw. den Geist up to date, bewege ihn
|
||||||
|
/// @param maze Das Labyrinth
|
||||||
|
/// @param player_position Die Position des Spielers
|
||||||
|
void tick(const Maze& maze, const Vector2d& player_position);
|
||||||
|
|
||||||
|
/// Kontrolliere, ob sich das Entity auf einer Position befindet
|
||||||
|
/// @param position Die Position
|
||||||
|
/// @returns Ob das sich das Entity auf der Position befindet
|
||||||
|
bool is_at_position(const Vector2d& position) const;
|
||||||
|
|
||||||
|
/// Besorge dir das Zeichen, was auf dem Labyrinth angezeigt werden soll
|
||||||
|
/// @returns Das Zeichen
|
||||||
|
char get_display_character() const;
|
||||||
|
};
|
||||||
|
} // game
|
||||||
|
|
||||||
|
#endif //ENTITY_H
|
108
Entities/Player.cpp
Normal file
108
Entities/Player.cpp
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
#include "Player.h"
|
||||||
|
#include "../Environment/Maze.h"
|
||||||
|
#include "../Exceptions/MovementNotPossible.h"
|
||||||
|
#include "../Util/GameState.h"
|
||||||
|
#include "../Environment/Game.h"
|
||||||
|
|
||||||
|
using game::GameState;
|
||||||
|
using game::Game;
|
||||||
|
using game_exceptions::MovementNotPossible;
|
||||||
|
|
||||||
|
namespace game
|
||||||
|
{
|
||||||
|
Player::Player(const int target_x, const int target_y): pos(target_x, target_y), keys_in_inventory(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Player::Player(const Vector2d pos) : pos(pos), keys_in_inventory(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2d Player::get_pos() const
|
||||||
|
{
|
||||||
|
return this->pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::update_position(const Vector2d& target)
|
||||||
|
{
|
||||||
|
this->pos = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maze Player::handle_move(Maze& maze, const Vector2d& move_vector)
|
||||||
|
{
|
||||||
|
const Vector2d target_position = Vector2d(this->get_pos().x + move_vector.x,
|
||||||
|
this->get_pos().y + move_vector.y);
|
||||||
|
|
||||||
|
if (maze.is_pos_free(target_position, this->has_key_available()))
|
||||||
|
{
|
||||||
|
this->update_position(target_position);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw MovementNotPossible("Bewegung nicht moeglich!");
|
||||||
|
return maze;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maze Player::handle_user_input(Maze& maze, const char& input) {
|
||||||
|
Vector2d move_vector = {0, 0};
|
||||||
|
|
||||||
|
switch (input) {
|
||||||
|
case 'w':
|
||||||
|
move_vector = {0, -1};
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
move_vector = {0, 1};
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
move_vector = {-1, 0};
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
move_vector = {1, 0};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->handle_move(maze, move_vector);
|
||||||
|
|
||||||
|
return maze;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::handle_keys(Maze& maze) {
|
||||||
|
switch (maze.get_field(this->pos))
|
||||||
|
{
|
||||||
|
case 'K':
|
||||||
|
++this->keys_in_inventory;
|
||||||
|
maze.update_field(this->get_pos(), '.');
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
--this->keys_in_inventory;
|
||||||
|
maze.update_field(this->get_pos(), '.');
|
||||||
|
break;
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GameState Player::handle_collisions(const Game& game, const Maze& maze) const {
|
||||||
|
char field_at_pos = maze.get_field(this->get_pos());
|
||||||
|
// Game state sanity check
|
||||||
|
if (game.get_state() != GameState::RUNNING)
|
||||||
|
return game.get_state();
|
||||||
|
|
||||||
|
if (field_at_pos == '.'){
|
||||||
|
if (game.is_enemy_at_pos(this->get_pos()))
|
||||||
|
return GameState::HIT_BY_GHOST;
|
||||||
|
return GameState::RUNNING;
|
||||||
|
}
|
||||||
|
// You are not supposed to be here!
|
||||||
|
return game.get_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GameState Player::tick(const Game& game, Maze& maze) {
|
||||||
|
this->handle_keys(maze);
|
||||||
|
return this->handle_collisions(game, maze);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Player::has_key_available() const
|
||||||
|
{
|
||||||
|
return this->keys_in_inventory > 0;
|
||||||
|
}
|
||||||
|
} // game
|
74
Entities/Player.h
Normal file
74
Entities/Player.h
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
#include "../Util/Vector2d.h"
|
||||||
|
#include "../Util/GameState.h"
|
||||||
|
|
||||||
|
#ifndef PLAYER_H
|
||||||
|
#define PLAYER_H
|
||||||
|
|
||||||
|
using game::GameState;
|
||||||
|
|
||||||
|
namespace game
|
||||||
|
{
|
||||||
|
class Maze;
|
||||||
|
class Game;
|
||||||
|
|
||||||
|
/// Ein Spieler.
|
||||||
|
/// Besitzt einen veränderbaren Positionsvektor
|
||||||
|
class Player
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/// Die Position des Spielers
|
||||||
|
Vector2d pos;
|
||||||
|
int keys_in_inventory;
|
||||||
|
|
||||||
|
/// Bewege den Splieler um den Bewegungsvektor, insofern die Zielposition begehbar ist
|
||||||
|
/// @param maze Das Maze
|
||||||
|
/// @param move_vector Die gewollte Bewegung
|
||||||
|
/// @return Die neue Position des Spielers
|
||||||
|
Maze handle_move(Maze& maze, const Vector2d& move_vector);
|
||||||
|
|
||||||
|
/// Gebe oder Nehme dem Spieler Schlüssel
|
||||||
|
/// Updated auch das Maze (Reference!)
|
||||||
|
/// @param maze Das Maze
|
||||||
|
void handle_keys(Maze& maze);
|
||||||
|
|
||||||
|
/// Kontrolliere, ob der Spieler gerade in einem Geist steht
|
||||||
|
/// @param maze Das Maze
|
||||||
|
GameState handle_collisions(const Game& game, const Maze& maze) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Ein Spieler.
|
||||||
|
/// Besitzt einen veränderbaren Positionsvektor
|
||||||
|
/// @param target_x Die Startposition des Spielers (X-Koordinate)
|
||||||
|
/// @param target_y Die Startposition des Spielers (Y-Koordinate)
|
||||||
|
Player(int target_x, int target_y);
|
||||||
|
|
||||||
|
/// Ein Spieler
|
||||||
|
/// @param pos Die Startposition des Spielers
|
||||||
|
explicit Player(Vector2d pos);
|
||||||
|
|
||||||
|
/// Kriege die Position des Spielers
|
||||||
|
/// @return Die Position des Spielers
|
||||||
|
Vector2d get_pos() const;
|
||||||
|
|
||||||
|
/// Aktuallisiere die Position des Spielers ohne weitere Checks
|
||||||
|
/// @param target Das ziel
|
||||||
|
void update_position(const Vector2d& target);
|
||||||
|
|
||||||
|
/// Behandle die eingabe des Nutzers für den Spieler
|
||||||
|
/// @param maze Das Labyrinth
|
||||||
|
/// @param input Die Eingabe des Nutzers
|
||||||
|
Maze handle_user_input(Maze& maze, const char& input);
|
||||||
|
|
||||||
|
/// Halte den Spieler aktuell
|
||||||
|
/// @param game Das Spiel
|
||||||
|
/// @param maze Das Labyrinth
|
||||||
|
/// @returns Der Status des Spiels
|
||||||
|
GameState tick(const Game& game, Maze& maze);
|
||||||
|
|
||||||
|
/// Check, if a player has at least one key
|
||||||
|
/// @return If the player as an available key
|
||||||
|
bool has_key_available() const;
|
||||||
|
};
|
||||||
|
} // maze
|
||||||
|
|
||||||
|
#endif //PLAYER_H
|
108
Environment/Game.cpp
Normal file
108
Environment/Game.cpp
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
#include "Game.h"
|
||||||
|
#include "Maze.h"
|
||||||
|
#include "../Exceptions/MovementNotPossible.h"
|
||||||
|
#include "../Exceptions/UnkownAction.h"
|
||||||
|
#include "../Util/Vector2d.h"
|
||||||
|
|
||||||
|
using game::Player;
|
||||||
|
using game::Maze;
|
||||||
|
using game_exceptions::UnkownAction;
|
||||||
|
using game_exceptions::MovementNotPossible;
|
||||||
|
|
||||||
|
namespace game
|
||||||
|
{
|
||||||
|
Game::Game(Maze& maze) : maze(maze), player(0, 0), enemies({}), state(GameState::RUNNING), infomode_enabled(false)
|
||||||
|
{
|
||||||
|
Vector2d player_start_position = this->maze.get_player_start_position();
|
||||||
|
|
||||||
|
this->player = Player(player_start_position);
|
||||||
|
this->enemies = maze.get_entities();
|
||||||
|
}
|
||||||
|
|
||||||
|
GameState Game::get_state() const {
|
||||||
|
return this->state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::handle_user_input(const char& input)
|
||||||
|
{
|
||||||
|
switch (input)
|
||||||
|
{
|
||||||
|
case 'w':
|
||||||
|
case 'a':
|
||||||
|
case 's':
|
||||||
|
case 'd':
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
this->infomode_enabled = !this->infomode_enabled;
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
this->state = GameState::QUITTING;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
cout <<
|
||||||
|
"Du wurdest von einem Zauberer in ein Labyrinth gesperrt, nachdem du seine Künste beleidigt hast.\n"
|
||||||
|
<< "Er laesst dich leben, wenn du es schaffst den Ausgang (Z) zu finden. Solltest du keinen Erfolg haben, laesst er dich verhungern.\n"
|
||||||
|
<< "Auf deinem Abenteuer wirst du dabei boesen Geistern (A) begegnen und mit Schluesseln (K) Tueren (T) aufschliessen.\n"
|
||||||
|
<< "Bewege dich mit 'w', 'a', 's' und 'd'.\n";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw UnkownAction("Diese Eingabe kenne ich nicht. Gib 'h' ein, um eine Hilfe zu erhalten.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Game::is_enemy_at_pos(const Vector2d& position) const {
|
||||||
|
for (Entity e : this->enemies)
|
||||||
|
if (e.is_at_position(position))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Game::should_end_game() const
|
||||||
|
{
|
||||||
|
return this->state != GameState::RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::run_game()
|
||||||
|
{
|
||||||
|
char game_input;
|
||||||
|
|
||||||
|
// Hauptschleife
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
this->maze.render(this->player, this->enemies, this->infomode_enabled);
|
||||||
|
|
||||||
|
if (this->maze.is_player_at_goal(this->player))
|
||||||
|
{
|
||||||
|
cout << "Ziel erreicht! Herzlichen Glueckwunsch!\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cin >> game_input;
|
||||||
|
|
||||||
|
if (!cin)
|
||||||
|
this->state = GameState::QUITTING;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this->handle_user_input(game_input);
|
||||||
|
this->player.handle_user_input(this->maze, game_input);
|
||||||
|
} catch (UnkownAction& err)
|
||||||
|
{
|
||||||
|
cout << err.what() << "\n";
|
||||||
|
} catch (MovementNotPossible& err)
|
||||||
|
{
|
||||||
|
cout << err.what() << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
this->state = this->player.tick(*this, this->maze);
|
||||||
|
|
||||||
|
for (Entity& e : this->enemies)
|
||||||
|
e.tick(this->maze, this->player.get_pos());
|
||||||
|
|
||||||
|
this->state = this->player.tick(*this, this->maze);
|
||||||
|
|
||||||
|
if (this->should_end_game())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // game
|
54
Environment/Game.h
Normal file
54
Environment/Game.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#include "Maze.h"
|
||||||
|
#include "../Entities/Player.h"
|
||||||
|
#include "../Util/GameState.h"
|
||||||
|
#include "../Entities/Entity.h"
|
||||||
|
|
||||||
|
#ifndef GAME_H
|
||||||
|
#define GAME_H
|
||||||
|
|
||||||
|
namespace game
|
||||||
|
{
|
||||||
|
/// Eine Instanz des Spiels
|
||||||
|
class Game
|
||||||
|
{
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Das Labyrinth
|
||||||
|
Maze maze;
|
||||||
|
/// Der Spieler
|
||||||
|
Player player;
|
||||||
|
/// Die Gegner des Spieles
|
||||||
|
vector<Entity> enemies;
|
||||||
|
/// Der Status des Spiels
|
||||||
|
GameState state;
|
||||||
|
///
|
||||||
|
bool infomode_enabled;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Game(Maze& maze);
|
||||||
|
|
||||||
|
/// Bearbeite die Eingabe des Spielers
|
||||||
|
/// @param input Die Eingabe des Nutzers
|
||||||
|
/// @return Der Bewegungsvektor, um den sich den Spieler bewegen möchte
|
||||||
|
/// @throws UnkownAction Wenn die Eingabe des Spielers unbekannt ist
|
||||||
|
void handle_user_input(const char& input);
|
||||||
|
|
||||||
|
/// Kontrolliere, ob das Spiel beendet werden sollte
|
||||||
|
bool should_end_game() const;
|
||||||
|
|
||||||
|
/// Starte das Spiel
|
||||||
|
void run_game();
|
||||||
|
|
||||||
|
/// Kriege den aktuellen Status des Spiels
|
||||||
|
/// @returns Den aktuellen Status
|
||||||
|
GameState get_state() const;
|
||||||
|
|
||||||
|
/// Krontroliere ob ein Geist sich an einer Position befindet
|
||||||
|
/// @param position Die Position
|
||||||
|
/// @returns Ob sich dort ein Geist aufhält
|
||||||
|
bool is_enemy_at_pos(const Vector2d& position) const ;
|
||||||
|
};
|
||||||
|
} // game
|
||||||
|
|
||||||
|
#endif //GAME_H
|
162
Environment/Maze.cpp
Normal file
162
Environment/Maze.cpp
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
#include "Maze.h"
|
||||||
|
#include "../Entities/Entity.h"
|
||||||
|
#include "../Entities/Player.h"
|
||||||
|
#include "../Exceptions/MalformedMaze.h"
|
||||||
|
|
||||||
|
using game_exceptions::MalformedMaze;
|
||||||
|
namespace game {
|
||||||
|
/// Ist eine Konstante, darf also in global scope
|
||||||
|
static const vector<char> valid_maze_elements = {'Z', '.', '#', 'A', 'K', 'T', 'B', 'C'};
|
||||||
|
/// Welche Geistertypen es gibt
|
||||||
|
static const vector<char> valid_enemies = {'A', 'B', 'C'};
|
||||||
|
/// Die Maximale Labyrinthgröße
|
||||||
|
static constexpr int MAX_MAZE_SIZE = 20;
|
||||||
|
|
||||||
|
Maze::Maze(const vector<vector<char>> &play_field, const vector<int> &player_start_position,
|
||||||
|
const vector<Entity> &enemies) :
|
||||||
|
field(play_field), player_start_position(Vector2d{player_start_position[1], player_start_position[0]}),
|
||||||
|
enemies(enemies) {
|
||||||
|
if (!this->is_pos_free(this->player_start_position, false))
|
||||||
|
throw MalformedMaze("Player oob");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Maze::was_player_killed_by_ghost(const Player &player) const {
|
||||||
|
return this->field[player.get_pos().y][player.get_pos().x] == 'A';
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Maze::is_player_at_goal(const Player &player) const {
|
||||||
|
return this->field[player.get_pos().y][player.get_pos().x] == 'Z';
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Maze::is_pos_free(const Vector2d &pos, const bool &player_has_key) const {
|
||||||
|
if (pos.x < 0 || pos.y < 0 || pos.y > field.size() - 1 || pos.x > field[pos.y].size() - 1)
|
||||||
|
return false;
|
||||||
|
if (field[pos.y][pos.x] == '#')
|
||||||
|
return false;
|
||||||
|
if (field[pos.y][pos.x] == 'T')
|
||||||
|
return player_has_key;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Maze::render(const Player &player, const vector<Entity> &entities, const bool &infomode_enabled) {
|
||||||
|
for (int y = 0; y < field.size(); ++y) {
|
||||||
|
for (int x = 0; x < field[y].size(); ++x) {
|
||||||
|
if (y == player.get_pos().y && x == player.get_pos().x)
|
||||||
|
cout << "S";
|
||||||
|
else {
|
||||||
|
bool an_enemy_is_at_this_position = false;
|
||||||
|
for (Entity e: entities)
|
||||||
|
if (e.is_at_position({x, y})) {
|
||||||
|
an_enemy_is_at_this_position = true;
|
||||||
|
cout << e.get_display_character();
|
||||||
|
}
|
||||||
|
if (!an_enemy_is_at_this_position)
|
||||||
|
cout << field[y][x];
|
||||||
|
}
|
||||||
|
cout << " ";
|
||||||
|
}
|
||||||
|
if (y == 0 && infomode_enabled) {
|
||||||
|
const int steps = this->calculate_steps_until_win(player.get_pos(), 5);
|
||||||
|
if (steps < 999)
|
||||||
|
cout << steps << " Schritte bis zum Ziel";
|
||||||
|
}
|
||||||
|
cout << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char Maze::get_field(const Vector2d &pos) const { return this->field[pos.y][pos.x]; }
|
||||||
|
|
||||||
|
void Maze::update_field(const Vector2d &pos, const char &target) { this->field[pos.y][pos.x] = target; }
|
||||||
|
|
||||||
|
Vector2d Maze::get_player_start_position() const { return this->player_start_position; }
|
||||||
|
|
||||||
|
Vector2d Maze::get_delta_vector(const Vector2d &pos1, const Vector2d &pos2) const {
|
||||||
|
int x_diff = pos1.x - pos2.x;
|
||||||
|
int y_diff = pos1.y - pos2.y;
|
||||||
|
|
||||||
|
return {x_diff, y_diff};
|
||||||
|
}
|
||||||
|
|
||||||
|
int Maze::calculate_steps_until_win(Vector2d position, const int &steps) {
|
||||||
|
if (!this->is_pos_free(position, false))
|
||||||
|
return 999;
|
||||||
|
if (this->get_field(position) == 'Z')
|
||||||
|
return 0;
|
||||||
|
if (steps <= 0)
|
||||||
|
return 999;
|
||||||
|
|
||||||
|
return 1 + std::min({this->calculate_steps_until_win(position.get_new_updated(0, -1), steps - 1),
|
||||||
|
this->calculate_steps_until_win(position.get_new_updated(0, 1), steps - 1),
|
||||||
|
this->calculate_steps_until_win(position.get_new_updated(1, 0), steps - 1),
|
||||||
|
this->calculate_steps_until_win(position.get_new_updated(-1, 0), steps - 1)});
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<Entity> Maze::get_entities() { return this->enemies; }
|
||||||
|
|
||||||
|
vector<int> Maze::request_numbers_from_user(const int &amount_of_numbers) {
|
||||||
|
int input;
|
||||||
|
vector<int> list;
|
||||||
|
|
||||||
|
for (int i = 0; i < amount_of_numbers; ++i) {
|
||||||
|
cin >> input;
|
||||||
|
if (!cin)
|
||||||
|
throw MalformedMaze("Cin failed while reading numbers!");
|
||||||
|
|
||||||
|
if (input > MAX_MAZE_SIZE)
|
||||||
|
throw MalformedMaze("This maze is too big");
|
||||||
|
list.push_back(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Maze::validate_maze_element(const char &target) {
|
||||||
|
for (const char c: valid_maze_elements)
|
||||||
|
if (c == target)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Maze::is_valid_enemy(const char &target) {
|
||||||
|
for (const char c: valid_enemies)
|
||||||
|
if (c == target)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maze Maze::request_maze_from_user() {
|
||||||
|
vector<int> maze_size = request_numbers_from_user(2);
|
||||||
|
|
||||||
|
char input;
|
||||||
|
vector<vector<char>> field;
|
||||||
|
vector<Entity> enemies;
|
||||||
|
|
||||||
|
for (int y = 0; y < maze_size[0]; ++y) {
|
||||||
|
vector<char> row;
|
||||||
|
for (int x = 0; x < maze_size[1]; ++x) {
|
||||||
|
cin >> input;
|
||||||
|
if (!cin)
|
||||||
|
throw MalformedMaze("Cin failed while reading chars!");
|
||||||
|
|
||||||
|
// I don't think that this is needed. I doubt that they test the check for this one ~Eric
|
||||||
|
// if (input == 'q')
|
||||||
|
// throw ExitGame("Schoenen Tag noch!");
|
||||||
|
|
||||||
|
if (!validate_maze_element(input))
|
||||||
|
throw MalformedMaze("The given input is not a valid element of a maze!");
|
||||||
|
if (is_valid_enemy(input)) {
|
||||||
|
enemies.push_back(Entity({x, y}, input));
|
||||||
|
row.push_back('.');
|
||||||
|
} else {
|
||||||
|
row.push_back(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
field.push_back(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<int> player_start_pos = request_numbers_from_user(2);
|
||||||
|
|
||||||
|
return {field, player_start_pos, enemies};
|
||||||
|
} // Beispieleingabe: `4 3 #.# #.K #T# #Z# 0 1`
|
||||||
|
} // namespace game
|
113
Environment/Maze.h
Normal file
113
Environment/Maze.h
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
#ifndef MAZE_H
|
||||||
|
#define MAZE_H
|
||||||
|
|
||||||
|
#include "../Util/Vector2d.h"
|
||||||
|
#include "../std_lib_inc.h"
|
||||||
|
|
||||||
|
namespace game {
|
||||||
|
class Player;
|
||||||
|
class Entity;
|
||||||
|
/// Ist eine Konstante, darf also in global scope
|
||||||
|
|
||||||
|
/// Ein Labyrinth.
|
||||||
|
/// Besitzt ein Feld
|
||||||
|
class Maze {
|
||||||
|
// class -> members private by default
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Das Spielfeld
|
||||||
|
vector<vector<char>> field;
|
||||||
|
/// Die Startposition des Spielers
|
||||||
|
Vector2d player_start_position;
|
||||||
|
/// Eine Liste an Gegnern
|
||||||
|
vector<Entity> enemies;
|
||||||
|
/// Erlaubte Zeichen in einem Labyrinth
|
||||||
|
/* Legende
|
||||||
|
* S - Spieler
|
||||||
|
* Z - Ziel
|
||||||
|
* . - Leerer Raum (begehbar)
|
||||||
|
* # - Wand
|
||||||
|
* A - Animaltronic
|
||||||
|
* K - Schlüssel
|
||||||
|
* T - Tür
|
||||||
|
* B - Bowie
|
||||||
|
* C - Connellys
|
||||||
|
*/
|
||||||
|
public:
|
||||||
|
/// Das Spielfeld
|
||||||
|
Maze(const Vector<Vector<char>> &play_field, const Vector<int> &player_start_position,
|
||||||
|
const Vector<Entity> &enemies);
|
||||||
|
/// Kontrolliere, ob der Spieler stirbt
|
||||||
|
/// @param player Der Spieler
|
||||||
|
/// @return Ob der Spieler tot ist
|
||||||
|
bool was_player_killed_by_ghost(const Player &player) const;
|
||||||
|
|
||||||
|
/// Kontrolliere, ob der Spieler am Ziel ist
|
||||||
|
/// @param player Der Spieler
|
||||||
|
/// @return Ob der Spieler am Ziel ist
|
||||||
|
bool is_player_at_goal(const Player &player) const;
|
||||||
|
|
||||||
|
/// Kontrolliere, ob eine bestimmte Position begehbar ist
|
||||||
|
/// @param pos Die Position, die überprüft werden soll
|
||||||
|
/// @param player_has_key If the player has at least one key
|
||||||
|
/// @return Ob die Position begehbar ist
|
||||||
|
bool is_pos_free(const Vector2d &pos, const bool &player_has_key) const;
|
||||||
|
|
||||||
|
/// Zeige das Spielfeld in der Konsole an
|
||||||
|
/// @param player Der Spieler
|
||||||
|
/// @param entities Die Entities auf dem Spielfeld
|
||||||
|
/// @param infomode_enabled Ob der Infomode aktiv ist
|
||||||
|
void render(const Player &player, const vector<Entity> &entities, const bool &infomode_enabled);
|
||||||
|
|
||||||
|
/// Kriege den Wert einer Position
|
||||||
|
/// @param pos Die gewollte Position
|
||||||
|
/// @return Der Wert der Position
|
||||||
|
char get_field(const Vector2d &pos) const;
|
||||||
|
|
||||||
|
/// Ersetze den Wert von einer Position
|
||||||
|
/// @param pos Die Position die ersetzt werden soll
|
||||||
|
/// @param target Der Wert, auf den die Position gesetzt werden soll
|
||||||
|
void update_field(const Vector2d &pos, const char &target);
|
||||||
|
|
||||||
|
/// Kriege die Startposition des Spielers
|
||||||
|
/// @return Die Startposition des Spielers
|
||||||
|
Vector2d get_player_start_position() const;
|
||||||
|
|
||||||
|
/// Berrechne den Abstand zwischen zwei Vektoren
|
||||||
|
/// @return Der Abstand als Differenzvektor
|
||||||
|
Vector2d get_delta_vector(const Vector2d &pos1, const Vector2d &pos2) const;
|
||||||
|
|
||||||
|
/// Berechne wie viele Schritte benötigt werden, um das Labyrinth zu schaffen
|
||||||
|
/// @warning Steps nicht zu groß setzen! Diese Funktion ist 4-fach rekursiv!
|
||||||
|
/// @param position Die Startposition
|
||||||
|
/// @param steps Wie viele Schritte maximal gegangen werden sollten
|
||||||
|
/// @returns Wie viele Schritte benötigt werden
|
||||||
|
int calculate_steps_until_win(Vector2d position, const int &steps);
|
||||||
|
|
||||||
|
/// Kriege alle eingelesenen Entities
|
||||||
|
vector<Entity> get_entities();
|
||||||
|
|
||||||
|
/// Lese ein Labyrinth aus der Konsole
|
||||||
|
/// @return Das Labyrinth
|
||||||
|
/// @throws runtime_exception Falls die Eingabe nicht korrekt verlaufen ist.
|
||||||
|
static Maze request_maze_from_user();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Lese eine bestimmte Anzahl an Nummern aus der Konsole
|
||||||
|
/// @param amount_of_numbers Wie viele Nummern eingelesen werden sollen
|
||||||
|
/// @return Die eingelesenen Nummern
|
||||||
|
static vector<int> request_numbers_from_user(const int &amount_of_numbers);
|
||||||
|
|
||||||
|
/// Kontrolliere, ob ein Zeichen im Labyrinth vorkommen darf
|
||||||
|
/// @param target Das Zeichen, welches Kontrolliert werden soll
|
||||||
|
/// @return Ob das gegebene Zeichen in einem Labyrinth vorkommen darf
|
||||||
|
static bool validate_maze_element(const char &target);
|
||||||
|
|
||||||
|
/// Ob der angegebene char in valider Geist ist
|
||||||
|
/// @param target Der zu kontrollierende Wert
|
||||||
|
/// @returns Ob der Wert ein Valider Geist ist
|
||||||
|
static bool is_valid_enemy(const char &target);
|
||||||
|
};
|
||||||
|
} // namespace game
|
||||||
|
|
||||||
|
#endif // MAZE_H
|
23
Exceptions/MalformedMaze.h
Normal file
23
Exceptions/MalformedMaze.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#include "../std_lib_inc.h"
|
||||||
|
#ifndef MALFORMEDMAZE_H
|
||||||
|
#define MALFORMEDMAZE_H
|
||||||
|
|
||||||
|
namespace game_exceptions
|
||||||
|
{
|
||||||
|
class MalformedMaze
|
||||||
|
{
|
||||||
|
string why;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MalformedMaze(string why): why(why)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
string what()
|
||||||
|
{
|
||||||
|
return this->why;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // game_exceptions
|
||||||
|
|
||||||
|
#endif //MALFORMEDMAZE_H
|
23
Exceptions/MovementNotPossible.h
Normal file
23
Exceptions/MovementNotPossible.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#include "../std_lib_inc.h"
|
||||||
|
#ifndef MOVEMENTNOTPOSSIBLE_H
|
||||||
|
#define MOVEMENTNOTPOSSIBLE_H
|
||||||
|
|
||||||
|
namespace game_exceptions
|
||||||
|
{
|
||||||
|
class MovementNotPossible
|
||||||
|
{
|
||||||
|
string why;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MovementNotPossible(string why): why(why)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
string what()
|
||||||
|
{
|
||||||
|
return this->why;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // game_exceptions
|
||||||
|
|
||||||
|
#endif //MOVEMENTNOTPOSSIBLE_H
|
23
Exceptions/UnkownAction.h
Normal file
23
Exceptions/UnkownAction.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#include "../std_lib_inc.h"
|
||||||
|
#ifndef UNKOWNACTION_H
|
||||||
|
#define UNKOWNACTION_H
|
||||||
|
|
||||||
|
namespace game_exceptions
|
||||||
|
{
|
||||||
|
class UnkownAction
|
||||||
|
{
|
||||||
|
string why;
|
||||||
|
|
||||||
|
public:
|
||||||
|
UnkownAction(string why): why(why)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
string what()
|
||||||
|
{
|
||||||
|
return this->why;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // game_exceptions
|
||||||
|
|
||||||
|
#endif //UNKOWNACTION_H
|
15
Util/GameState.h
Normal file
15
Util/GameState.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef GAMESTATE_H
|
||||||
|
#define GAMESTATE_H
|
||||||
|
|
||||||
|
namespace game
|
||||||
|
{
|
||||||
|
/// Beschreibt den aktuellen GameState
|
||||||
|
enum class GameState
|
||||||
|
{
|
||||||
|
RUNNING,
|
||||||
|
HIT_BY_GHOST,
|
||||||
|
QUITTING,
|
||||||
|
};
|
||||||
|
} // game
|
||||||
|
|
||||||
|
#endif //GAMESTATE_H
|
47
Util/Vector2d.cpp
Normal file
47
Util/Vector2d.cpp
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#include "Vector2d.h"
|
||||||
|
|
||||||
|
namespace game
|
||||||
|
{
|
||||||
|
Vector2d::Vector2d(const int x, const int y)
|
||||||
|
{
|
||||||
|
this->x = x;
|
||||||
|
this->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vector2d::update(const int& x, const int& y)
|
||||||
|
{
|
||||||
|
this->x = x;
|
||||||
|
this->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vector2d::change_x(const int& amount) {
|
||||||
|
this->x += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vector2d::change_y(const int& amount) {
|
||||||
|
this->y += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2d Vector2d::normalize() {
|
||||||
|
Vector2d v = *this;
|
||||||
|
if (v.x < 0)
|
||||||
|
v.x *= -1;
|
||||||
|
if (v.y < 0)
|
||||||
|
v.y *= -1;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Vector2d::eq(const Vector2d& position) const {
|
||||||
|
return this->x == position.x && this->y == position.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Vector2d Vector2d::get_new_updated(const int& diff_x, const int& diff_y) const {
|
||||||
|
Vector2d new_position = *this;
|
||||||
|
new_position.change_x(diff_x);
|
||||||
|
new_position.change_y(diff_y);
|
||||||
|
|
||||||
|
return new_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // game
|
51
Util/Vector2d.h
Normal file
51
Util/Vector2d.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#ifndef POSITION_H
|
||||||
|
#define POSITION_H
|
||||||
|
|
||||||
|
namespace game
|
||||||
|
{
|
||||||
|
/// Ein Vector aus zwei zahlen.
|
||||||
|
/// Kann eine Position oder eine Differenz zwischen zwei Positionen darstellen.
|
||||||
|
struct Vector2d
|
||||||
|
{
|
||||||
|
// struct -> members public by default
|
||||||
|
// Die beiden Variablen des Vectors
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
|
||||||
|
/// Ein Vector aus zwei zahlen.
|
||||||
|
/// Kann eine Position oder eine Differenz zwischen zwei Positionen darstellen.
|
||||||
|
/// @param x Die 'X'-Koordinate
|
||||||
|
/// @param y Die 'Y'-Koordinate
|
||||||
|
Vector2d(int x, int y);
|
||||||
|
|
||||||
|
/// Aktualisiere die Werte des Vectors
|
||||||
|
/// @param x Die neue 'X'-Koordinate
|
||||||
|
/// @param y Die neue 'Y'-Koordinate
|
||||||
|
void update(const int& x, const int& y);
|
||||||
|
|
||||||
|
/// Verschiebe den X Wert des Vektors um eine Anzahl
|
||||||
|
/// @param amount Die zu verschiebene Anzahl
|
||||||
|
void change_x(const int& amount);
|
||||||
|
|
||||||
|
/// Verschiebe den Y Wert des Vektors um eine Anzhal
|
||||||
|
/// @param amount Die zu verschiebene Anzahl
|
||||||
|
void change_y(const int& amount);
|
||||||
|
|
||||||
|
/// Kriege einen normalisierten Vektor zurück
|
||||||
|
/// @returns Den aktuellen Vektor als normalisierter Vektor
|
||||||
|
Vector2d normalize();
|
||||||
|
|
||||||
|
/// Kontrolliere, ob ein Vektor einem anderen Enspricht
|
||||||
|
/// @param position Die Position mit der verglichen werden soll
|
||||||
|
/// @returns Ob die Position die gleiche ist
|
||||||
|
bool eq(const Vector2d& position) const;
|
||||||
|
|
||||||
|
/// Kriege einen Vektor, der mit den gegebenen Werten verschoben worden ist
|
||||||
|
/// @param diff_x Die Verschiebung auf der X-Achse
|
||||||
|
/// @param diff_y Die Verschiebung auf der Y-Achse
|
||||||
|
/// @returns Den berrechneten Vektor
|
||||||
|
Vector2d get_new_updated(const int& diff_x, const int& diff_y) const;
|
||||||
|
};
|
||||||
|
} // game
|
||||||
|
|
||||||
|
#endif //POSITION_H
|
|
@ -0,0 +1,904 @@
|
||||||
|
#ifdef __cplusplus
|
||||||
|
# error "A C++ compiler has been selected for C."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__18CXX)
|
||||||
|
# define ID_VOID_MAIN
|
||||||
|
#endif
|
||||||
|
#if defined(__CLASSIC_C__)
|
||||||
|
/* cv-qualifiers did not exist in K&R C */
|
||||||
|
# define const
|
||||||
|
# define volatile
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__has_include)
|
||||||
|
/* If the compiler does not have __has_include, pretend the answer is
|
||||||
|
always no. */
|
||||||
|
# define __has_include(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Version number components: V=Version, R=Revision, P=Patch
|
||||||
|
Version date components: YYYY=Year, MM=Month, DD=Day */
|
||||||
|
|
||||||
|
#if defined(__INTEL_COMPILER) || defined(__ICC)
|
||||||
|
# define COMPILER_ID "Intel"
|
||||||
|
# if defined(_MSC_VER)
|
||||||
|
# define SIMULATE_ID "MSVC"
|
||||||
|
# endif
|
||||||
|
# if defined(__GNUC__)
|
||||||
|
# define SIMULATE_ID "GNU"
|
||||||
|
# endif
|
||||||
|
/* __INTEL_COMPILER = VRP prior to 2021, and then VVVV for 2021 and later,
|
||||||
|
except that a few beta releases use the old format with V=2021. */
|
||||||
|
# if __INTEL_COMPILER < 2021 || __INTEL_COMPILER == 202110 || __INTEL_COMPILER == 202111
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
|
||||||
|
# if defined(__INTEL_COMPILER_UPDATE)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE)
|
||||||
|
# else
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER_UPDATE)
|
||||||
|
/* The third version component from --version is an update index,
|
||||||
|
but no macro is provided for it. */
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(0)
|
||||||
|
# endif
|
||||||
|
# if defined(__INTEL_COMPILER_BUILD_DATE)
|
||||||
|
/* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
|
||||||
|
# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
|
||||||
|
# endif
|
||||||
|
# if defined(_MSC_VER)
|
||||||
|
/* _MSC_VER = VVRR */
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
|
||||||
|
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
|
||||||
|
# endif
|
||||||
|
# if defined(__GNUC__)
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
|
||||||
|
# elif defined(__GNUG__)
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
|
||||||
|
# endif
|
||||||
|
# if defined(__GNUC_MINOR__)
|
||||||
|
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
|
||||||
|
# endif
|
||||||
|
# if defined(__GNUC_PATCHLEVEL__)
|
||||||
|
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif (defined(__clang__) && defined(__INTEL_CLANG_COMPILER)) || defined(__INTEL_LLVM_COMPILER)
|
||||||
|
# define COMPILER_ID "IntelLLVM"
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# define SIMULATE_ID "MSVC"
|
||||||
|
#endif
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
# define SIMULATE_ID "GNU"
|
||||||
|
#endif
|
||||||
|
/* __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and
|
||||||
|
* later. Look for 6 digit vs. 8 digit version number to decide encoding.
|
||||||
|
* VVVV is no smaller than the current year when a version is released.
|
||||||
|
*/
|
||||||
|
#if __INTEL_LLVM_COMPILER < 1000000L
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/10 % 10)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 10)
|
||||||
|
#else
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/10000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/100 % 100)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 100)
|
||||||
|
#endif
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
/* _MSC_VER = VVRR */
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
|
||||||
|
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
|
||||||
|
#endif
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
|
||||||
|
#elif defined(__GNUG__)
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
|
||||||
|
#endif
|
||||||
|
#if defined(__GNUC_MINOR__)
|
||||||
|
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
|
||||||
|
#endif
|
||||||
|
#if defined(__GNUC_PATCHLEVEL__)
|
||||||
|
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(__PATHCC__)
|
||||||
|
# define COMPILER_ID "PathScale"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
|
||||||
|
# if defined(__PATHCC_PATCHLEVEL__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
|
||||||
|
# define COMPILER_ID "Embarcadero"
|
||||||
|
# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
|
||||||
|
# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF)
|
||||||
|
|
||||||
|
#elif defined(__BORLANDC__)
|
||||||
|
# define COMPILER_ID "Borland"
|
||||||
|
/* __BORLANDC__ = 0xVRR */
|
||||||
|
# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
|
||||||
|
# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
|
||||||
|
|
||||||
|
#elif defined(__WATCOMC__) && __WATCOMC__ < 1200
|
||||||
|
# define COMPILER_ID "Watcom"
|
||||||
|
/* __WATCOMC__ = VVRR */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
|
||||||
|
# if (__WATCOMC__ % 10) > 0
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__WATCOMC__)
|
||||||
|
# define COMPILER_ID "OpenWatcom"
|
||||||
|
/* __WATCOMC__ = VVRP + 1100 */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
|
||||||
|
# if (__WATCOMC__ % 10) > 0
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__SUNPRO_C)
|
||||||
|
# define COMPILER_ID "SunPro"
|
||||||
|
# if __SUNPRO_C >= 0x5100
|
||||||
|
/* __SUNPRO_C = 0xVRRP */
|
||||||
|
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>12)
|
||||||
|
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xFF)
|
||||||
|
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF)
|
||||||
|
# else
|
||||||
|
/* __SUNPRO_CC = 0xVRP */
|
||||||
|
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>8)
|
||||||
|
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xF)
|
||||||
|
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__HP_cc)
|
||||||
|
# define COMPILER_ID "HP"
|
||||||
|
/* __HP_cc = VVRRPP */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__HP_cc/10000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__HP_cc/100 % 100)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__HP_cc % 100)
|
||||||
|
|
||||||
|
#elif defined(__DECC)
|
||||||
|
# define COMPILER_ID "Compaq"
|
||||||
|
/* __DECC_VER = VVRRTPPPP */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__DECC_VER/10000000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__DECC_VER/100000 % 100)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__DECC_VER % 10000)
|
||||||
|
|
||||||
|
#elif defined(__IBMC__) && defined(__COMPILER_VER__)
|
||||||
|
# define COMPILER_ID "zOS"
|
||||||
|
/* __IBMC__ = VRP */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
|
||||||
|
|
||||||
|
#elif defined(__open_xl__) && defined(__clang__)
|
||||||
|
# define COMPILER_ID "IBMClang"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__open_xl_version__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__open_xl_release__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__open_xl_modification__)
|
||||||
|
# define COMPILER_VERSION_TWEAK DEC(__open_xl_ptf_fix_level__)
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(__ibmxl__) && defined(__clang__)
|
||||||
|
# define COMPILER_ID "XLClang"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__)
|
||||||
|
# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__)
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ >= 800
|
||||||
|
# define COMPILER_ID "XL"
|
||||||
|
/* __IBMC__ = VRP */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
|
||||||
|
|
||||||
|
#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ < 800
|
||||||
|
# define COMPILER_ID "VisualAge"
|
||||||
|
/* __IBMC__ = VRP */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
|
||||||
|
|
||||||
|
#elif defined(__NVCOMPILER)
|
||||||
|
# define COMPILER_ID "NVHPC"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__NVCOMPILER_MAJOR__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__NVCOMPILER_MINOR__)
|
||||||
|
# if defined(__NVCOMPILER_PATCHLEVEL__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__NVCOMPILER_PATCHLEVEL__)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__PGI)
|
||||||
|
# define COMPILER_ID "PGI"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
|
||||||
|
# if defined(__PGIC_PATCHLEVEL__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__clang__) && defined(__cray__)
|
||||||
|
# define COMPILER_ID "CrayClang"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__cray_major__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__cray_minor__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__cray_patchlevel__)
|
||||||
|
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(_CRAYC)
|
||||||
|
# define COMPILER_ID "Cray"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
|
||||||
|
|
||||||
|
#elif defined(__TI_COMPILER_VERSION__)
|
||||||
|
# define COMPILER_ID "TI"
|
||||||
|
/* __TI_COMPILER_VERSION__ = VVVRRRPPP */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
|
||||||
|
|
||||||
|
#elif defined(__CLANG_FUJITSU)
|
||||||
|
# define COMPILER_ID "FujitsuClang"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
|
||||||
|
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(__FUJITSU)
|
||||||
|
# define COMPILER_ID "Fujitsu"
|
||||||
|
# if defined(__FCC_version__)
|
||||||
|
# define COMPILER_VERSION __FCC_version__
|
||||||
|
# elif defined(__FCC_major__)
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
|
||||||
|
# endif
|
||||||
|
# if defined(__fcc_version)
|
||||||
|
# define COMPILER_VERSION_INTERNAL DEC(__fcc_version)
|
||||||
|
# elif defined(__FCC_VERSION)
|
||||||
|
# define COMPILER_VERSION_INTERNAL DEC(__FCC_VERSION)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(__ghs__)
|
||||||
|
# define COMPILER_ID "GHS"
|
||||||
|
/* __GHS_VERSION_NUMBER = VVVVRP */
|
||||||
|
# ifdef __GHS_VERSION_NUMBER
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__TASKING__)
|
||||||
|
# define COMPILER_ID "Tasking"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__VERSION__/1000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__VERSION__ % 100)
|
||||||
|
# define COMPILER_VERSION_INTERNAL DEC(__VERSION__)
|
||||||
|
|
||||||
|
#elif defined(__ORANGEC__)
|
||||||
|
# define COMPILER_ID "OrangeC"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__ORANGEC_MAJOR__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__ORANGEC_MINOR__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__ORANGEC_PATCHLEVEL__)
|
||||||
|
|
||||||
|
#elif defined(__TINYC__)
|
||||||
|
# define COMPILER_ID "TinyCC"
|
||||||
|
|
||||||
|
#elif defined(__BCC__)
|
||||||
|
# define COMPILER_ID "Bruce"
|
||||||
|
|
||||||
|
#elif defined(__SCO_VERSION__)
|
||||||
|
# define COMPILER_ID "SCO"
|
||||||
|
|
||||||
|
#elif defined(__ARMCC_VERSION) && !defined(__clang__)
|
||||||
|
# define COMPILER_ID "ARMCC"
|
||||||
|
#if __ARMCC_VERSION >= 1000000
|
||||||
|
/* __ARMCC_VERSION = VRRPPPP */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
|
||||||
|
#else
|
||||||
|
/* __ARMCC_VERSION = VRPPPP */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(__clang__) && defined(__apple_build_version__)
|
||||||
|
# define COMPILER_ID "AppleClang"
|
||||||
|
# if defined(_MSC_VER)
|
||||||
|
# define SIMULATE_ID "MSVC"
|
||||||
|
# endif
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
|
||||||
|
# if defined(_MSC_VER)
|
||||||
|
/* _MSC_VER = VVRR */
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
|
||||||
|
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
|
||||||
|
# endif
|
||||||
|
# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__)
|
||||||
|
|
||||||
|
#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION)
|
||||||
|
# define COMPILER_ID "ARMClang"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION/100 % 100)
|
||||||
|
# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION)
|
||||||
|
|
||||||
|
#elif defined(__clang__) && defined(__ti__)
|
||||||
|
# define COMPILER_ID "TIClang"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__ti_major__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__ti_minor__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__ti_patchlevel__)
|
||||||
|
# define COMPILER_VERSION_INTERNAL DEC(__ti_version__)
|
||||||
|
|
||||||
|
#elif defined(__clang__)
|
||||||
|
# define COMPILER_ID "Clang"
|
||||||
|
# if defined(_MSC_VER)
|
||||||
|
# define SIMULATE_ID "MSVC"
|
||||||
|
# endif
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
|
||||||
|
# if defined(_MSC_VER)
|
||||||
|
/* _MSC_VER = VVRR */
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
|
||||||
|
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__LCC__) && (defined(__GNUC__) || defined(__GNUG__) || defined(__MCST__))
|
||||||
|
# define COMPILER_ID "LCC"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__LCC__ / 100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__LCC__ % 100)
|
||||||
|
# if defined(__LCC_MINOR__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__LCC_MINOR__)
|
||||||
|
# endif
|
||||||
|
# if defined(__GNUC__) && defined(__GNUC_MINOR__)
|
||||||
|
# define SIMULATE_ID "GNU"
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
|
||||||
|
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
|
||||||
|
# if defined(__GNUC_PATCHLEVEL__)
|
||||||
|
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
# define COMPILER_ID "GNU"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
|
||||||
|
# if defined(__GNUC_MINOR__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
|
||||||
|
# endif
|
||||||
|
# if defined(__GNUC_PATCHLEVEL__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
# define COMPILER_ID "MSVC"
|
||||||
|
/* _MSC_VER = VVRR */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
|
||||||
|
# if defined(_MSC_FULL_VER)
|
||||||
|
# if _MSC_VER >= 1400
|
||||||
|
/* _MSC_FULL_VER = VVRRPPPPP */
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
|
||||||
|
# else
|
||||||
|
/* _MSC_FULL_VER = VVRRPPPP */
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# if defined(_MSC_BUILD)
|
||||||
|
# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(_ADI_COMPILER)
|
||||||
|
# define COMPILER_ID "ADSP"
|
||||||
|
#if defined(__VERSIONNUM__)
|
||||||
|
/* __VERSIONNUM__ = 0xVVRRPPTT */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__VERSIONNUM__ >> 24 & 0xFF)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__VERSIONNUM__ >> 16 & 0xFF)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__VERSIONNUM__ >> 8 & 0xFF)
|
||||||
|
# define COMPILER_VERSION_TWEAK DEC(__VERSIONNUM__ & 0xFF)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
|
||||||
|
# define COMPILER_ID "IAR"
|
||||||
|
# if defined(__VER__) && defined(__ICCARM__)
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000)
|
||||||
|
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
|
||||||
|
# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__) || defined(__ICCSTM8__))
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100))
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__)
|
||||||
|
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__SDCC_VERSION_MAJOR) || defined(SDCC)
|
||||||
|
# define COMPILER_ID "SDCC"
|
||||||
|
# if defined(__SDCC_VERSION_MAJOR)
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__SDCC_VERSION_MAJOR)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__SDCC_VERSION_MINOR)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__SDCC_VERSION_PATCH)
|
||||||
|
# else
|
||||||
|
/* SDCC = VRP */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(SDCC/100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(SDCC/10 % 10)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(SDCC % 10)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
|
||||||
|
/* These compilers are either not known or too old to define an
|
||||||
|
identification macro. Try to identify the platform and guess that
|
||||||
|
it is the native compiler. */
|
||||||
|
#elif defined(__hpux) || defined(__hpua)
|
||||||
|
# define COMPILER_ID "HP"
|
||||||
|
|
||||||
|
#else /* unknown compiler */
|
||||||
|
# define COMPILER_ID ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Construct the string literal in pieces to prevent the source from
|
||||||
|
getting matched. Store it in a pointer rather than an array
|
||||||
|
because some compilers will just produce instructions to fill the
|
||||||
|
array rather than assigning a pointer to a static array. */
|
||||||
|
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
|
||||||
|
#ifdef SIMULATE_ID
|
||||||
|
char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __QNXNTO__
|
||||||
|
char const* qnxnto = "INFO" ":" "qnxnto[]";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
|
||||||
|
char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define STRINGIFY_HELPER(X) #X
|
||||||
|
#define STRINGIFY(X) STRINGIFY_HELPER(X)
|
||||||
|
|
||||||
|
/* Identify known platforms by name. */
|
||||||
|
#if defined(__linux) || defined(__linux__) || defined(linux)
|
||||||
|
# define PLATFORM_ID "Linux"
|
||||||
|
|
||||||
|
#elif defined(__MSYS__)
|
||||||
|
# define PLATFORM_ID "MSYS"
|
||||||
|
|
||||||
|
#elif defined(__CYGWIN__)
|
||||||
|
# define PLATFORM_ID "Cygwin"
|
||||||
|
|
||||||
|
#elif defined(__MINGW32__)
|
||||||
|
# define PLATFORM_ID "MinGW"
|
||||||
|
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
# define PLATFORM_ID "Darwin"
|
||||||
|
|
||||||
|
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||||||
|
# define PLATFORM_ID "Windows"
|
||||||
|
|
||||||
|
#elif defined(__FreeBSD__) || defined(__FreeBSD)
|
||||||
|
# define PLATFORM_ID "FreeBSD"
|
||||||
|
|
||||||
|
#elif defined(__NetBSD__) || defined(__NetBSD)
|
||||||
|
# define PLATFORM_ID "NetBSD"
|
||||||
|
|
||||||
|
#elif defined(__OpenBSD__) || defined(__OPENBSD)
|
||||||
|
# define PLATFORM_ID "OpenBSD"
|
||||||
|
|
||||||
|
#elif defined(__sun) || defined(sun)
|
||||||
|
# define PLATFORM_ID "SunOS"
|
||||||
|
|
||||||
|
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
|
||||||
|
# define PLATFORM_ID "AIX"
|
||||||
|
|
||||||
|
#elif defined(__hpux) || defined(__hpux__)
|
||||||
|
# define PLATFORM_ID "HP-UX"
|
||||||
|
|
||||||
|
#elif defined(__HAIKU__)
|
||||||
|
# define PLATFORM_ID "Haiku"
|
||||||
|
|
||||||
|
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
|
||||||
|
# define PLATFORM_ID "BeOS"
|
||||||
|
|
||||||
|
#elif defined(__QNX__) || defined(__QNXNTO__)
|
||||||
|
# define PLATFORM_ID "QNX"
|
||||||
|
|
||||||
|
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
|
||||||
|
# define PLATFORM_ID "Tru64"
|
||||||
|
|
||||||
|
#elif defined(__riscos) || defined(__riscos__)
|
||||||
|
# define PLATFORM_ID "RISCos"
|
||||||
|
|
||||||
|
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
|
||||||
|
# define PLATFORM_ID "SINIX"
|
||||||
|
|
||||||
|
#elif defined(__UNIX_SV__)
|
||||||
|
# define PLATFORM_ID "UNIX_SV"
|
||||||
|
|
||||||
|
#elif defined(__bsdos__)
|
||||||
|
# define PLATFORM_ID "BSDOS"
|
||||||
|
|
||||||
|
#elif defined(_MPRAS) || defined(MPRAS)
|
||||||
|
# define PLATFORM_ID "MP-RAS"
|
||||||
|
|
||||||
|
#elif defined(__osf) || defined(__osf__)
|
||||||
|
# define PLATFORM_ID "OSF1"
|
||||||
|
|
||||||
|
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
|
||||||
|
# define PLATFORM_ID "SCO_SV"
|
||||||
|
|
||||||
|
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
|
||||||
|
# define PLATFORM_ID "ULTRIX"
|
||||||
|
|
||||||
|
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
|
||||||
|
# define PLATFORM_ID "Xenix"
|
||||||
|
|
||||||
|
#elif defined(__WATCOMC__)
|
||||||
|
# if defined(__LINUX__)
|
||||||
|
# define PLATFORM_ID "Linux"
|
||||||
|
|
||||||
|
# elif defined(__DOS__)
|
||||||
|
# define PLATFORM_ID "DOS"
|
||||||
|
|
||||||
|
# elif defined(__OS2__)
|
||||||
|
# define PLATFORM_ID "OS2"
|
||||||
|
|
||||||
|
# elif defined(__WINDOWS__)
|
||||||
|
# define PLATFORM_ID "Windows3x"
|
||||||
|
|
||||||
|
# elif defined(__VXWORKS__)
|
||||||
|
# define PLATFORM_ID "VxWorks"
|
||||||
|
|
||||||
|
# else /* unknown platform */
|
||||||
|
# define PLATFORM_ID
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__INTEGRITY)
|
||||||
|
# if defined(INT_178B)
|
||||||
|
# define PLATFORM_ID "Integrity178"
|
||||||
|
|
||||||
|
# else /* regular Integrity */
|
||||||
|
# define PLATFORM_ID "Integrity"
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# elif defined(_ADI_COMPILER)
|
||||||
|
# define PLATFORM_ID "ADSP"
|
||||||
|
|
||||||
|
#else /* unknown platform */
|
||||||
|
# define PLATFORM_ID
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* For windows compilers MSVC and Intel we can determine
|
||||||
|
the architecture of the compiler being used. This is because
|
||||||
|
the compilers do not have flags that can change the architecture,
|
||||||
|
but rather depend on which compiler is being used
|
||||||
|
*/
|
||||||
|
#if defined(_WIN32) && defined(_MSC_VER)
|
||||||
|
# if defined(_M_IA64)
|
||||||
|
# define ARCHITECTURE_ID "IA64"
|
||||||
|
|
||||||
|
# elif defined(_M_ARM64EC)
|
||||||
|
# define ARCHITECTURE_ID "ARM64EC"
|
||||||
|
|
||||||
|
# elif defined(_M_X64) || defined(_M_AMD64)
|
||||||
|
# define ARCHITECTURE_ID "x64"
|
||||||
|
|
||||||
|
# elif defined(_M_IX86)
|
||||||
|
# define ARCHITECTURE_ID "X86"
|
||||||
|
|
||||||
|
# elif defined(_M_ARM64)
|
||||||
|
# define ARCHITECTURE_ID "ARM64"
|
||||||
|
|
||||||
|
# elif defined(_M_ARM)
|
||||||
|
# if _M_ARM == 4
|
||||||
|
# define ARCHITECTURE_ID "ARMV4I"
|
||||||
|
# elif _M_ARM == 5
|
||||||
|
# define ARCHITECTURE_ID "ARMV5I"
|
||||||
|
# else
|
||||||
|
# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# elif defined(_M_MIPS)
|
||||||
|
# define ARCHITECTURE_ID "MIPS"
|
||||||
|
|
||||||
|
# elif defined(_M_SH)
|
||||||
|
# define ARCHITECTURE_ID "SHx"
|
||||||
|
|
||||||
|
# else /* unknown architecture */
|
||||||
|
# define ARCHITECTURE_ID ""
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__WATCOMC__)
|
||||||
|
# if defined(_M_I86)
|
||||||
|
# define ARCHITECTURE_ID "I86"
|
||||||
|
|
||||||
|
# elif defined(_M_IX86)
|
||||||
|
# define ARCHITECTURE_ID "X86"
|
||||||
|
|
||||||
|
# else /* unknown architecture */
|
||||||
|
# define ARCHITECTURE_ID ""
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
|
||||||
|
# if defined(__ICCARM__)
|
||||||
|
# define ARCHITECTURE_ID "ARM"
|
||||||
|
|
||||||
|
# elif defined(__ICCRX__)
|
||||||
|
# define ARCHITECTURE_ID "RX"
|
||||||
|
|
||||||
|
# elif defined(__ICCRH850__)
|
||||||
|
# define ARCHITECTURE_ID "RH850"
|
||||||
|
|
||||||
|
# elif defined(__ICCRL78__)
|
||||||
|
# define ARCHITECTURE_ID "RL78"
|
||||||
|
|
||||||
|
# elif defined(__ICCRISCV__)
|
||||||
|
# define ARCHITECTURE_ID "RISCV"
|
||||||
|
|
||||||
|
# elif defined(__ICCAVR__)
|
||||||
|
# define ARCHITECTURE_ID "AVR"
|
||||||
|
|
||||||
|
# elif defined(__ICC430__)
|
||||||
|
# define ARCHITECTURE_ID "MSP430"
|
||||||
|
|
||||||
|
# elif defined(__ICCV850__)
|
||||||
|
# define ARCHITECTURE_ID "V850"
|
||||||
|
|
||||||
|
# elif defined(__ICC8051__)
|
||||||
|
# define ARCHITECTURE_ID "8051"
|
||||||
|
|
||||||
|
# elif defined(__ICCSTM8__)
|
||||||
|
# define ARCHITECTURE_ID "STM8"
|
||||||
|
|
||||||
|
# else /* unknown architecture */
|
||||||
|
# define ARCHITECTURE_ID ""
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__ghs__)
|
||||||
|
# if defined(__PPC64__)
|
||||||
|
# define ARCHITECTURE_ID "PPC64"
|
||||||
|
|
||||||
|
# elif defined(__ppc__)
|
||||||
|
# define ARCHITECTURE_ID "PPC"
|
||||||
|
|
||||||
|
# elif defined(__ARM__)
|
||||||
|
# define ARCHITECTURE_ID "ARM"
|
||||||
|
|
||||||
|
# elif defined(__x86_64__)
|
||||||
|
# define ARCHITECTURE_ID "x64"
|
||||||
|
|
||||||
|
# elif defined(__i386__)
|
||||||
|
# define ARCHITECTURE_ID "X86"
|
||||||
|
|
||||||
|
# else /* unknown architecture */
|
||||||
|
# define ARCHITECTURE_ID ""
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__clang__) && defined(__ti__)
|
||||||
|
# if defined(__ARM_ARCH)
|
||||||
|
# define ARCHITECTURE_ID "Arm"
|
||||||
|
|
||||||
|
# else /* unknown architecture */
|
||||||
|
# define ARCHITECTURE_ID ""
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__TI_COMPILER_VERSION__)
|
||||||
|
# if defined(__TI_ARM__)
|
||||||
|
# define ARCHITECTURE_ID "ARM"
|
||||||
|
|
||||||
|
# elif defined(__MSP430__)
|
||||||
|
# define ARCHITECTURE_ID "MSP430"
|
||||||
|
|
||||||
|
# elif defined(__TMS320C28XX__)
|
||||||
|
# define ARCHITECTURE_ID "TMS320C28x"
|
||||||
|
|
||||||
|
# elif defined(__TMS320C6X__) || defined(_TMS320C6X)
|
||||||
|
# define ARCHITECTURE_ID "TMS320C6x"
|
||||||
|
|
||||||
|
# else /* unknown architecture */
|
||||||
|
# define ARCHITECTURE_ID ""
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# elif defined(__ADSPSHARC__)
|
||||||
|
# define ARCHITECTURE_ID "SHARC"
|
||||||
|
|
||||||
|
# elif defined(__ADSPBLACKFIN__)
|
||||||
|
# define ARCHITECTURE_ID "Blackfin"
|
||||||
|
|
||||||
|
#elif defined(__TASKING__)
|
||||||
|
|
||||||
|
# if defined(__CTC__) || defined(__CPTC__)
|
||||||
|
# define ARCHITECTURE_ID "TriCore"
|
||||||
|
|
||||||
|
# elif defined(__CMCS__)
|
||||||
|
# define ARCHITECTURE_ID "MCS"
|
||||||
|
|
||||||
|
# elif defined(__CARM__)
|
||||||
|
# define ARCHITECTURE_ID "ARM"
|
||||||
|
|
||||||
|
# elif defined(__CARC__)
|
||||||
|
# define ARCHITECTURE_ID "ARC"
|
||||||
|
|
||||||
|
# elif defined(__C51__)
|
||||||
|
# define ARCHITECTURE_ID "8051"
|
||||||
|
|
||||||
|
# elif defined(__CPCP__)
|
||||||
|
# define ARCHITECTURE_ID "PCP"
|
||||||
|
|
||||||
|
# else
|
||||||
|
# define ARCHITECTURE_ID ""
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
# define ARCHITECTURE_ID
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Convert integer to decimal digit literals. */
|
||||||
|
#define DEC(n) \
|
||||||
|
('0' + (((n) / 10000000)%10)), \
|
||||||
|
('0' + (((n) / 1000000)%10)), \
|
||||||
|
('0' + (((n) / 100000)%10)), \
|
||||||
|
('0' + (((n) / 10000)%10)), \
|
||||||
|
('0' + (((n) / 1000)%10)), \
|
||||||
|
('0' + (((n) / 100)%10)), \
|
||||||
|
('0' + (((n) / 10)%10)), \
|
||||||
|
('0' + ((n) % 10))
|
||||||
|
|
||||||
|
/* Convert integer to hex digit literals. */
|
||||||
|
#define HEX(n) \
|
||||||
|
('0' + ((n)>>28 & 0xF)), \
|
||||||
|
('0' + ((n)>>24 & 0xF)), \
|
||||||
|
('0' + ((n)>>20 & 0xF)), \
|
||||||
|
('0' + ((n)>>16 & 0xF)), \
|
||||||
|
('0' + ((n)>>12 & 0xF)), \
|
||||||
|
('0' + ((n)>>8 & 0xF)), \
|
||||||
|
('0' + ((n)>>4 & 0xF)), \
|
||||||
|
('0' + ((n) & 0xF))
|
||||||
|
|
||||||
|
/* Construct a string literal encoding the version number. */
|
||||||
|
#ifdef COMPILER_VERSION
|
||||||
|
char const* info_version = "INFO" ":" "compiler_version[" COMPILER_VERSION "]";
|
||||||
|
|
||||||
|
/* Construct a string literal encoding the version number components. */
|
||||||
|
#elif defined(COMPILER_VERSION_MAJOR)
|
||||||
|
char const info_version[] = {
|
||||||
|
'I', 'N', 'F', 'O', ':',
|
||||||
|
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
|
||||||
|
COMPILER_VERSION_MAJOR,
|
||||||
|
# ifdef COMPILER_VERSION_MINOR
|
||||||
|
'.', COMPILER_VERSION_MINOR,
|
||||||
|
# ifdef COMPILER_VERSION_PATCH
|
||||||
|
'.', COMPILER_VERSION_PATCH,
|
||||||
|
# ifdef COMPILER_VERSION_TWEAK
|
||||||
|
'.', COMPILER_VERSION_TWEAK,
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
']','\0'};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Construct a string literal encoding the internal version number. */
|
||||||
|
#ifdef COMPILER_VERSION_INTERNAL
|
||||||
|
char const info_version_internal[] = {
|
||||||
|
'I', 'N', 'F', 'O', ':',
|
||||||
|
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_',
|
||||||
|
'i','n','t','e','r','n','a','l','[',
|
||||||
|
COMPILER_VERSION_INTERNAL,']','\0'};
|
||||||
|
#elif defined(COMPILER_VERSION_INTERNAL_STR)
|
||||||
|
char const* info_version_internal = "INFO" ":" "compiler_version_internal[" COMPILER_VERSION_INTERNAL_STR "]";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Construct a string literal encoding the version number components. */
|
||||||
|
#ifdef SIMULATE_VERSION_MAJOR
|
||||||
|
char const info_simulate_version[] = {
|
||||||
|
'I', 'N', 'F', 'O', ':',
|
||||||
|
's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[',
|
||||||
|
SIMULATE_VERSION_MAJOR,
|
||||||
|
# ifdef SIMULATE_VERSION_MINOR
|
||||||
|
'.', SIMULATE_VERSION_MINOR,
|
||||||
|
# ifdef SIMULATE_VERSION_PATCH
|
||||||
|
'.', SIMULATE_VERSION_PATCH,
|
||||||
|
# ifdef SIMULATE_VERSION_TWEAK
|
||||||
|
'.', SIMULATE_VERSION_TWEAK,
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
']','\0'};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Construct the string literal in pieces to prevent the source from
|
||||||
|
getting matched. Store it in a pointer rather than an array
|
||||||
|
because some compilers will just produce instructions to fill the
|
||||||
|
array rather than assigning a pointer to a static array. */
|
||||||
|
char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
|
||||||
|
char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define C_STD_99 199901L
|
||||||
|
#define C_STD_11 201112L
|
||||||
|
#define C_STD_17 201710L
|
||||||
|
#define C_STD_23 202311L
|
||||||
|
|
||||||
|
#ifdef __STDC_VERSION__
|
||||||
|
# define C_STD __STDC_VERSION__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__STDC__) && !defined(__clang__)
|
||||||
|
# if defined(_MSC_VER) || defined(__ibmxl__) || defined(__IBMC__)
|
||||||
|
# define C_VERSION "90"
|
||||||
|
# else
|
||||||
|
# define C_VERSION
|
||||||
|
# endif
|
||||||
|
#elif C_STD > C_STD_17
|
||||||
|
# define C_VERSION "23"
|
||||||
|
#elif C_STD > C_STD_11
|
||||||
|
# define C_VERSION "17"
|
||||||
|
#elif C_STD > C_STD_99
|
||||||
|
# define C_VERSION "11"
|
||||||
|
#elif C_STD >= C_STD_99
|
||||||
|
# define C_VERSION "99"
|
||||||
|
#else
|
||||||
|
# define C_VERSION "90"
|
||||||
|
#endif
|
||||||
|
const char* info_language_standard_default =
|
||||||
|
"INFO" ":" "standard_default[" C_VERSION "]";
|
||||||
|
|
||||||
|
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
|
||||||
|
#if (defined(__clang__) || defined(__GNUC__) || defined(__xlC__) || \
|
||||||
|
defined(__TI_COMPILER_VERSION__)) && \
|
||||||
|
!defined(__STRICT_ANSI__)
|
||||||
|
"ON"
|
||||||
|
#else
|
||||||
|
"OFF"
|
||||||
|
#endif
|
||||||
|
"]";
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifdef ID_VOID_MAIN
|
||||||
|
void main() {}
|
||||||
|
#else
|
||||||
|
# if defined(__CLASSIC_C__)
|
||||||
|
int main(argc, argv) int argc; char *argv[];
|
||||||
|
# else
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
int require = 0;
|
||||||
|
require += info_compiler[argc];
|
||||||
|
require += info_platform[argc];
|
||||||
|
require += info_arch[argc];
|
||||||
|
#ifdef COMPILER_VERSION_MAJOR
|
||||||
|
require += info_version[argc];
|
||||||
|
#endif
|
||||||
|
#ifdef COMPILER_VERSION_INTERNAL
|
||||||
|
require += info_version_internal[argc];
|
||||||
|
#endif
|
||||||
|
#ifdef SIMULATE_ID
|
||||||
|
require += info_simulate[argc];
|
||||||
|
#endif
|
||||||
|
#ifdef SIMULATE_VERSION_MAJOR
|
||||||
|
require += info_simulate_version[argc];
|
||||||
|
#endif
|
||||||
|
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
|
||||||
|
require += info_cray[argc];
|
||||||
|
#endif
|
||||||
|
require += info_language_standard_default[argc];
|
||||||
|
require += info_language_extensions_default[argc];
|
||||||
|
(void)argv;
|
||||||
|
return require;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,919 @@
|
||||||
|
/* This source file must have a .cpp extension so that all C++ compilers
|
||||||
|
recognize the extension without flags. Borland does not know .cxx for
|
||||||
|
example. */
|
||||||
|
#ifndef __cplusplus
|
||||||
|
# error "A C compiler has been selected for C++."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__has_include)
|
||||||
|
/* If the compiler does not have __has_include, pretend the answer is
|
||||||
|
always no. */
|
||||||
|
# define __has_include(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Version number components: V=Version, R=Revision, P=Patch
|
||||||
|
Version date components: YYYY=Year, MM=Month, DD=Day */
|
||||||
|
|
||||||
|
#if defined(__INTEL_COMPILER) || defined(__ICC)
|
||||||
|
# define COMPILER_ID "Intel"
|
||||||
|
# if defined(_MSC_VER)
|
||||||
|
# define SIMULATE_ID "MSVC"
|
||||||
|
# endif
|
||||||
|
# if defined(__GNUC__)
|
||||||
|
# define SIMULATE_ID "GNU"
|
||||||
|
# endif
|
||||||
|
/* __INTEL_COMPILER = VRP prior to 2021, and then VVVV for 2021 and later,
|
||||||
|
except that a few beta releases use the old format with V=2021. */
|
||||||
|
# if __INTEL_COMPILER < 2021 || __INTEL_COMPILER == 202110 || __INTEL_COMPILER == 202111
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
|
||||||
|
# if defined(__INTEL_COMPILER_UPDATE)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE)
|
||||||
|
# else
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER_UPDATE)
|
||||||
|
/* The third version component from --version is an update index,
|
||||||
|
but no macro is provided for it. */
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(0)
|
||||||
|
# endif
|
||||||
|
# if defined(__INTEL_COMPILER_BUILD_DATE)
|
||||||
|
/* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
|
||||||
|
# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
|
||||||
|
# endif
|
||||||
|
# if defined(_MSC_VER)
|
||||||
|
/* _MSC_VER = VVRR */
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
|
||||||
|
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
|
||||||
|
# endif
|
||||||
|
# if defined(__GNUC__)
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
|
||||||
|
# elif defined(__GNUG__)
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
|
||||||
|
# endif
|
||||||
|
# if defined(__GNUC_MINOR__)
|
||||||
|
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
|
||||||
|
# endif
|
||||||
|
# if defined(__GNUC_PATCHLEVEL__)
|
||||||
|
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif (defined(__clang__) && defined(__INTEL_CLANG_COMPILER)) || defined(__INTEL_LLVM_COMPILER)
|
||||||
|
# define COMPILER_ID "IntelLLVM"
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# define SIMULATE_ID "MSVC"
|
||||||
|
#endif
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
# define SIMULATE_ID "GNU"
|
||||||
|
#endif
|
||||||
|
/* __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and
|
||||||
|
* later. Look for 6 digit vs. 8 digit version number to decide encoding.
|
||||||
|
* VVVV is no smaller than the current year when a version is released.
|
||||||
|
*/
|
||||||
|
#if __INTEL_LLVM_COMPILER < 1000000L
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/10 % 10)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 10)
|
||||||
|
#else
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/10000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/100 % 100)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 100)
|
||||||
|
#endif
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
/* _MSC_VER = VVRR */
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
|
||||||
|
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
|
||||||
|
#endif
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
|
||||||
|
#elif defined(__GNUG__)
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
|
||||||
|
#endif
|
||||||
|
#if defined(__GNUC_MINOR__)
|
||||||
|
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
|
||||||
|
#endif
|
||||||
|
#if defined(__GNUC_PATCHLEVEL__)
|
||||||
|
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(__PATHCC__)
|
||||||
|
# define COMPILER_ID "PathScale"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
|
||||||
|
# if defined(__PATHCC_PATCHLEVEL__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
|
||||||
|
# define COMPILER_ID "Embarcadero"
|
||||||
|
# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
|
||||||
|
# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF)
|
||||||
|
|
||||||
|
#elif defined(__BORLANDC__)
|
||||||
|
# define COMPILER_ID "Borland"
|
||||||
|
/* __BORLANDC__ = 0xVRR */
|
||||||
|
# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
|
||||||
|
# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
|
||||||
|
|
||||||
|
#elif defined(__WATCOMC__) && __WATCOMC__ < 1200
|
||||||
|
# define COMPILER_ID "Watcom"
|
||||||
|
/* __WATCOMC__ = VVRR */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
|
||||||
|
# if (__WATCOMC__ % 10) > 0
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__WATCOMC__)
|
||||||
|
# define COMPILER_ID "OpenWatcom"
|
||||||
|
/* __WATCOMC__ = VVRP + 1100 */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
|
||||||
|
# if (__WATCOMC__ % 10) > 0
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__SUNPRO_CC)
|
||||||
|
# define COMPILER_ID "SunPro"
|
||||||
|
# if __SUNPRO_CC >= 0x5100
|
||||||
|
/* __SUNPRO_CC = 0xVRRP */
|
||||||
|
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12)
|
||||||
|
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF)
|
||||||
|
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
|
||||||
|
# else
|
||||||
|
/* __SUNPRO_CC = 0xVRP */
|
||||||
|
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8)
|
||||||
|
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF)
|
||||||
|
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__HP_aCC)
|
||||||
|
# define COMPILER_ID "HP"
|
||||||
|
/* __HP_aCC = VVRRPP */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100)
|
||||||
|
|
||||||
|
#elif defined(__DECCXX)
|
||||||
|
# define COMPILER_ID "Compaq"
|
||||||
|
/* __DECCXX_VER = VVRRTPPPP */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000)
|
||||||
|
|
||||||
|
#elif defined(__IBMCPP__) && defined(__COMPILER_VER__)
|
||||||
|
# define COMPILER_ID "zOS"
|
||||||
|
/* __IBMCPP__ = VRP */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
|
||||||
|
|
||||||
|
#elif defined(__open_xl__) && defined(__clang__)
|
||||||
|
# define COMPILER_ID "IBMClang"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__open_xl_version__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__open_xl_release__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__open_xl_modification__)
|
||||||
|
# define COMPILER_VERSION_TWEAK DEC(__open_xl_ptf_fix_level__)
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(__ibmxl__) && defined(__clang__)
|
||||||
|
# define COMPILER_ID "XLClang"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__)
|
||||||
|
# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__)
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ >= 800
|
||||||
|
# define COMPILER_ID "XL"
|
||||||
|
/* __IBMCPP__ = VRP */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
|
||||||
|
|
||||||
|
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ < 800
|
||||||
|
# define COMPILER_ID "VisualAge"
|
||||||
|
/* __IBMCPP__ = VRP */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
|
||||||
|
|
||||||
|
#elif defined(__NVCOMPILER)
|
||||||
|
# define COMPILER_ID "NVHPC"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__NVCOMPILER_MAJOR__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__NVCOMPILER_MINOR__)
|
||||||
|
# if defined(__NVCOMPILER_PATCHLEVEL__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__NVCOMPILER_PATCHLEVEL__)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__PGI)
|
||||||
|
# define COMPILER_ID "PGI"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
|
||||||
|
# if defined(__PGIC_PATCHLEVEL__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__clang__) && defined(__cray__)
|
||||||
|
# define COMPILER_ID "CrayClang"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__cray_major__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__cray_minor__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__cray_patchlevel__)
|
||||||
|
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(_CRAYC)
|
||||||
|
# define COMPILER_ID "Cray"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
|
||||||
|
|
||||||
|
#elif defined(__TI_COMPILER_VERSION__)
|
||||||
|
# define COMPILER_ID "TI"
|
||||||
|
/* __TI_COMPILER_VERSION__ = VVVRRRPPP */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
|
||||||
|
|
||||||
|
#elif defined(__CLANG_FUJITSU)
|
||||||
|
# define COMPILER_ID "FujitsuClang"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
|
||||||
|
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(__FUJITSU)
|
||||||
|
# define COMPILER_ID "Fujitsu"
|
||||||
|
# if defined(__FCC_version__)
|
||||||
|
# define COMPILER_VERSION __FCC_version__
|
||||||
|
# elif defined(__FCC_major__)
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
|
||||||
|
# endif
|
||||||
|
# if defined(__fcc_version)
|
||||||
|
# define COMPILER_VERSION_INTERNAL DEC(__fcc_version)
|
||||||
|
# elif defined(__FCC_VERSION)
|
||||||
|
# define COMPILER_VERSION_INTERNAL DEC(__FCC_VERSION)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(__ghs__)
|
||||||
|
# define COMPILER_ID "GHS"
|
||||||
|
/* __GHS_VERSION_NUMBER = VVVVRP */
|
||||||
|
# ifdef __GHS_VERSION_NUMBER
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__TASKING__)
|
||||||
|
# define COMPILER_ID "Tasking"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__VERSION__/1000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__VERSION__ % 100)
|
||||||
|
# define COMPILER_VERSION_INTERNAL DEC(__VERSION__)
|
||||||
|
|
||||||
|
#elif defined(__ORANGEC__)
|
||||||
|
# define COMPILER_ID "OrangeC"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__ORANGEC_MAJOR__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__ORANGEC_MINOR__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__ORANGEC_PATCHLEVEL__)
|
||||||
|
|
||||||
|
#elif defined(__SCO_VERSION__)
|
||||||
|
# define COMPILER_ID "SCO"
|
||||||
|
|
||||||
|
#elif defined(__ARMCC_VERSION) && !defined(__clang__)
|
||||||
|
# define COMPILER_ID "ARMCC"
|
||||||
|
#if __ARMCC_VERSION >= 1000000
|
||||||
|
/* __ARMCC_VERSION = VRRPPPP */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
|
||||||
|
#else
|
||||||
|
/* __ARMCC_VERSION = VRPPPP */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(__clang__) && defined(__apple_build_version__)
|
||||||
|
# define COMPILER_ID "AppleClang"
|
||||||
|
# if defined(_MSC_VER)
|
||||||
|
# define SIMULATE_ID "MSVC"
|
||||||
|
# endif
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
|
||||||
|
# if defined(_MSC_VER)
|
||||||
|
/* _MSC_VER = VVRR */
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
|
||||||
|
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
|
||||||
|
# endif
|
||||||
|
# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__)
|
||||||
|
|
||||||
|
#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION)
|
||||||
|
# define COMPILER_ID "ARMClang"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION/100 % 100)
|
||||||
|
# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION)
|
||||||
|
|
||||||
|
#elif defined(__clang__) && defined(__ti__)
|
||||||
|
# define COMPILER_ID "TIClang"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__ti_major__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__ti_minor__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__ti_patchlevel__)
|
||||||
|
# define COMPILER_VERSION_INTERNAL DEC(__ti_version__)
|
||||||
|
|
||||||
|
#elif defined(__clang__)
|
||||||
|
# define COMPILER_ID "Clang"
|
||||||
|
# if defined(_MSC_VER)
|
||||||
|
# define SIMULATE_ID "MSVC"
|
||||||
|
# endif
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
|
||||||
|
# if defined(_MSC_VER)
|
||||||
|
/* _MSC_VER = VVRR */
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
|
||||||
|
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__LCC__) && (defined(__GNUC__) || defined(__GNUG__) || defined(__MCST__))
|
||||||
|
# define COMPILER_ID "LCC"
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__LCC__ / 100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__LCC__ % 100)
|
||||||
|
# if defined(__LCC_MINOR__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__LCC_MINOR__)
|
||||||
|
# endif
|
||||||
|
# if defined(__GNUC__) && defined(__GNUC_MINOR__)
|
||||||
|
# define SIMULATE_ID "GNU"
|
||||||
|
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
|
||||||
|
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
|
||||||
|
# if defined(__GNUC_PATCHLEVEL__)
|
||||||
|
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__GNUC__) || defined(__GNUG__)
|
||||||
|
# define COMPILER_ID "GNU"
|
||||||
|
# if defined(__GNUC__)
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
|
||||||
|
# else
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__GNUG__)
|
||||||
|
# endif
|
||||||
|
# if defined(__GNUC_MINOR__)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
|
||||||
|
# endif
|
||||||
|
# if defined(__GNUC_PATCHLEVEL__)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
# define COMPILER_ID "MSVC"
|
||||||
|
/* _MSC_VER = VVRR */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
|
||||||
|
# if defined(_MSC_FULL_VER)
|
||||||
|
# if _MSC_VER >= 1400
|
||||||
|
/* _MSC_FULL_VER = VVRRPPPPP */
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
|
||||||
|
# else
|
||||||
|
/* _MSC_FULL_VER = VVRRPPPP */
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# if defined(_MSC_BUILD)
|
||||||
|
# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(_ADI_COMPILER)
|
||||||
|
# define COMPILER_ID "ADSP"
|
||||||
|
#if defined(__VERSIONNUM__)
|
||||||
|
/* __VERSIONNUM__ = 0xVVRRPPTT */
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC(__VERSIONNUM__ >> 24 & 0xFF)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(__VERSIONNUM__ >> 16 & 0xFF)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__VERSIONNUM__ >> 8 & 0xFF)
|
||||||
|
# define COMPILER_VERSION_TWEAK DEC(__VERSIONNUM__ & 0xFF)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
|
||||||
|
# define COMPILER_ID "IAR"
|
||||||
|
# if defined(__VER__) && defined(__ICCARM__)
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000)
|
||||||
|
# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000)
|
||||||
|
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
|
||||||
|
# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__) || defined(__ICCSTM8__))
|
||||||
|
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100)
|
||||||
|
# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100))
|
||||||
|
# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__)
|
||||||
|
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
|
||||||
|
/* These compilers are either not known or too old to define an
|
||||||
|
identification macro. Try to identify the platform and guess that
|
||||||
|
it is the native compiler. */
|
||||||
|
#elif defined(__hpux) || defined(__hpua)
|
||||||
|
# define COMPILER_ID "HP"
|
||||||
|
|
||||||
|
#else /* unknown compiler */
|
||||||
|
# define COMPILER_ID ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Construct the string literal in pieces to prevent the source from
|
||||||
|
getting matched. Store it in a pointer rather than an array
|
||||||
|
because some compilers will just produce instructions to fill the
|
||||||
|
array rather than assigning a pointer to a static array. */
|
||||||
|
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
|
||||||
|
#ifdef SIMULATE_ID
|
||||||
|
char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __QNXNTO__
|
||||||
|
char const* qnxnto = "INFO" ":" "qnxnto[]";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
|
||||||
|
char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define STRINGIFY_HELPER(X) #X
|
||||||
|
#define STRINGIFY(X) STRINGIFY_HELPER(X)
|
||||||
|
|
||||||
|
/* Identify known platforms by name. */
|
||||||
|
#if defined(__linux) || defined(__linux__) || defined(linux)
|
||||||
|
# define PLATFORM_ID "Linux"
|
||||||
|
|
||||||
|
#elif defined(__MSYS__)
|
||||||
|
# define PLATFORM_ID "MSYS"
|
||||||
|
|
||||||
|
#elif defined(__CYGWIN__)
|
||||||
|
# define PLATFORM_ID "Cygwin"
|
||||||
|
|
||||||
|
#elif defined(__MINGW32__)
|
||||||
|
# define PLATFORM_ID "MinGW"
|
||||||
|
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
# define PLATFORM_ID "Darwin"
|
||||||
|
|
||||||
|
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||||||
|
# define PLATFORM_ID "Windows"
|
||||||
|
|
||||||
|
#elif defined(__FreeBSD__) || defined(__FreeBSD)
|
||||||
|
# define PLATFORM_ID "FreeBSD"
|
||||||
|
|
||||||
|
#elif defined(__NetBSD__) || defined(__NetBSD)
|
||||||
|
# define PLATFORM_ID "NetBSD"
|
||||||
|
|
||||||
|
#elif defined(__OpenBSD__) || defined(__OPENBSD)
|
||||||
|
# define PLATFORM_ID "OpenBSD"
|
||||||
|
|
||||||
|
#elif defined(__sun) || defined(sun)
|
||||||
|
# define PLATFORM_ID "SunOS"
|
||||||
|
|
||||||
|
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
|
||||||
|
# define PLATFORM_ID "AIX"
|
||||||
|
|
||||||
|
#elif defined(__hpux) || defined(__hpux__)
|
||||||
|
# define PLATFORM_ID "HP-UX"
|
||||||
|
|
||||||
|
#elif defined(__HAIKU__)
|
||||||
|
# define PLATFORM_ID "Haiku"
|
||||||
|
|
||||||
|
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
|
||||||
|
# define PLATFORM_ID "BeOS"
|
||||||
|
|
||||||
|
#elif defined(__QNX__) || defined(__QNXNTO__)
|
||||||
|
# define PLATFORM_ID "QNX"
|
||||||
|
|
||||||
|
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
|
||||||
|
# define PLATFORM_ID "Tru64"
|
||||||
|
|
||||||
|
#elif defined(__riscos) || defined(__riscos__)
|
||||||
|
# define PLATFORM_ID "RISCos"
|
||||||
|
|
||||||
|
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
|
||||||
|
# define PLATFORM_ID "SINIX"
|
||||||
|
|
||||||
|
#elif defined(__UNIX_SV__)
|
||||||
|
# define PLATFORM_ID "UNIX_SV"
|
||||||
|
|
||||||
|
#elif defined(__bsdos__)
|
||||||
|
# define PLATFORM_ID "BSDOS"
|
||||||
|
|
||||||
|
#elif defined(_MPRAS) || defined(MPRAS)
|
||||||
|
# define PLATFORM_ID "MP-RAS"
|
||||||
|
|
||||||
|
#elif defined(__osf) || defined(__osf__)
|
||||||
|
# define PLATFORM_ID "OSF1"
|
||||||
|
|
||||||
|
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
|
||||||
|
# define PLATFORM_ID "SCO_SV"
|
||||||
|
|
||||||
|
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
|
||||||
|
# define PLATFORM_ID "ULTRIX"
|
||||||
|
|
||||||
|
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
|
||||||
|
# define PLATFORM_ID "Xenix"
|
||||||
|
|
||||||
|
#elif defined(__WATCOMC__)
|
||||||
|
# if defined(__LINUX__)
|
||||||
|
# define PLATFORM_ID "Linux"
|
||||||
|
|
||||||
|
# elif defined(__DOS__)
|
||||||
|
# define PLATFORM_ID "DOS"
|
||||||
|
|
||||||
|
# elif defined(__OS2__)
|
||||||
|
# define PLATFORM_ID "OS2"
|
||||||
|
|
||||||
|
# elif defined(__WINDOWS__)
|
||||||
|
# define PLATFORM_ID "Windows3x"
|
||||||
|
|
||||||
|
# elif defined(__VXWORKS__)
|
||||||
|
# define PLATFORM_ID "VxWorks"
|
||||||
|
|
||||||
|
# else /* unknown platform */
|
||||||
|
# define PLATFORM_ID
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__INTEGRITY)
|
||||||
|
# if defined(INT_178B)
|
||||||
|
# define PLATFORM_ID "Integrity178"
|
||||||
|
|
||||||
|
# else /* regular Integrity */
|
||||||
|
# define PLATFORM_ID "Integrity"
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# elif defined(_ADI_COMPILER)
|
||||||
|
# define PLATFORM_ID "ADSP"
|
||||||
|
|
||||||
|
#else /* unknown platform */
|
||||||
|
# define PLATFORM_ID
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* For windows compilers MSVC and Intel we can determine
|
||||||
|
the architecture of the compiler being used. This is because
|
||||||
|
the compilers do not have flags that can change the architecture,
|
||||||
|
but rather depend on which compiler is being used
|
||||||
|
*/
|
||||||
|
#if defined(_WIN32) && defined(_MSC_VER)
|
||||||
|
# if defined(_M_IA64)
|
||||||
|
# define ARCHITECTURE_ID "IA64"
|
||||||
|
|
||||||
|
# elif defined(_M_ARM64EC)
|
||||||
|
# define ARCHITECTURE_ID "ARM64EC"
|
||||||
|
|
||||||
|
# elif defined(_M_X64) || defined(_M_AMD64)
|
||||||
|
# define ARCHITECTURE_ID "x64"
|
||||||
|
|
||||||
|
# elif defined(_M_IX86)
|
||||||
|
# define ARCHITECTURE_ID "X86"
|
||||||
|
|
||||||
|
# elif defined(_M_ARM64)
|
||||||
|
# define ARCHITECTURE_ID "ARM64"
|
||||||
|
|
||||||
|
# elif defined(_M_ARM)
|
||||||
|
# if _M_ARM == 4
|
||||||
|
# define ARCHITECTURE_ID "ARMV4I"
|
||||||
|
# elif _M_ARM == 5
|
||||||
|
# define ARCHITECTURE_ID "ARMV5I"
|
||||||
|
# else
|
||||||
|
# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# elif defined(_M_MIPS)
|
||||||
|
# define ARCHITECTURE_ID "MIPS"
|
||||||
|
|
||||||
|
# elif defined(_M_SH)
|
||||||
|
# define ARCHITECTURE_ID "SHx"
|
||||||
|
|
||||||
|
# else /* unknown architecture */
|
||||||
|
# define ARCHITECTURE_ID ""
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__WATCOMC__)
|
||||||
|
# if defined(_M_I86)
|
||||||
|
# define ARCHITECTURE_ID "I86"
|
||||||
|
|
||||||
|
# elif defined(_M_IX86)
|
||||||
|
# define ARCHITECTURE_ID "X86"
|
||||||
|
|
||||||
|
# else /* unknown architecture */
|
||||||
|
# define ARCHITECTURE_ID ""
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
|
||||||
|
# if defined(__ICCARM__)
|
||||||
|
# define ARCHITECTURE_ID "ARM"
|
||||||
|
|
||||||
|
# elif defined(__ICCRX__)
|
||||||
|
# define ARCHITECTURE_ID "RX"
|
||||||
|
|
||||||
|
# elif defined(__ICCRH850__)
|
||||||
|
# define ARCHITECTURE_ID "RH850"
|
||||||
|
|
||||||
|
# elif defined(__ICCRL78__)
|
||||||
|
# define ARCHITECTURE_ID "RL78"
|
||||||
|
|
||||||
|
# elif defined(__ICCRISCV__)
|
||||||
|
# define ARCHITECTURE_ID "RISCV"
|
||||||
|
|
||||||
|
# elif defined(__ICCAVR__)
|
||||||
|
# define ARCHITECTURE_ID "AVR"
|
||||||
|
|
||||||
|
# elif defined(__ICC430__)
|
||||||
|
# define ARCHITECTURE_ID "MSP430"
|
||||||
|
|
||||||
|
# elif defined(__ICCV850__)
|
||||||
|
# define ARCHITECTURE_ID "V850"
|
||||||
|
|
||||||
|
# elif defined(__ICC8051__)
|
||||||
|
# define ARCHITECTURE_ID "8051"
|
||||||
|
|
||||||
|
# elif defined(__ICCSTM8__)
|
||||||
|
# define ARCHITECTURE_ID "STM8"
|
||||||
|
|
||||||
|
# else /* unknown architecture */
|
||||||
|
# define ARCHITECTURE_ID ""
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__ghs__)
|
||||||
|
# if defined(__PPC64__)
|
||||||
|
# define ARCHITECTURE_ID "PPC64"
|
||||||
|
|
||||||
|
# elif defined(__ppc__)
|
||||||
|
# define ARCHITECTURE_ID "PPC"
|
||||||
|
|
||||||
|
# elif defined(__ARM__)
|
||||||
|
# define ARCHITECTURE_ID "ARM"
|
||||||
|
|
||||||
|
# elif defined(__x86_64__)
|
||||||
|
# define ARCHITECTURE_ID "x64"
|
||||||
|
|
||||||
|
# elif defined(__i386__)
|
||||||
|
# define ARCHITECTURE_ID "X86"
|
||||||
|
|
||||||
|
# else /* unknown architecture */
|
||||||
|
# define ARCHITECTURE_ID ""
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__clang__) && defined(__ti__)
|
||||||
|
# if defined(__ARM_ARCH)
|
||||||
|
# define ARCHITECTURE_ID "Arm"
|
||||||
|
|
||||||
|
# else /* unknown architecture */
|
||||||
|
# define ARCHITECTURE_ID ""
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__TI_COMPILER_VERSION__)
|
||||||
|
# if defined(__TI_ARM__)
|
||||||
|
# define ARCHITECTURE_ID "ARM"
|
||||||
|
|
||||||
|
# elif defined(__MSP430__)
|
||||||
|
# define ARCHITECTURE_ID "MSP430"
|
||||||
|
|
||||||
|
# elif defined(__TMS320C28XX__)
|
||||||
|
# define ARCHITECTURE_ID "TMS320C28x"
|
||||||
|
|
||||||
|
# elif defined(__TMS320C6X__) || defined(_TMS320C6X)
|
||||||
|
# define ARCHITECTURE_ID "TMS320C6x"
|
||||||
|
|
||||||
|
# else /* unknown architecture */
|
||||||
|
# define ARCHITECTURE_ID ""
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# elif defined(__ADSPSHARC__)
|
||||||
|
# define ARCHITECTURE_ID "SHARC"
|
||||||
|
|
||||||
|
# elif defined(__ADSPBLACKFIN__)
|
||||||
|
# define ARCHITECTURE_ID "Blackfin"
|
||||||
|
|
||||||
|
#elif defined(__TASKING__)
|
||||||
|
|
||||||
|
# if defined(__CTC__) || defined(__CPTC__)
|
||||||
|
# define ARCHITECTURE_ID "TriCore"
|
||||||
|
|
||||||
|
# elif defined(__CMCS__)
|
||||||
|
# define ARCHITECTURE_ID "MCS"
|
||||||
|
|
||||||
|
# elif defined(__CARM__)
|
||||||
|
# define ARCHITECTURE_ID "ARM"
|
||||||
|
|
||||||
|
# elif defined(__CARC__)
|
||||||
|
# define ARCHITECTURE_ID "ARC"
|
||||||
|
|
||||||
|
# elif defined(__C51__)
|
||||||
|
# define ARCHITECTURE_ID "8051"
|
||||||
|
|
||||||
|
# elif defined(__CPCP__)
|
||||||
|
# define ARCHITECTURE_ID "PCP"
|
||||||
|
|
||||||
|
# else
|
||||||
|
# define ARCHITECTURE_ID ""
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
# define ARCHITECTURE_ID
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Convert integer to decimal digit literals. */
|
||||||
|
#define DEC(n) \
|
||||||
|
('0' + (((n) / 10000000)%10)), \
|
||||||
|
('0' + (((n) / 1000000)%10)), \
|
||||||
|
('0' + (((n) / 100000)%10)), \
|
||||||
|
('0' + (((n) / 10000)%10)), \
|
||||||
|
('0' + (((n) / 1000)%10)), \
|
||||||
|
('0' + (((n) / 100)%10)), \
|
||||||
|
('0' + (((n) / 10)%10)), \
|
||||||
|
('0' + ((n) % 10))
|
||||||
|
|
||||||
|
/* Convert integer to hex digit literals. */
|
||||||
|
#define HEX(n) \
|
||||||
|
('0' + ((n)>>28 & 0xF)), \
|
||||||
|
('0' + ((n)>>24 & 0xF)), \
|
||||||
|
('0' + ((n)>>20 & 0xF)), \
|
||||||
|
('0' + ((n)>>16 & 0xF)), \
|
||||||
|
('0' + ((n)>>12 & 0xF)), \
|
||||||
|
('0' + ((n)>>8 & 0xF)), \
|
||||||
|
('0' + ((n)>>4 & 0xF)), \
|
||||||
|
('0' + ((n) & 0xF))
|
||||||
|
|
||||||
|
/* Construct a string literal encoding the version number. */
|
||||||
|
#ifdef COMPILER_VERSION
|
||||||
|
char const* info_version = "INFO" ":" "compiler_version[" COMPILER_VERSION "]";
|
||||||
|
|
||||||
|
/* Construct a string literal encoding the version number components. */
|
||||||
|
#elif defined(COMPILER_VERSION_MAJOR)
|
||||||
|
char const info_version[] = {
|
||||||
|
'I', 'N', 'F', 'O', ':',
|
||||||
|
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
|
||||||
|
COMPILER_VERSION_MAJOR,
|
||||||
|
# ifdef COMPILER_VERSION_MINOR
|
||||||
|
'.', COMPILER_VERSION_MINOR,
|
||||||
|
# ifdef COMPILER_VERSION_PATCH
|
||||||
|
'.', COMPILER_VERSION_PATCH,
|
||||||
|
# ifdef COMPILER_VERSION_TWEAK
|
||||||
|
'.', COMPILER_VERSION_TWEAK,
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
']','\0'};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Construct a string literal encoding the internal version number. */
|
||||||
|
#ifdef COMPILER_VERSION_INTERNAL
|
||||||
|
char const info_version_internal[] = {
|
||||||
|
'I', 'N', 'F', 'O', ':',
|
||||||
|
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_',
|
||||||
|
'i','n','t','e','r','n','a','l','[',
|
||||||
|
COMPILER_VERSION_INTERNAL,']','\0'};
|
||||||
|
#elif defined(COMPILER_VERSION_INTERNAL_STR)
|
||||||
|
char const* info_version_internal = "INFO" ":" "compiler_version_internal[" COMPILER_VERSION_INTERNAL_STR "]";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Construct a string literal encoding the version number components. */
|
||||||
|
#ifdef SIMULATE_VERSION_MAJOR
|
||||||
|
char const info_simulate_version[] = {
|
||||||
|
'I', 'N', 'F', 'O', ':',
|
||||||
|
's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[',
|
||||||
|
SIMULATE_VERSION_MAJOR,
|
||||||
|
# ifdef SIMULATE_VERSION_MINOR
|
||||||
|
'.', SIMULATE_VERSION_MINOR,
|
||||||
|
# ifdef SIMULATE_VERSION_PATCH
|
||||||
|
'.', SIMULATE_VERSION_PATCH,
|
||||||
|
# ifdef SIMULATE_VERSION_TWEAK
|
||||||
|
'.', SIMULATE_VERSION_TWEAK,
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
']','\0'};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Construct the string literal in pieces to prevent the source from
|
||||||
|
getting matched. Store it in a pointer rather than an array
|
||||||
|
because some compilers will just produce instructions to fill the
|
||||||
|
array rather than assigning a pointer to a static array. */
|
||||||
|
char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
|
||||||
|
char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define CXX_STD_98 199711L
|
||||||
|
#define CXX_STD_11 201103L
|
||||||
|
#define CXX_STD_14 201402L
|
||||||
|
#define CXX_STD_17 201703L
|
||||||
|
#define CXX_STD_20 202002L
|
||||||
|
#define CXX_STD_23 202302L
|
||||||
|
|
||||||
|
#if defined(__INTEL_COMPILER) && defined(_MSVC_LANG)
|
||||||
|
# if _MSVC_LANG > CXX_STD_17
|
||||||
|
# define CXX_STD _MSVC_LANG
|
||||||
|
# elif _MSVC_LANG == CXX_STD_17 && defined(__cpp_aggregate_paren_init)
|
||||||
|
# define CXX_STD CXX_STD_20
|
||||||
|
# elif _MSVC_LANG > CXX_STD_14 && __cplusplus > CXX_STD_17
|
||||||
|
# define CXX_STD CXX_STD_20
|
||||||
|
# elif _MSVC_LANG > CXX_STD_14
|
||||||
|
# define CXX_STD CXX_STD_17
|
||||||
|
# elif defined(__INTEL_CXX11_MODE__) && defined(__cpp_aggregate_nsdmi)
|
||||||
|
# define CXX_STD CXX_STD_14
|
||||||
|
# elif defined(__INTEL_CXX11_MODE__)
|
||||||
|
# define CXX_STD CXX_STD_11
|
||||||
|
# else
|
||||||
|
# define CXX_STD CXX_STD_98
|
||||||
|
# endif
|
||||||
|
#elif defined(_MSC_VER) && defined(_MSVC_LANG)
|
||||||
|
# if _MSVC_LANG > __cplusplus
|
||||||
|
# define CXX_STD _MSVC_LANG
|
||||||
|
# else
|
||||||
|
# define CXX_STD __cplusplus
|
||||||
|
# endif
|
||||||
|
#elif defined(__NVCOMPILER)
|
||||||
|
# if __cplusplus == CXX_STD_17 && defined(__cpp_aggregate_paren_init)
|
||||||
|
# define CXX_STD CXX_STD_20
|
||||||
|
# else
|
||||||
|
# define CXX_STD __cplusplus
|
||||||
|
# endif
|
||||||
|
#elif defined(__INTEL_COMPILER) || defined(__PGI)
|
||||||
|
# if __cplusplus == CXX_STD_11 && defined(__cpp_namespace_attributes)
|
||||||
|
# define CXX_STD CXX_STD_17
|
||||||
|
# elif __cplusplus == CXX_STD_11 && defined(__cpp_aggregate_nsdmi)
|
||||||
|
# define CXX_STD CXX_STD_14
|
||||||
|
# else
|
||||||
|
# define CXX_STD __cplusplus
|
||||||
|
# endif
|
||||||
|
#elif (defined(__IBMCPP__) || defined(__ibmxl__)) && defined(__linux__)
|
||||||
|
# if __cplusplus == CXX_STD_11 && defined(__cpp_aggregate_nsdmi)
|
||||||
|
# define CXX_STD CXX_STD_14
|
||||||
|
# else
|
||||||
|
# define CXX_STD __cplusplus
|
||||||
|
# endif
|
||||||
|
#elif __cplusplus == 1 && defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
# define CXX_STD CXX_STD_11
|
||||||
|
#else
|
||||||
|
# define CXX_STD __cplusplus
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char* info_language_standard_default = "INFO" ":" "standard_default["
|
||||||
|
#if CXX_STD > CXX_STD_23
|
||||||
|
"26"
|
||||||
|
#elif CXX_STD > CXX_STD_20
|
||||||
|
"23"
|
||||||
|
#elif CXX_STD > CXX_STD_17
|
||||||
|
"20"
|
||||||
|
#elif CXX_STD > CXX_STD_14
|
||||||
|
"17"
|
||||||
|
#elif CXX_STD > CXX_STD_11
|
||||||
|
"14"
|
||||||
|
#elif CXX_STD >= CXX_STD_11
|
||||||
|
"11"
|
||||||
|
#else
|
||||||
|
"98"
|
||||||
|
#endif
|
||||||
|
"]";
|
||||||
|
|
||||||
|
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
|
||||||
|
#if (defined(__clang__) || defined(__GNUC__) || defined(__xlC__) || \
|
||||||
|
defined(__TI_COMPILER_VERSION__)) && \
|
||||||
|
!defined(__STRICT_ANSI__)
|
||||||
|
"ON"
|
||||||
|
#else
|
||||||
|
"OFF"
|
||||||
|
#endif
|
||||||
|
"]";
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
int require = 0;
|
||||||
|
require += info_compiler[argc];
|
||||||
|
require += info_platform[argc];
|
||||||
|
require += info_arch[argc];
|
||||||
|
#ifdef COMPILER_VERSION_MAJOR
|
||||||
|
require += info_version[argc];
|
||||||
|
#endif
|
||||||
|
#ifdef COMPILER_VERSION_INTERNAL
|
||||||
|
require += info_version_internal[argc];
|
||||||
|
#endif
|
||||||
|
#ifdef SIMULATE_ID
|
||||||
|
require += info_simulate[argc];
|
||||||
|
#endif
|
||||||
|
#ifdef SIMULATE_VERSION_MAJOR
|
||||||
|
require += info_simulate_version[argc];
|
||||||
|
#endif
|
||||||
|
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
|
||||||
|
require += info_cray[argc];
|
||||||
|
#endif
|
||||||
|
require += info_language_standard_default[argc];
|
||||||
|
require += info_language_extensions_default[argc];
|
||||||
|
(void)argv;
|
||||||
|
return require;
|
||||||
|
}
|
414
main.cpp
414
main.cpp
|
@ -1,395 +1,53 @@
|
||||||
/*
|
#include "Environment/Maze.h"
|
||||||
* Ein verbessertes Labyrinth-Spiel
|
#include "Environment/Game.h"
|
||||||
* Autor: Fritz Bökler (fboekler@uos.de)
|
#include "Exceptions/MalformedMaze.h"
|
||||||
* Datum: 02.12.2024
|
#include "Util/GameState.h"
|
||||||
* MIT Lizenz
|
|
||||||
*
|
|
||||||
* In diesem Spiel versucht eine SpielerIn (S) das Ziel (Z) zu erreichen.
|
|
||||||
* Das Labyrinth wird ueber die Konsole (cout) ausgegeben, die Eingabe erfolgt ebenfalls
|
|
||||||
* zeilengepuffert ueber die Konsole (cin).
|
|
||||||
*
|
|
||||||
* Das Labyrinth enthält die folgenden Zeichen:
|
|
||||||
* . Leeres Feld
|
|
||||||
* # Wand (nicht begehbar)
|
|
||||||
* Z Ziel
|
|
||||||
* S SpielerIn (wird nicht im Labyrint selbst gespeichert)
|
|
||||||
* K Schluessel
|
|
||||||
* T Tür
|
|
||||||
* A Geist
|
|
||||||
*
|
|
||||||
* Eine SpielerIn hat eine Anzahl an Schlüsseln. Diese Anzahl wird beim Erreichen eines
|
|
||||||
* K-Feldes erhöht und beim Erreichen eines T-Feldes reduziert. Eine Tür kann nur durchschritten
|
|
||||||
* werden, wenn die SpielerIn mindestens einen Schluessel besitzt. Ein aufgenommener Schluessel
|
|
||||||
* verschwindet (wird zu .), ebenso wie eine durchschrittene Tuer.
|
|
||||||
*
|
|
||||||
* Die folgenden Eingaben sind gültig:
|
|
||||||
* w - nach oben bewegen
|
|
||||||
* a - nach links bewegen
|
|
||||||
* s - nach unten bewegen
|
|
||||||
* d - nach rechts bewegen
|
|
||||||
* q - Spiel beenden
|
|
||||||
*
|
|
||||||
* Das Labyrnith wird zu Beginn eingegeben.
|
|
||||||
* Syntax: <Zeilen> <Spalte> <Labyrinth-Zeichen> <Spieler Zeile> <Spieler Spalte>
|
|
||||||
* <Zeilen>: 1 bis 20
|
|
||||||
* <Spalten>: 1 bis 20
|
|
||||||
* <Labyrint-Zeichen>: Eine Folge von <Zeilen> * <Spalten> vielen Zeichen aus {., #, Z, K, T, A}
|
|
||||||
* <Spieler Zeile>: 0 bis <Zeilen> - 1
|
|
||||||
* <Spieler Spalte>: 0 bis <Spalten> - 1
|
|
||||||
*
|
|
||||||
* Ein Beispiellabyrinth: 7 7 ...#....#...#T..####Z#....##K###.#......A#.###### 0 4
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "std_lib_inc.h"
|
using game::Maze;
|
||||||
|
using game::Game;
|
||||||
|
using game::GameState;
|
||||||
|
|
||||||
// Exception fuer nicht erlaubte Bewegungen
|
using game_exceptions::MalformedMaze;
|
||||||
class BadMovement {};
|
|
||||||
|
|
||||||
// Exception fuer unbekannte Eingaben
|
// Ein Programm, welches dir erlaubt ein Labyrinth zu erkunden mit 'w', 'a', 's', und 'd'.
|
||||||
class UnknownInput {};
|
|
||||||
|
|
||||||
// Exception fuer eine falsche Labyrinth-Eingabe
|
void print_exit_message_based_on_state(const GameState& state);
|
||||||
class BadMaze {};
|
|
||||||
|
|
||||||
// Klasse, die eine SpielerIn kapselt
|
|
||||||
class Player
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
int no_keys; // Anzahl der Schlüssel der SpielerIn
|
|
||||||
vector<int> position; // Aktuelle Position der SpielerIn im Labyrinth
|
|
||||||
};
|
|
||||||
|
|
||||||
// Klasse, die das Labyrinth kapselt
|
|
||||||
class Maze
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
int rows; // Anzahl der Zeilen des Labyrinths
|
|
||||||
int cols; // Anzahl der Spalten des Labyrinths
|
|
||||||
vector<vector<char>> data; // Labyrinth-Daten (erst Zeilen dann Spalten)
|
|
||||||
vector<int> player_start_position; // Startposition der SpielerIn, so wie es in der Übergabe steht
|
|
||||||
};
|
|
||||||
|
|
||||||
// Fasst Labyrinth und Spieler zu einem Spiel-Status zusammen
|
|
||||||
class GameState
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Maze maze; // Das Labyrinth
|
|
||||||
Player player; // Die SpielerIn
|
|
||||||
bool exit; // Wurde 'q' gerdückt?
|
|
||||||
bool hit_ghost; // Wurde ein Geist getroffen?
|
|
||||||
};
|
|
||||||
|
|
||||||
// Funktion zur Anzeige des Spielfeldes
|
|
||||||
void display_maze(GameState game_state)
|
|
||||||
{
|
|
||||||
const int player_row = game_state.player.position[0];
|
|
||||||
const int player_col = game_state.player.position[1];
|
|
||||||
|
|
||||||
//cout << "\033[H\033[J"; // ANSI Escape Code zum Loeschen des Bildschirms
|
|
||||||
for(int i = 0; i < game_state.maze.rows; i++)
|
|
||||||
{
|
|
||||||
for(int j = 0; j < game_state.maze.cols; j++)
|
|
||||||
{
|
|
||||||
if(i == player_row && j == player_col)
|
|
||||||
{
|
|
||||||
cout << 'S';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cout << game_state.maze.data[i][j];
|
|
||||||
}
|
|
||||||
cout << " ";
|
|
||||||
}
|
|
||||||
cout << '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Funktion zur Umrechnung eines Kommandos zu einer neuen Position
|
|
||||||
// Vorbedingung: direction muss aus {w, s, a, d} kommen.
|
|
||||||
vector<int> new_position_by_direction(vector<int> player_position, char direction)
|
|
||||||
{
|
|
||||||
const int row = player_position[0];
|
|
||||||
const int col = player_position[1];
|
|
||||||
|
|
||||||
switch(direction)
|
|
||||||
{
|
|
||||||
case 'w':
|
|
||||||
return {row - 1, col};
|
|
||||||
case 's':
|
|
||||||
return {row + 1, col};
|
|
||||||
case 'a':
|
|
||||||
return {row, col - 1};
|
|
||||||
case 'd':
|
|
||||||
return {row, col + 1};
|
|
||||||
default:
|
|
||||||
assert(false, "new_position_by_direction: invalid direction, assumes direction is one of {w, s, a, d}.");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fuehrt Aktionen des Spieler-Feldes aus
|
|
||||||
// Vorbedingung: Wenn das Feld eine Tuer ist, muss mindestens ein Schluessel zur Verfuegung stehen
|
|
||||||
GameState process_tile_action(GameState game_state)
|
|
||||||
{
|
|
||||||
const int row = game_state.player.position[0];
|
|
||||||
const int col = game_state.player.position[1];
|
|
||||||
|
|
||||||
assert(game_state.maze.data[row][col] != 'T' || game_state.player.no_keys > 0,
|
|
||||||
"process_tile_action(...) assumes enough keys are there when approaching a door.");
|
|
||||||
|
|
||||||
if(game_state.maze.data[row][col] == 'K')
|
|
||||||
{
|
|
||||||
++game_state.player.no_keys;
|
|
||||||
game_state.maze.data[row][col] = '.';
|
|
||||||
}
|
|
||||||
else if(game_state.maze.data[row][col] == 'T')
|
|
||||||
{
|
|
||||||
--game_state.player.no_keys;
|
|
||||||
game_state.maze.data[row][col] = '.';
|
|
||||||
}
|
|
||||||
else if(game_state.maze.data[row][col] == 'A')
|
|
||||||
{
|
|
||||||
game_state.hit_ghost = true;
|
|
||||||
}
|
|
||||||
return game_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gibt true zurueck gdw. die Position begehbar ist
|
|
||||||
bool position_is_walkable(vector<int> position, GameState game_state)
|
|
||||||
{
|
|
||||||
const int row = position[0];
|
|
||||||
const int col = position[1];
|
|
||||||
|
|
||||||
if(row < 0 || col < 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(row >= game_state.maze.rows || col >= game_state.maze.cols)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(game_state.maze.data[row][col] == '#')
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(game_state.maze.data[row][col] == 'T' && game_state.player.no_keys == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Funktion zur Bewegung der SpielerIn
|
|
||||||
GameState move_player(GameState game_state, char direction)
|
|
||||||
{
|
|
||||||
vector<int> potential_new_position = new_position_by_direction(game_state.player.position, direction);
|
|
||||||
|
|
||||||
if(!position_is_walkable(potential_new_position, game_state))
|
|
||||||
{
|
|
||||||
throw BadMovement {};
|
|
||||||
}
|
|
||||||
|
|
||||||
game_state.player.position = potential_new_position;
|
|
||||||
return process_tile_action(game_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gibt eine kurze Hilfe aus
|
|
||||||
void display_help()
|
|
||||||
{
|
|
||||||
cout << "Willkommen zum Labyrinth-Spiel!\n";
|
|
||||||
cout << "Ziel des Spiels: Finden Sie den Weg vom Startpunkt (S) zum Ziel (Z).\n";
|
|
||||||
cout << "Spielfeld-Erklaerung:\n";
|
|
||||||
cout << "S - Startpunkt: Hier beginnt die SpielerIn.\n";
|
|
||||||
cout << "Z - Ziel: Erreichen Sie diesen Punkt, um das Spiel zu gewinnen.\n";
|
|
||||||
cout << "# - Wand: Diese Felder sind nicht begehbar.\n";
|
|
||||||
cout << "K - Schluessel: Hier können Sie einen Schluessel aufsammeln, um eine Tuer zu oeffnen.\n";
|
|
||||||
cout << "T - Tuer: Unbegehbares Feld, ausser, Sie haben einen Schluessel. Beim Durchschreiten wird ein Schluessel verbraucht.\n";
|
|
||||||
cout << "A - Geist: Ein Geist im Labyrinth. Stehen die SpielerIn auf dem selben Feld, verlieren Sie das Spiel!\n";
|
|
||||||
cout << ". - Leeres Feld: Diese Felder koennen betreten werden.\n";
|
|
||||||
cout << "\nSteuerung:\n";
|
|
||||||
cout << "w - Nach oben bewegen\n";
|
|
||||||
cout << "a - Nach links bewegen\n";
|
|
||||||
cout << "s - Nach unten bewegen\n";
|
|
||||||
cout << "d - Nach rechts bewegen\n";
|
|
||||||
cout << "q - Spiel beenden\n";
|
|
||||||
cout << "Nach jeder Befehlseingabe muss die Eingabetaste (Enter) gedrueckt werden, um sich zu bewegen.\n";
|
|
||||||
cout << "\nViel Erfolg im Labyrinth!\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reagiert auf das eingegebene Kommando und gibt an die jeweilige Funktion
|
|
||||||
// ab, die sich um genau dieses Kommando kuemmert.
|
|
||||||
GameState process_input(GameState game_state, char input)
|
|
||||||
{
|
|
||||||
switch(input)
|
|
||||||
{
|
|
||||||
case 'w':
|
|
||||||
case 's':
|
|
||||||
case 'a':
|
|
||||||
case 'd':
|
|
||||||
return move_player(game_state, input);
|
|
||||||
case 'h':
|
|
||||||
case 'H':
|
|
||||||
display_help();
|
|
||||||
break;
|
|
||||||
case 'q':
|
|
||||||
game_state.exit = true;
|
|
||||||
return game_state;
|
|
||||||
default:
|
|
||||||
throw UnknownInput{};
|
|
||||||
}
|
|
||||||
return game_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gibt true zurueck, wenn das Ziel erreicht wurde
|
|
||||||
bool reached_goal(GameState game_state)
|
|
||||||
{
|
|
||||||
return game_state.maze.data[game_state.player.position[0]][game_state.player.position[1]] == 'Z';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gibt true zurueck gdw der Geist getroffen wurde
|
|
||||||
bool hit_ghost(GameState game_state)
|
|
||||||
{
|
|
||||||
return game_state.hit_ghost;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gibt true zurueck gdw. das Spiel zuende ist
|
|
||||||
bool is_end_condition(GameState game_state)
|
|
||||||
{
|
|
||||||
return reached_goal(game_state) || hit_ghost(game_state) || game_state.exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Die Hauptschleife des Spiels
|
|
||||||
GameState game_loop(GameState game_state)
|
|
||||||
{
|
|
||||||
char input;
|
|
||||||
while(cin && !is_end_condition(game_state))
|
|
||||||
{
|
|
||||||
assert(game_state.player.no_keys >= 0,
|
|
||||||
"Player has a negative number of keys.");
|
|
||||||
|
|
||||||
display_maze(game_state);
|
|
||||||
|
|
||||||
cin >> input;
|
|
||||||
if(cin)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
game_state = process_input(game_state, input);
|
|
||||||
}
|
|
||||||
catch(BadMovement&)
|
|
||||||
{
|
|
||||||
cout << "Bewegung nicht moeglich!\n";
|
|
||||||
}
|
|
||||||
catch(UnknownInput&)
|
|
||||||
{
|
|
||||||
cout << "Diese Eingabe kenne ich nicht. Gib 'h' ein, um eine Hilfe zu erhalten.\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return game_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Liest ein integer von der Eingabe.
|
|
||||||
// Vorbedingung: cin ist in Ordnung
|
|
||||||
int read_int()
|
|
||||||
{
|
|
||||||
int integer;
|
|
||||||
cin >> integer;
|
|
||||||
if(!cin) {throw BadMaze{};}
|
|
||||||
return integer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Liest die Labyrinth-Daten ein.
|
|
||||||
// Vorbedingung: cin ist ok.
|
|
||||||
vector<vector<char>> read_maze_data(int rows, int cols)
|
|
||||||
{
|
|
||||||
vector<vector<char>> maze_data(rows);
|
|
||||||
char ch;
|
|
||||||
for(int i = 0; i < rows * cols; ++i)
|
|
||||||
{
|
|
||||||
cin >> ch;
|
|
||||||
if(!cin) {throw BadMaze {};}
|
|
||||||
if(!(ch == '#' || ch == 'T' || ch == 'A' || ch == '.' || ch == 'K' || ch == 'Z'))
|
|
||||||
{
|
|
||||||
throw BadMaze {};
|
|
||||||
}
|
|
||||||
|
|
||||||
maze_data[i / cols].push_back(ch);
|
|
||||||
}
|
|
||||||
return maze_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Liest das Labyrinth von der Konsole nach der Formatdefinition aus der Aufgabe
|
|
||||||
Maze read_maze()
|
|
||||||
{
|
|
||||||
int rows = read_int();
|
|
||||||
int cols = read_int();
|
|
||||||
|
|
||||||
if(rows < 1 || cols < 1 || rows > 20 || cols > 20)
|
|
||||||
{
|
|
||||||
throw BadMaze {};
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<vector<char>> labyrinth_data = read_maze_data(rows, cols);
|
|
||||||
|
|
||||||
int player_row = read_int();
|
|
||||||
int player_col = read_int();
|
|
||||||
|
|
||||||
if(player_row < 0 || player_row >= rows || player_col < 0 || player_col >= cols)
|
|
||||||
{
|
|
||||||
throw BadMaze {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if(labyrinth_data[player_row][player_col] != '.')
|
|
||||||
{
|
|
||||||
throw BadMaze {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {rows, cols, labyrinth_data, {player_row, player_col}};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialisiert das Labyrinth-Objekt
|
|
||||||
GameState initialize()
|
|
||||||
{
|
|
||||||
Maze maze = read_maze();
|
|
||||||
Player player{0, maze.player_start_position};
|
|
||||||
|
|
||||||
return GameState {maze, player, false, false};
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
activateAssertions();
|
GameState state = GameState::RUNNING;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
GameState game_state = initialize();
|
Maze maze = Maze::request_maze_from_user();
|
||||||
|
|
||||||
game_state = game_loop(game_state);
|
Game game = Game(maze);
|
||||||
|
|
||||||
if(reached_goal(game_state))
|
game.run_game();
|
||||||
{
|
|
||||||
display_maze(game_state);
|
state = game.get_state();
|
||||||
cout << "Ziel erreicht! Herzlichen Glueckwunsch!\n";
|
|
||||||
}
|
|
||||||
else if(hit_ghost(game_state))
|
|
||||||
{
|
|
||||||
cout << "Sie haben einen Geist getroffen! Game Over!\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cout << "Schoenen Tag noch!\n";
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
catch(BadMaze&)
|
catch (MalformedMaze& _)
|
||||||
{
|
{
|
||||||
cout << "Fehler beim Einlesen des Labyrinths.\n";
|
cout << "Fehler beim Einlesen des Labyrinths.\n";
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
catch(...)
|
|
||||||
{
|
print_exit_message_based_on_state(state);
|
||||||
cout << "Unbekannter Fehler!\n";
|
|
||||||
return 1;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Schriebe eine Nachricht in die Konsole wenn das Programm beendet wird
|
||||||
|
/// @param state Der Spielzustand als das Programm beendet wurde
|
||||||
|
void print_exit_message_based_on_state(const GameState& state) {
|
||||||
|
switch (state){
|
||||||
|
case GameState::QUITTING:
|
||||||
|
cout << "Schoenen Tag noch!" << "\n";
|
||||||
|
break;
|
||||||
|
case GameState::HIT_BY_GHOST:
|
||||||
|
cout << "Sie haben einen Geist getroffen! Game Over!\n";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,15 @@ namespace std
|
||||||
{
|
{
|
||||||
using size_type = typename std::vector<T>::size_type;
|
using size_type = typename std::vector<T>::size_type;
|
||||||
|
|
||||||
|
/* #ifdef _MSC_VER
|
||||||
|
// microsoft doesn't yet support C++11 inheriting constructors
|
||||||
|
Vector() { }
|
||||||
|
explicit Vector(size_type n) :std::vector<T>(n) {}
|
||||||
|
Vector(size_type n, const T& v) :std::vector<T>(n, v) {}
|
||||||
|
template <class I>
|
||||||
|
Vector(I first, I last) : std::vector<T>(first, last) {}
|
||||||
|
Vector(initializer_list<T> list) : std::vector<T>(list) {}
|
||||||
|
*/
|
||||||
using std::vector<T>::vector; // inheriting constructor
|
using std::vector<T>::vector; // inheriting constructor
|
||||||
|
|
||||||
T &operator[](unsigned int i) // rather than return at(i);
|
T &operator[](unsigned int i) // rather than return at(i);
|
||||||
|
|
Loading…
Add table
Reference in a new issue