mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Bash the imagewriter stuff into working with the new config system.
This commit is contained in:
@@ -9,9 +9,6 @@ message ImgInputOutput {
|
||||
optional int32 sector_size = 4;
|
||||
}
|
||||
|
||||
optional int32 tracks = 1;
|
||||
optional int32 heads = 2;
|
||||
optional int32 sectors = 3;
|
||||
repeated Format format = 4;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "imagewriter/imagewriter.h"
|
||||
#include "fmt/format.h"
|
||||
#include "ldbs.h"
|
||||
#include "lib/config.pb.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
@@ -24,15 +25,15 @@ static int sectors_per_track(int track)
|
||||
class D64ImageWriter : public ImageWriter
|
||||
{
|
||||
public:
|
||||
D64ImageWriter(const SectorSet& sectors, const ImageSpec& spec):
|
||||
ImageWriter(sectors, spec)
|
||||
D64ImageWriter(const Config_OutputFile& config):
|
||||
ImageWriter(config)
|
||||
{}
|
||||
|
||||
void writeImage()
|
||||
void writeImage(const SectorSet& sectors)
|
||||
{
|
||||
std::cout << "writing D64 triangular image\n";
|
||||
|
||||
std::ofstream outputFile(spec.filename, std::ios::out | std::ios::binary);
|
||||
std::ofstream outputFile(_config.filename(), std::ios::out | std::ios::binary);
|
||||
if (!outputFile.is_open())
|
||||
Error() << "cannot open output file";
|
||||
|
||||
@@ -55,9 +56,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<ImageWriter> ImageWriter::createD64ImageWriter(
|
||||
const SectorSet& sectors, const ImageSpec& spec)
|
||||
std::unique_ptr<ImageWriter> ImageWriter::createD64ImageWriter(const Config_OutputFile& config)
|
||||
{
|
||||
return std::unique_ptr<ImageWriter>(new D64ImageWriter(sectors, spec));
|
||||
return std::unique_ptr<ImageWriter>(new D64ImageWriter(config));
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "imagewriter/imagewriter.h"
|
||||
#include "fmt/format.h"
|
||||
#include "ldbs.h"
|
||||
#include "lib/config.pb.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
@@ -27,35 +28,44 @@ static void write_and_update_checksum(ByteWriter& bw, uint32_t& checksum, const
|
||||
class DiskCopyImageWriter : public ImageWriter
|
||||
{
|
||||
public:
|
||||
DiskCopyImageWriter(const SectorSet& sectors, const ImageSpec& spec):
|
||||
ImageWriter(sectors, spec)
|
||||
DiskCopyImageWriter(const Config_OutputFile& config):
|
||||
ImageWriter(config)
|
||||
{}
|
||||
|
||||
void writeImage()
|
||||
void writeImage(const SectorSet& sectors)
|
||||
{
|
||||
unsigned numCylinders;
|
||||
unsigned numHeads;
|
||||
unsigned numSectors;
|
||||
unsigned numBytes;
|
||||
sectors.calculateSize(numCylinders, numHeads, numSectors, numBytes);
|
||||
|
||||
bool mfm = false;
|
||||
|
||||
if (spec.bytes == 524)
|
||||
switch (numBytes)
|
||||
{
|
||||
case 524:
|
||||
/* GCR disk */
|
||||
}
|
||||
else if (spec.bytes == 512)
|
||||
{
|
||||
break;
|
||||
|
||||
case 512:
|
||||
/* MFM disk */
|
||||
mfm = true;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
default:
|
||||
Error() << "this image is not compatible with the DiskCopy 4.2 format";
|
||||
}
|
||||
|
||||
std::cout << "writing DiskCopy 4.2 image\n"
|
||||
<< fmt::format("{} tracks, {} heads, {} sectors, {} bytes per sector; {}\n",
|
||||
spec.cylinders, spec.heads, spec.sectors, spec.bytes,
|
||||
numCylinders, numHeads, numSectors, numBytes,
|
||||
mfm ? "MFM" : "GCR");
|
||||
|
||||
auto sectors_per_track = [&](int track) -> int
|
||||
{
|
||||
if (mfm)
|
||||
return spec.sectors;
|
||||
return numSectors;
|
||||
|
||||
if (track < 16)
|
||||
return 12;
|
||||
@@ -77,9 +87,9 @@ public:
|
||||
uint32_t tagChecksum = 0;
|
||||
uint32_t offset = 0x54;
|
||||
uint32_t sectorDataStart = offset;
|
||||
for (int track = 0; track < spec.cylinders; track++)
|
||||
for (int track = 0; track < numCylinders; track++)
|
||||
{
|
||||
for (int head = 0; head < spec.heads; head++)
|
||||
for (int head = 0; head < numHeads; head++)
|
||||
{
|
||||
int sectorCount = sectors_per_track(track);
|
||||
for (int sectorId = 0; sectorId < sectorCount; sectorId++)
|
||||
@@ -97,9 +107,9 @@ public:
|
||||
uint32_t sectorDataEnd = offset;
|
||||
if (!mfm)
|
||||
{
|
||||
for (int track = 0; track < spec.cylinders; track++)
|
||||
for (int track = 0; track < numCylinders; track++)
|
||||
{
|
||||
for (int head = 0; head < spec.heads; head++)
|
||||
for (int head = 0; head < numHeads; head++)
|
||||
{
|
||||
int sectorCount = sectors_per_track(track);
|
||||
for (int sectorId = 0; sectorId < sectorCount; sectorId++)
|
||||
@@ -124,14 +134,14 @@ public:
|
||||
if (mfm)
|
||||
{
|
||||
format = 0x22;
|
||||
if (spec.sectors == 18)
|
||||
if (numSectors == 18)
|
||||
encoding = 3;
|
||||
else
|
||||
encoding = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (spec.heads == 2)
|
||||
if (numHeads == 2)
|
||||
{
|
||||
encoding = 1;
|
||||
format = 0x22;
|
||||
@@ -155,14 +165,14 @@ public:
|
||||
bw.write_8(format); /* format byte */
|
||||
bw.write_be16(0x0100); /* magic number */
|
||||
|
||||
image.writeToFile(spec.filename);
|
||||
image.writeToFile(_config.filename());
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<ImageWriter> ImageWriter::createDiskCopyImageWriter(
|
||||
const SectorSet& sectors, const ImageSpec& spec)
|
||||
const Config_OutputFile& config)
|
||||
{
|
||||
return std::unique_ptr<ImageWriter>(new DiskCopyImageWriter(sectors, spec));
|
||||
return std::unique_ptr<ImageWriter>(new DiskCopyImageWriter(config));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,10 +5,12 @@
|
||||
#include "sectorset.h"
|
||||
#include "imagewriter/imagewriter.h"
|
||||
#include "utils.h"
|
||||
#include "lib/config.pb.h"
|
||||
#include "fmt/format.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#if 0
|
||||
std::map<std::string, ImageWriter::Constructor> ImageWriter::formats =
|
||||
{
|
||||
{".adf", ImageWriter::createImgImageWriter},
|
||||
@@ -19,48 +21,27 @@ std::map<std::string, ImageWriter::Constructor> ImageWriter::formats =
|
||||
{".ldbs", ImageWriter::createLDBSImageWriter},
|
||||
{".st", ImageWriter::createImgImageWriter},
|
||||
};
|
||||
#endif
|
||||
|
||||
ImageWriter::Constructor ImageWriter::findConstructor(const ImageSpec& spec)
|
||||
std::unique_ptr<ImageWriter> ImageWriter::create(const Config_OutputFile& config)
|
||||
{
|
||||
const auto& filename = spec.filename;
|
||||
|
||||
for (const auto& e : formats)
|
||||
{
|
||||
if (endsWith(filename, e.first))
|
||||
return e.second;
|
||||
if (config.has_img())
|
||||
return ImageWriter::createImgImageWriter(config);
|
||||
else
|
||||
Error() << "bad output image config";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
//void ImageWriter::verifyImageSpec(const ImageSpec& spec)
|
||||
//{
|
||||
// if (!findConstructor(spec))
|
||||
// Error() << "unrecognised output image filename extension";
|
||||
//}
|
||||
|
||||
std::unique_ptr<ImageWriter> ImageWriter::create(const SectorSet& sectors, const ImageSpec& spec)
|
||||
{
|
||||
verifyImageSpec(spec);
|
||||
return findConstructor(spec)(sectors, spec);
|
||||
}
|
||||
|
||||
void ImageWriter::verifyImageSpec(const ImageSpec& spec)
|
||||
{
|
||||
if (!findConstructor(spec))
|
||||
Error() << "unrecognised output image filename extension";
|
||||
}
|
||||
|
||||
ImageWriter::ImageWriter(const SectorSet& sectors, const ImageSpec& spec):
|
||||
sectors(sectors),
|
||||
spec(spec)
|
||||
ImageWriter::ImageWriter(const Config_OutputFile& config):
|
||||
_config(config)
|
||||
{}
|
||||
|
||||
void ImageWriter::adjustGeometry()
|
||||
{
|
||||
if (!spec.initialised)
|
||||
{
|
||||
sectors.calculateSize(spec.cylinders, spec.heads, spec.sectors, spec.bytes);
|
||||
spec.initialised = true;
|
||||
std::cout << "Autodetecting output geometry\n";
|
||||
}
|
||||
}
|
||||
|
||||
void ImageWriter::writeCsv(const std::string& filename)
|
||||
void ImageWriter::writeCsv(const SectorSet& sectors, const std::string& filename)
|
||||
{
|
||||
std::ofstream f(filename, std::ios::out);
|
||||
if (!f.is_open())
|
||||
@@ -81,18 +62,12 @@ void ImageWriter::writeCsv(const std::string& filename)
|
||||
"\"Status\""
|
||||
"\n";
|
||||
|
||||
for (int track = 0; track < spec.cylinders; track++)
|
||||
for (const auto& it : sectors.get())
|
||||
{
|
||||
for (int head = 0; head < spec.heads; head++)
|
||||
{
|
||||
for (int sectorId = 0; sectorId < spec.sectors; sectorId++)
|
||||
{
|
||||
f << fmt::format("{},{},", track, head);
|
||||
const auto& sector = sectors.get(track, head, sectorId);
|
||||
if (!sector)
|
||||
f << fmt::format(",,{},,,,,,,,sector not found\n", sectorId);
|
||||
else
|
||||
f << fmt::format("{},{},{},{},{},{},{},{},{},{},{}\n",
|
||||
const auto& sector = it.second;
|
||||
f << fmt::format("{},{},{},{},{},{},{},{},{},{},{},{},{}\n",
|
||||
sector->physicalTrack,
|
||||
sector->physicalSide,
|
||||
sector->logicalTrack,
|
||||
sector->logicalSide,
|
||||
sector->logicalSector,
|
||||
@@ -107,21 +82,25 @@ void ImageWriter::writeCsv(const std::string& filename)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImageWriter::printMap()
|
||||
void ImageWriter::printMap(const SectorSet& sectors)
|
||||
{
|
||||
unsigned numCylinders;
|
||||
unsigned numHeads;
|
||||
unsigned numSectors;
|
||||
unsigned numBytes;
|
||||
sectors.calculateSize(numCylinders, numHeads, numSectors, numBytes);
|
||||
|
||||
int badSectors = 0;
|
||||
int missingSectors = 0;
|
||||
int totalSectors = 0;
|
||||
std::cout << "H.SS Tracks --->" << std::endl;
|
||||
for (int head = 0; head < spec.heads; head++)
|
||||
for (int head = 0; head < numHeads; head++)
|
||||
{
|
||||
for (int sectorId = 0; sectorId < spec.sectors; sectorId++)
|
||||
for (int sectorId = 0; sectorId < numSectors; sectorId++)
|
||||
{
|
||||
std::cout << fmt::format("{}.{:2} ", head, sectorId);
|
||||
for (int track = 0; track < spec.cylinders; track++)
|
||||
for (int track = 0; track < numCylinders; track++)
|
||||
{
|
||||
const auto& sector = sectors.get(track, head, sectorId);
|
||||
if (!sector)
|
||||
|
||||
@@ -2,47 +2,33 @@
|
||||
#define IMAGEWRITER_H
|
||||
|
||||
class SectorSet;
|
||||
class ImageSpec;
|
||||
class Config_OutputFile;
|
||||
|
||||
class ImageWriter
|
||||
{
|
||||
public:
|
||||
ImageWriter(const SectorSet& sectors, const ImageSpec& spec);
|
||||
ImageWriter(const Config_OutputFile& config);
|
||||
virtual ~ImageWriter() {};
|
||||
|
||||
public:
|
||||
static std::unique_ptr<ImageWriter> create(const SectorSet& sectors, const ImageSpec& spec);
|
||||
static void verifyImageSpec(const ImageSpec& filename);
|
||||
|
||||
private:
|
||||
typedef
|
||||
std::function<
|
||||
std::unique_ptr<ImageWriter>(const SectorSet& sectors, const ImageSpec& spec)
|
||||
>
|
||||
Constructor;
|
||||
|
||||
static std::map<std::string, Constructor> formats;
|
||||
static std::unique_ptr<ImageWriter> create(const Config_OutputFile& config);
|
||||
|
||||
static std::unique_ptr<ImageWriter> createImgImageWriter(
|
||||
const SectorSet& sectors, const ImageSpec& spec);
|
||||
const Config_OutputFile& config);
|
||||
static std::unique_ptr<ImageWriter> createLDBSImageWriter(
|
||||
const SectorSet& sectors, const ImageSpec& spec);
|
||||
const Config_OutputFile& config);
|
||||
static std::unique_ptr<ImageWriter> createD64ImageWriter(
|
||||
const SectorSet& sectors, const ImageSpec& spec);
|
||||
const Config_OutputFile& config);
|
||||
static std::unique_ptr<ImageWriter> createDiskCopyImageWriter(
|
||||
const SectorSet& sectors, const ImageSpec& spec);
|
||||
|
||||
static Constructor findConstructor(const ImageSpec& spec);
|
||||
const Config_OutputFile& config);
|
||||
|
||||
public:
|
||||
virtual void adjustGeometry();
|
||||
void printMap();
|
||||
void writeCsv(const std::string& filename);
|
||||
virtual void writeImage() = 0;
|
||||
void printMap(const SectorSet& sectors);
|
||||
void writeCsv(const SectorSet& sectors, const std::string& filename);
|
||||
virtual void writeImage(const SectorSet& sectors) = 0;
|
||||
|
||||
protected:
|
||||
const SectorSet& sectors;
|
||||
ImageSpec spec;
|
||||
const Config_OutputFile& _config;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "sector.h"
|
||||
#include "sectorset.h"
|
||||
#include "imagewriter/imagewriter.h"
|
||||
#include "lib/config.pb.h"
|
||||
#include "fmt/format.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
@@ -12,16 +13,17 @@
|
||||
class ImgImageWriter : public ImageWriter
|
||||
{
|
||||
public:
|
||||
ImgImageWriter(const SectorSet& sectors, const ImageSpec& spec):
|
||||
ImageWriter(sectors, spec)
|
||||
ImgImageWriter(const Config_OutputFile& config):
|
||||
ImageWriter(config)
|
||||
{}
|
||||
|
||||
void writeImage()
|
||||
void writeImage(const SectorSet& sectors)
|
||||
{
|
||||
unsigned numCylinders = spec.cylinders;
|
||||
unsigned numHeads = spec.heads;
|
||||
unsigned numSectors = spec.sectors;
|
||||
unsigned numBytes = spec.bytes;
|
||||
unsigned numCylinders;
|
||||
unsigned numHeads;
|
||||
unsigned numSectors;
|
||||
unsigned numBytes;
|
||||
sectors.calculateSize(numCylinders, numHeads, numSectors, numBytes);
|
||||
|
||||
size_t headSize = numSectors * numBytes;
|
||||
size_t trackSize = headSize * numHeads;
|
||||
@@ -32,7 +34,7 @@ public:
|
||||
numCylinders * trackSize / 1024)
|
||||
<< std::endl;
|
||||
|
||||
std::ofstream outputFile(spec.filename, std::ios::out | std::ios::binary);
|
||||
std::ofstream outputFile(_config.filename(), std::ios::out | std::ios::binary);
|
||||
if (!outputFile.is_open())
|
||||
Error() << "cannot open output file";
|
||||
|
||||
@@ -55,7 +57,7 @@ public:
|
||||
};
|
||||
|
||||
std::unique_ptr<ImageWriter> ImageWriter::createImgImageWriter(
|
||||
const SectorSet& sectors, const ImageSpec& spec)
|
||||
const Config_OutputFile& config)
|
||||
{
|
||||
return std::unique_ptr<ImageWriter>(new ImgImageWriter(sectors, spec));
|
||||
return std::unique_ptr<ImageWriter>(new ImgImageWriter(config));
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "imagewriter/imagewriter.h"
|
||||
#include "fmt/format.h"
|
||||
#include "ldbs.h"
|
||||
#include "lib/config.pb.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
@@ -13,18 +14,20 @@
|
||||
class LDBSImageWriter : public ImageWriter
|
||||
{
|
||||
public:
|
||||
LDBSImageWriter(const SectorSet& sectors, const ImageSpec& spec):
|
||||
ImageWriter(sectors, spec)
|
||||
LDBSImageWriter(const Config_OutputFile& config):
|
||||
ImageWriter(config)
|
||||
{}
|
||||
|
||||
void writeImage()
|
||||
void writeImage(const SectorSet& sectors)
|
||||
{
|
||||
LDBS ldbs;
|
||||
|
||||
unsigned numCylinders = spec.cylinders;
|
||||
unsigned numHeads = spec.heads;
|
||||
unsigned numSectors = spec.sectors;
|
||||
unsigned numBytes = spec.bytes;
|
||||
unsigned numCylinders;
|
||||
unsigned numHeads;
|
||||
unsigned numSectors;
|
||||
unsigned numBytes;
|
||||
sectors.calculateSize(numCylinders, numHeads, numSectors, numBytes);
|
||||
|
||||
std::cout << fmt::format("writing {} tracks, {} heads, {} sectors, {} bytes per sector",
|
||||
numCylinders, numHeads,
|
||||
numSectors, numBytes)
|
||||
@@ -95,12 +98,11 @@ public:
|
||||
|
||||
uint32_t trackDirectoryAddress = ldbs.put(trackDirectory, LDBS_TRACK_BLOCK);
|
||||
Bytes data = ldbs.write(trackDirectoryAddress);
|
||||
data.writeToFile(spec.filename);
|
||||
data.writeToFile(_config.filename());
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<ImageWriter> ImageWriter::createLDBSImageWriter(
|
||||
const SectorSet& sectors, const ImageSpec& spec)
|
||||
std::unique_ptr<ImageWriter> ImageWriter::createLDBSImageWriter(const Config_OutputFile& config)
|
||||
{
|
||||
return std::unique_ptr<ImageWriter>(new LDBSImageWriter(sectors, spec));
|
||||
return std::unique_ptr<ImageWriter>(new LDBSImageWriter(config));
|
||||
}
|
||||
|
||||
@@ -27,16 +27,6 @@ FlagGroup readerFlags
|
||||
&fluxmapReaderFlags,
|
||||
};
|
||||
|
||||
//static DataSpecFlag source(
|
||||
// { "--source", "-s" },
|
||||
// "source for data",
|
||||
// ":t=0-79:s=0-1:d=0");
|
||||
//
|
||||
//static DataSpecFlag output(
|
||||
// { "--output", "-o" },
|
||||
// "output image file to write to",
|
||||
// "");
|
||||
|
||||
static StringFlag destination(
|
||||
{ "--write-flux", "-f" },
|
||||
"write the raw magnetic flux to this file",
|
||||
@@ -66,16 +56,6 @@ static StringFlag csvFile(
|
||||
|
||||
static std::unique_ptr<FluxSink> outputFluxSink;
|
||||
|
||||
static void writeSectorsToFile(const SectorSet& sectors, const ImageSpec& spec)
|
||||
{
|
||||
std::unique_ptr<ImageWriter> writer(ImageWriter::create(sectors, spec));
|
||||
writer->adjustGeometry();
|
||||
writer->printMap();
|
||||
if (!csvFile.get().empty())
|
||||
writer->writeCsv(csvFile.get());
|
||||
writer->writeImage();
|
||||
}
|
||||
|
||||
void Track::readFluxmap()
|
||||
{
|
||||
std::cout << fmt::format("{0:>3}.{1}: ", physicalTrack, physicalSide) << std::flush;
|
||||
@@ -158,16 +138,6 @@ void readDiskCommand(FluxSource& fluxsource, AbstractDecoder& decoder, ImageWrit
|
||||
{
|
||||
for (int side : iterate(config.sides()))
|
||||
{
|
||||
#if 0
|
||||
auto track = std::make_unique<Track>(location
|
||||
std::vector<std::unique_ptr<Track>> tracks;
|
||||
for (const auto& location : spec.locations)
|
||||
{
|
||||
auto track = std::make_unique<Track>(location.track, location.side);
|
||||
track->fluxsource = fluxSource;
|
||||
tracks.push_back(std::move(track));
|
||||
}
|
||||
#endif
|
||||
auto track = std::make_unique<Track>(cylinder, side);
|
||||
track->fluxsource = &fluxsource;
|
||||
|
||||
@@ -281,8 +251,11 @@ void readDiskCommand(FluxSource& fluxsource, AbstractDecoder& decoder, ImageWrit
|
||||
}
|
||||
}
|
||||
|
||||
Error() << "write to image not done";
|
||||
//writeSectorsToFile(allSectors, outputSpec);
|
||||
writer.printMap(allSectors);
|
||||
if (!csvFile.get().empty())
|
||||
writer.writeCsv(allSectors, csvFile.get());
|
||||
writer.writeImage(allSectors);
|
||||
|
||||
if (failures)
|
||||
std::cerr << "Warning: some sectors could not be decoded." << std::endl;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ static void syntax()
|
||||
|
||||
int mainConvertImage(int argc, const char* argv[])
|
||||
{
|
||||
Error() << "unimplemented";
|
||||
#if 0
|
||||
auto filenames = flags.parseFlagsWithFilenames(argc, argv);
|
||||
if (filenames.size() != 2)
|
||||
syntax();
|
||||
@@ -32,6 +34,7 @@ int mainConvertImage(int argc, const char* argv[])
|
||||
writer->adjustGeometry();
|
||||
writer->printMap();
|
||||
writer->writeImage();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -40,11 +40,7 @@ int mainRead(int argc, const char* argv[])
|
||||
else
|
||||
Error() << "no input disk format specified";
|
||||
|
||||
std::unique_ptr<ImageWriter> writer;
|
||||
// if (config.output().file().has_img())
|
||||
// write.reset(new ImgImageWriter());
|
||||
// else
|
||||
// Error() << "no output image format specified";
|
||||
std::unique_ptr<ImageWriter> writer(ImageWriter::create(config.output().file()));
|
||||
|
||||
readDiskCommand(*fluxSource, *decoder, *writer);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
input {
|
||||
disk {
|
||||
fluxfile: "samples/brother-clean.flux"
|
||||
brother {}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user