1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-03-20 03:29:47 +00:00

Standardises the static analyser on std::vector and slightly widens passageway to a machine.

The SDL target would now be fooled by a hypothetical multi-target, the Mac not yet.
This commit is contained in:
Thomas Harte 2018-01-23 22:18:16 -05:00
parent 6a112edc18
commit d360b2c62d
32 changed files with 74 additions and 75 deletions

@ -18,15 +18,16 @@
#include "TypedDynamicMachine.hpp"
::Machine::DynamicMachine *::Machine::MachineForTarget(const StaticAnalyser::Target &target) {
switch(target.machine) {
::Machine::DynamicMachine *::Machine::MachineForTargets(const std::vector<StaticAnalyser::Target> &targets) {
// TODO: deal with target lists containing more than one machine.
switch(targets.front().machine) {
case StaticAnalyser::Target::AmstradCPC: return new TypedDynamicMachine<AmstradCPC::Machine>(AmstradCPC::Machine::AmstradCPC());
case StaticAnalyser::Target::Atari2600: return new TypedDynamicMachine<Atari2600::Machine>(Atari2600::Machine::Atari2600());
case StaticAnalyser::Target::Electron: return new TypedDynamicMachine<Electron::Machine>(Electron::Machine::Electron());
case StaticAnalyser::Target::MSX: return new TypedDynamicMachine<MSX::Machine>(MSX::Machine::MSX());
case StaticAnalyser::Target::Oric: return new TypedDynamicMachine<Oric::Machine>(Oric::Machine::Oric());
case StaticAnalyser::Target::Vic20: return new TypedDynamicMachine<Commodore::Vic20::Machine>(Commodore::Vic20::Machine::Vic20());
case StaticAnalyser::Target::ZX8081: return new TypedDynamicMachine<ZX8081::Machine>(ZX8081::Machine::ZX8081(target));
case StaticAnalyser::Target::ZX8081: return new TypedDynamicMachine<ZX8081::Machine>(ZX8081::Machine::ZX8081(targets.front()));
default: return nullptr;
}

@ -20,6 +20,7 @@
#include <map>
#include <string>
#include <vector>
namespace Machine {
@ -38,10 +39,10 @@ struct DynamicMachine {
/*!
Allocates an instance of DynamicMachine holding a machine that can
receive the supplied target. The machine has been allocated on the heap.
It is the caller's responsibility to delete the class when finished.
receive the supplied static analyser result. The machine has been allocated
on the heap. It is the caller's responsibility to delete the class when finished.
*/
DynamicMachine *MachineForTarget(const StaticAnalyser::Target &target);
DynamicMachine *MachineForTargets(const std::vector<StaticAnalyser::Target> &target);
/*!
Returns a short string name for the machine identified by the target,

@ -166,6 +166,7 @@
4B2C45421E3C3896002A2389 /* cartridge.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B2C45411E3C3896002A2389 /* cartridge.png */; };
4B2E2D9A1C3A06EC00138695 /* Atari2600.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D971C3A06EC00138695 /* Atari2600.cpp */; };
4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D9B1C3A070400138695 /* Electron.cpp */; };
4B2F67F12018312F00251FB5 /* Z80.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9C9D731FF81CC00030A129 /* Z80.cpp */; };
4B30512D1D989E2200B4FED8 /* Drive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B30512B1D989E2200B4FED8 /* Drive.cpp */; };
4B3051301D98ACC600B4FED8 /* Plus3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B30512E1D98ACC600B4FED8 /* Plus3.cpp */; };
4B322E011F5A2990004EB04C /* Z80AllRAM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B322DFD1F5A2981004EB04C /* Z80AllRAM.cpp */; };
@ -2848,13 +2849,13 @@
4BF1354A1D6D2C300054B2EA /* StaticAnalyser.cpp */,
4BF1354B1D6D2C300054B2EA /* StaticAnalyser.hpp */,
4BD14B121D7462810088EAD6 /* Acorn */,
4B38F3451F2EB41800D9235D /* AmstradCPC */,
4BA799961D8B65730045123D /* Atari */,
4BC830D21D6E7C6D0000A26F /* Commodore */,
4B5A12581DD55873007A2231 /* Disassembler */,
4B0E04F01FC9E89100F43484 /* MSX */,
4BCF1FAC1DADD41F0039D2E7 /* Oric */,
4B14978C1EE4AC6200CE2596 /* ZX80/81 */,
4B38F3451F2EB41800D9235D /* AmstradCPC */,
4B0E04F01FC9E89100F43484 /* MSX */,
);
name = StaticAnalyser;
sourceTree = "<group>";
@ -3380,6 +3381,7 @@
4B055A881FAE85530060FFFF /* 6502.cpp in Sources */,
4B055AED1FAE9BA20060FFFF /* Z80Storage.cpp in Sources */,
4B055AD11FAE9B030060FFFF /* Video.cpp in Sources */,
4B2F67F12018312F00251FB5 /* Z80.cpp in Sources */,
4B055AA21FAE85DA0060FFFF /* SSD.cpp in Sources */,
4BEBFB4E2002C4BF000708CC /* MSXDSK.cpp in Sources */,
4B055ADD1FAE9B460060FFFF /* i8272.cpp in Sources */,

@ -25,15 +25,14 @@
#import "Clock_Signal-Swift.h"
@implementation CSStaticAnalyser {
StaticAnalyser::Target _target;
std::vector<StaticAnalyser::Target> _targets;
}
- (instancetype)initWithFileAtURL:(NSURL *)url {
self = [super init];
if(self) {
std::list<StaticAnalyser::Target> targets = StaticAnalyser::GetTargets([url fileSystemRepresentation]);
if(!targets.size()) return nil;
_target = targets.front();
_targets = StaticAnalyser::GetTargets([url fileSystemRepresentation]);
if(!_targets.size()) return nil;
// TODO: can this better be supplied by the analyser?
_displayName = [[url pathComponents] lastObject];
@ -42,7 +41,7 @@
}
- (NSString *)optionsPanelNibName {
switch(_target.machine) {
switch(_targets.front().machine) {
case StaticAnalyser::Target::AmstradCPC: return nil;
case StaticAnalyser::Target::Atari2600: return @"Atari2600Options";
case StaticAnalyser::Target::Electron: return @"QuickLoadCompositeOptions";
@ -55,20 +54,20 @@
}
- (CSMachine *)newMachine {
switch(_target.machine) {
switch(_targets.front().machine) {
case StaticAnalyser::Target::AmstradCPC: return [[CSAmstradCPC alloc] init];
case StaticAnalyser::Target::Atari2600: return [[CSAtari2600 alloc] init];
case StaticAnalyser::Target::Electron: return [[CSElectron alloc] init];
case StaticAnalyser::Target::MSX: return [[CSMSX alloc] init];
case StaticAnalyser::Target::Oric: return [[CSOric alloc] init];
case StaticAnalyser::Target::Vic20: return [[CSVic20 alloc] init];
case StaticAnalyser::Target::ZX8081: return [[CSZX8081 alloc] initWithIntendedTarget:_target];
case StaticAnalyser::Target::ZX8081: return [[CSZX8081 alloc] initWithIntendedTarget:_targets.front()];
default: return nil;
}
}
- (void)applyToMachine:(CSMachine *)machine {
[machine applyTarget:_target];
[machine applyTarget:_targets.front()];
}
@end

@ -250,7 +250,7 @@ int main(int argc, char *argv[]) {
}
// Determine the machine for the supplied file.
std::list<StaticAnalyser::Target> targets = StaticAnalyser::GetTargets(arguments.file_name.c_str());
std::vector<StaticAnalyser::Target> targets = StaticAnalyser::GetTargets(arguments.file_name.c_str());
if(targets.empty()) {
std::cerr << "Cannot open " << arguments.file_name << std::endl;
return -1;
@ -262,7 +262,7 @@ int main(int argc, char *argv[]) {
SpeakerDelegate speaker_delegate;
// Create and configure a machine.
std::unique_ptr<::Machine::DynamicMachine> machine(::Machine::MachineForTarget(targets.front()));
std::unique_ptr<::Machine::DynamicMachine> machine(::Machine::MachineForTargets(targets));
updater.set_clock_rate(machine->crt_machine()->get_clock_rate());
crt_delegate.best_effort_updater = &updater;

@ -41,9 +41,7 @@ std::unique_ptr<Catalogue> StaticAnalyser::Acorn::GetDFSCatalogue(const std::sha
case 3: catalogue->bootOption = Catalogue::BootOption::ExecBOOT; break;
}
// DFS files are stored contiguously, and listed in descending order of distance from track 0.
// So iterating backwards implies the least amount of seeking.
for(std::size_t file_offset = final_file_offset - 8; file_offset > 0; file_offset -= 8) {
for(std::size_t file_offset = 8; file_offset < final_file_offset; file_offset += 8) {
File new_file;
char name[10];
snprintf(name, 10, "%c.%.7s", names->samples[0][file_offset + 7] & 0x7f, &names->samples[0][file_offset]);
@ -69,7 +67,7 @@ std::unique_ptr<Catalogue> StaticAnalyser::Acorn::GetDFSCatalogue(const std::sha
new_file.data.insert(new_file.data.end(), next_sector->samples[0].begin(), next_sector->samples[0].begin() + length_from_sector);
data_length -= length_from_sector;
}
if(!data_length) catalogue->files.push_front(new_file);
if(!data_length) catalogue->files.push_back(new_file);
}
return catalogue;

@ -18,7 +18,7 @@ namespace Acorn {
/// Describes a DFS- or ADFS-format catalogue(/directory) — the list of files available and the catalogue's boot option.
struct Catalogue {
std::string name;
std::list<File> files;
std::vector<File> files;
enum class BootOption {
None,
LoadBOOT,

@ -9,7 +9,6 @@
#ifndef StaticAnalyser_Acorn_File_hpp
#define StaticAnalyser_Acorn_File_hpp
#include <list>
#include <memory>
#include <string>
#include <vector>
@ -38,7 +37,7 @@ struct File {
std::vector<uint8_t> data;
};
std::list<Chunk> chunks;
std::vector<Chunk> chunks;
};
}

@ -13,9 +13,9 @@
using namespace StaticAnalyser::Acorn;
static std::list<std::shared_ptr<Storage::Cartridge::Cartridge>>
AcornCartridgesFrom(const std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> &cartridges) {
std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> acorn_cartridges;
static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
AcornCartridgesFrom(const std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>> &cartridges) {
std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>> acorn_cartridges;
for(const auto &cartridge : cartridges) {
const auto &segments = cartridge->get_segments();
@ -56,7 +56,7 @@ static std::list<std::shared_ptr<Storage::Cartridge::Cartridge>>
return acorn_cartridges;
}
void StaticAnalyser::Acorn::AddTargets(const Media &media, std::list<Target> &destination) {
void StaticAnalyser::Acorn::AddTargets(const Media &media, std::vector<Target> &destination) {
Target target;
target.machine = Target::Electron;
target.probability = 1.0; // TODO: a proper estimation
@ -70,7 +70,7 @@ void StaticAnalyser::Acorn::AddTargets(const Media &media, std::list<Target> &de
// if there are any tapes, attempt to get data from the first
if(media.tapes.size() > 0) {
std::shared_ptr<Storage::Tape::Tape> tape = media.tapes.front();
std::list<File> files = GetFiles(tape);
std::vector<File> files = GetFiles(tape);
tape->reset();
// continue if there are any files

@ -14,7 +14,7 @@
namespace StaticAnalyser {
namespace Acorn {
void AddTargets(const Media &media, std::list<Target> &destination);
void AddTargets(const Media &media, std::vector<Target> &destination);
}
}

@ -118,7 +118,7 @@ static std::unique_ptr<File> GetNextFile(std::deque<File::Chunk> &chunks) {
return file;
}
std::list<File> StaticAnalyser::Acorn::GetFiles(const std::shared_ptr<Storage::Tape::Tape> &tape) {
std::vector<File> StaticAnalyser::Acorn::GetFiles(const std::shared_ptr<Storage::Tape::Tape> &tape) {
Storage::Tape::Acorn::Parser parser;
// populate chunk list
@ -131,7 +131,7 @@ std::list<File> StaticAnalyser::Acorn::GetFiles(const std::shared_ptr<Storage::T
}
// decompose into file list
std::list<File> file_list;
std::vector<File> file_list;
while(chunk_list.size()) {
std::unique_ptr<File> next_file = GetNextFile(chunk_list);

@ -17,7 +17,7 @@
namespace StaticAnalyser {
namespace Acorn {
std::list<File> GetFiles(const std::shared_ptr<Storage::Tape::Tape> &tape);
std::vector<File> GetFiles(const std::shared_ptr<Storage::Tape::Tape> &tape);
}
}

@ -177,7 +177,7 @@ static bool CheckBootSector(const std::shared_ptr<Storage::Disk::Disk> &disk, St
return false;
}
void StaticAnalyser::AmstradCPC::AddTargets(const Media &media, std::list<Target> &destination) {
void StaticAnalyser::AmstradCPC::AddTargets(const Media &media, std::vector<Target> &destination) {
Target target;
target.machine = Target::AmstradCPC;
target.probability = 1.0;

@ -14,7 +14,7 @@
namespace StaticAnalyser {
namespace AmstradCPC {
void AddTargets(const Media &media, std::list<Target> &destination);
void AddTargets(const Media &media, std::vector<Target> &destination);
}
}

@ -178,7 +178,7 @@ static void DeterminePagingForCartridge(StaticAnalyser::Target &target, const St
}
}
void StaticAnalyser::Atari::AddTargets(const Media &media, std::list<Target> &destination) {
void StaticAnalyser::Atari::AddTargets(const Media &media, std::vector<Target> &destination) {
// TODO: sanity checking; is this image really for an Atari 2600.
Target target;
target.machine = Target::Atari2600;

@ -14,7 +14,7 @@
namespace StaticAnalyser {
namespace Atari {
void AddTargets(const Media &media, std::list<Target> &destination);
void AddTargets(const Media &media, std::vector<Target> &destination);
}
}

@ -165,8 +165,8 @@ class CommodoreGCRParser: public Storage::Disk::Controller {
}
};
std::list<File> StaticAnalyser::Commodore::GetFiles(const std::shared_ptr<Storage::Disk::Disk> &disk) {
std::list<File> files;
std::vector<File> StaticAnalyser::Commodore::GetFiles(const std::shared_ptr<Storage::Disk::Disk> &disk) {
std::vector<File> files;
CommodoreGCRParser parser;
parser.drive->set_disk(disk);

@ -11,12 +11,12 @@
#include "../../Storage/Disk/Disk.hpp"
#include "File.hpp"
#include <list>
#include <vector>
namespace StaticAnalyser {
namespace Commodore {
std::list<File> GetFiles(const std::shared_ptr<Storage::Disk::Disk> &disk);
std::vector<File> GetFiles(const std::shared_ptr<Storage::Disk::Disk> &disk);
}
}

@ -17,9 +17,9 @@
using namespace StaticAnalyser::Commodore;
static std::list<std::shared_ptr<Storage::Cartridge::Cartridge>>
Vic20CartridgesFrom(const std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> &cartridges) {
std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> vic20_cartridges;
static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
Vic20CartridgesFrom(const std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>> &cartridges) {
std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>> vic20_cartridges;
for(const auto &cartridge : cartridges) {
const auto &segments = cartridge->get_segments();
@ -38,13 +38,13 @@ static std::list<std::shared_ptr<Storage::Cartridge::Cartridge>>
return vic20_cartridges;
}
void StaticAnalyser::Commodore::AddTargets(const Media &media, std::list<Target> &destination) {
void StaticAnalyser::Commodore::AddTargets(const Media &media, std::vector<Target> &destination) {
Target target;
target.machine = Target::Vic20; // TODO: machine estimation
target.probability = 1.0; // TODO: a proper estimation
int device = 0;
std::list<File> files;
std::vector<File> files;
bool is_disk = false;
// strip out inappropriate cartridges
@ -52,10 +52,10 @@ void StaticAnalyser::Commodore::AddTargets(const Media &media, std::list<Target>
// check disks
for(auto &disk : media.disks) {
std::list<File> disk_files = GetFiles(disk);
std::vector<File> disk_files = GetFiles(disk);
if(!disk_files.empty()) {
is_disk = true;
files.splice(files.end(), disk_files);
files.insert(files.end(), disk_files.begin(), disk_files.end());
target.media.disks.push_back(disk);
if(!device) device = 8;
}
@ -63,10 +63,10 @@ void StaticAnalyser::Commodore::AddTargets(const Media &media, std::list<Target>
// check tapes
for(auto &tape : media.tapes) {
std::list<File> tape_files = GetFiles(tape);
std::vector<File> tape_files = GetFiles(tape);
tape->reset();
if(!tape_files.empty()) {
files.splice(files.end(), tape_files);
files.insert(files.end(), tape_files.begin(), tape_files.end());
target.media.tapes.push_back(tape);
if(!device) device = 1;
}

@ -14,7 +14,7 @@
namespace StaticAnalyser {
namespace Commodore {
void AddTargets(const Media &media, std::list<Target> &destination);
void AddTargets(const Media &media, std::vector<Target> &destination);
}
}

@ -12,9 +12,9 @@
using namespace StaticAnalyser::Commodore;
std::list<File> StaticAnalyser::Commodore::GetFiles(const std::shared_ptr<Storage::Tape::Tape> &tape) {
std::vector<File> StaticAnalyser::Commodore::GetFiles(const std::shared_ptr<Storage::Tape::Tape> &tape) {
Storage::Tape::Commodore::Parser parser;
std::list<File> file_list;
std::vector<File> file_list;
std::unique_ptr<Storage::Tape::Commodore::Header> header = parser.get_next_header(tape);

@ -16,7 +16,7 @@
namespace StaticAnalyser {
namespace Commodore {
std::list<File> GetFiles(const std::shared_ptr<Storage::Tape::Tape> &tape);
std::vector<File> GetFiles(const std::shared_ptr<Storage::Tape::Tape> &tape);
}
}

@ -24,9 +24,9 @@
DEFW basic ; pointer to the start of a tokenized basicprogram, 0 if no basicprogram
DEFS 6,0 ; room reserved for future extensions
*/
static std::list<std::shared_ptr<Storage::Cartridge::Cartridge>>
MSXCartridgesFrom(const std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> &cartridges, StaticAnalyser::Target &target) {
std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> msx_cartridges;
static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
MSXCartridgesFrom(const std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>> &cartridges, StaticAnalyser::Target &target) {
std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>> msx_cartridges;
for(const auto &cartridge : cartridges) {
const auto &segments = cartridge->get_segments();
@ -200,7 +200,7 @@ static std::list<std::shared_ptr<Storage::Cartridge::Cartridge>>
return msx_cartridges;
}
void StaticAnalyser::MSX::AddTargets(const Media &media, std::list<Target> &destination) {
void StaticAnalyser::MSX::AddTargets(const Media &media, std::vector<Target> &destination) {
Target target;
// Obtain only those cartridges which it looks like an MSX would understand.

@ -14,7 +14,7 @@
namespace StaticAnalyser {
namespace MSX {
void AddTargets(const Media &media, std::list<Target> &destination);
void AddTargets(const Media &media, std::vector<Target> &destination);
}
}

@ -73,7 +73,7 @@ static int Basic11Score(const StaticAnalyser::MOS6502::Disassembly &disassembly)
return Score(disassembly, rom_functions, variable_locations);
}
void StaticAnalyser::Oric::AddTargets(const Media &media, std::list<Target> &destination) {
void StaticAnalyser::Oric::AddTargets(const Media &media, std::vector<Target> &destination) {
Target target;
target.machine = Target::Oric;
target.probability = 1.0;
@ -82,7 +82,7 @@ void StaticAnalyser::Oric::AddTargets(const Media &media, std::list<Target> &des
int basic11_votes = 0;
for(auto &tape : media.tapes) {
std::list<File> tape_files = GetFiles(tape);
std::vector<File> tape_files = GetFiles(tape);
tape->reset();
if(tape_files.size()) {
for(auto file : tape_files) {

@ -14,7 +14,7 @@
namespace StaticAnalyser {
namespace Oric {
void AddTargets(const Media &media, std::list<Target> &destination);
void AddTargets(const Media &media, std::vector<Target> &destination);
}
}

@ -11,8 +11,8 @@
using namespace StaticAnalyser::Oric;
std::list<File> StaticAnalyser::Oric::GetFiles(const std::shared_ptr<Storage::Tape::Tape> &tape) {
std::list<File> files;
std::vector<File> StaticAnalyser::Oric::GetFiles(const std::shared_ptr<Storage::Tape::Tape> &tape) {
std::vector<File> files;
Storage::Tape::Oric::Parser parser;
while(!tape->is_at_end()) {

@ -30,7 +30,7 @@ struct File {
std::vector<uint8_t> data;
};
std::list<File> GetFiles(const std::shared_ptr<Storage::Tape::Tape> &tape);
std::vector<File> GetFiles(const std::shared_ptr<Storage::Tape::Tape> &tape);
}
}

@ -139,8 +139,8 @@ Media StaticAnalyser::GetMedia(const char *file_name) {
return GetMediaAndPlatforms(file_name, throwaway);
}
std::list<Target> StaticAnalyser::GetTargets(const char *file_name) {
std::list<Target> targets;
std::vector<Target> StaticAnalyser::GetTargets(const char *file_name) {
std::vector<Target> targets;
// Collect all disks, tapes and ROMs as can be extrapolated from this file, forming the
// union of all platforms this file might be a target for.

@ -14,7 +14,6 @@
#include "../Storage/Cartridge/Cartridge.hpp"
#include <string>
#include <list>
#include <vector>
namespace StaticAnalyser {
@ -65,9 +64,9 @@ enum class AmstradCPCModel {
A list of disks, tapes and cartridges.
*/
struct Media {
std::list<std::shared_ptr<Storage::Disk::Disk>> disks;
std::list<std::shared_ptr<Storage::Tape::Tape>> tapes;
std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> cartridges;
std::vector<std::shared_ptr<Storage::Disk::Disk>> disks;
std::vector<std::shared_ptr<Storage::Tape::Tape>> tapes;
std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>> cartridges;
bool empty() const {
return disks.empty() && tapes.empty() && cartridges.empty();
@ -137,7 +136,7 @@ struct Target {
@returns The list of potential targets, sorted from most to least probable.
*/
std::list<Target> GetTargets(const char *file_name);
std::vector<Target> GetTargets(const char *file_name);
/*!
Inspects the supplied file and determines the media included.

@ -27,7 +27,7 @@ static std::vector<Storage::Data::ZX8081::File> GetFiles(const std::shared_ptr<S
return files;
}
void StaticAnalyser::ZX8081::AddTargets(const Media &media, std::list<Target> &destination, TargetPlatform::IntType potential_platforms) {
void StaticAnalyser::ZX8081::AddTargets(const Media &media, std::vector<Target> &destination, TargetPlatform::IntType potential_platforms) {
if(!media.tapes.empty()) {
std::vector<Storage::Data::ZX8081::File> files = GetFiles(media.tapes.front());
media.tapes.front()->reset();

@ -15,7 +15,7 @@
namespace StaticAnalyser {
namespace ZX8081 {
void AddTargets(const Media &media, std::list<Target> &destination, TargetPlatform::IntType potential_platforms);
void AddTargets(const Media &media, std::vector<Target> &destination, TargetPlatform::IntType potential_platforms);
}
}