2016-04-16 03:49:39 +00:00
|
|
|
/**
|
|
|
|
Copyright (c) 2015-present, Facebook, Inc.
|
|
|
|
All rights reserved.
|
|
|
|
|
|
|
|
This source code is licensed under the BSD-style license found in the
|
|
|
|
LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*/
|
2016-03-09 01:01:27 +00:00
|
|
|
|
|
|
|
#include <acdriver/Driver.h>
|
|
|
|
#include <acdriver/Options.h>
|
2016-03-15 18:14:27 +00:00
|
|
|
#include <acdriver/Output.h>
|
|
|
|
#include <acdriver/Result.h>
|
2016-03-16 02:27:50 +00:00
|
|
|
#include <acdriver/VersionAction.h>
|
|
|
|
#include <acdriver/CompileAction.h>
|
|
|
|
#include <acdriver/ContentsAction.h>
|
2016-05-24 23:06:36 +00:00
|
|
|
#include <libutil/Filesystem.h>
|
2016-09-20 05:59:52 +00:00
|
|
|
#include <process/Context.h>
|
2016-03-15 18:14:27 +00:00
|
|
|
|
2016-05-24 00:59:34 +00:00
|
|
|
#include <algorithm>
|
|
|
|
#include <iterator>
|
2016-03-15 18:14:27 +00:00
|
|
|
#include <iostream>
|
2016-03-09 01:01:27 +00:00
|
|
|
|
|
|
|
using acdriver::Driver;
|
|
|
|
using acdriver::Options;
|
2016-03-15 18:14:27 +00:00
|
|
|
using acdriver::Output;
|
|
|
|
using acdriver::Result;
|
2016-03-16 02:27:50 +00:00
|
|
|
using acdriver::VersionAction;
|
|
|
|
using acdriver::CompileAction;
|
|
|
|
using acdriver::ContentsAction;
|
2016-05-24 23:06:36 +00:00
|
|
|
using libutil::Filesystem;
|
2016-03-09 01:01:27 +00:00
|
|
|
|
|
|
|
Driver::
|
|
|
|
Driver()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Driver::
|
|
|
|
~Driver()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-03-15 18:14:27 +00:00
|
|
|
static void
|
2016-05-24 23:06:36 +00:00
|
|
|
RunInternal(Filesystem *filesystem, Options const &options, Output *output, Result *result)
|
2016-03-15 18:14:27 +00:00
|
|
|
{
|
|
|
|
if (options.version()) {
|
2016-03-16 02:27:50 +00:00
|
|
|
VersionAction version;
|
|
|
|
version.run(options, output, result);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (options.printContents()) {
|
|
|
|
ContentsAction contents;
|
2016-05-24 23:06:36 +00:00
|
|
|
contents.run(filesystem, options, output, result);
|
2016-03-16 02:27:50 +00:00
|
|
|
}
|
|
|
|
|
2016-07-28 00:38:07 +00:00
|
|
|
if (options.compile()) {
|
2016-03-16 02:27:50 +00:00
|
|
|
CompileAction compile;
|
2016-07-06 23:25:12 +00:00
|
|
|
compile.run(filesystem, options, output, result);
|
2016-03-15 18:14:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Output::Format
|
|
|
|
OptionsOutputFormat(Options const &options, Result *result)
|
|
|
|
{
|
2016-07-28 00:38:07 +00:00
|
|
|
if (!options.outputFormat() || *options.outputFormat() == "xml1") {
|
2016-03-15 18:14:27 +00:00
|
|
|
return Output::Format::XML;
|
2016-07-28 00:38:07 +00:00
|
|
|
} else if (*options.outputFormat() == "binary1") {
|
2016-03-15 18:14:27 +00:00
|
|
|
return Output::Format::Binary;
|
2016-07-28 00:38:07 +00:00
|
|
|
} else if (*options.outputFormat() == "human-readable-text") {
|
2016-03-15 18:14:27 +00:00
|
|
|
return Output::Format::Text;
|
|
|
|
} else {
|
|
|
|
result->normal(Result::Severity::Error, "unknown output format");
|
|
|
|
return Output::Format::XML;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-09 01:01:27 +00:00
|
|
|
int Driver::
|
2016-09-20 05:59:52 +00:00
|
|
|
Run(process::Context const *processContext, Filesystem *filesystem)
|
2016-03-09 01:01:27 +00:00
|
|
|
{
|
2016-03-15 18:14:27 +00:00
|
|
|
Result result;
|
|
|
|
Output output;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Parse input options.
|
|
|
|
*/
|
2016-03-09 01:01:27 +00:00
|
|
|
Options options;
|
2016-09-20 04:42:46 +00:00
|
|
|
std::pair<bool, std::string> optionsResult = libutil::Options::Parse<Options>(&options, processContext->commandLineArguments());
|
2016-03-15 18:14:27 +00:00
|
|
|
if (!optionsResult.first) {
|
|
|
|
result.normal(Result::Severity::Error, optionsResult.second, std::string("unknown option"));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Validate output format. Do this first so errors are caught early.
|
|
|
|
*/
|
|
|
|
Output::Format outputFormat = OptionsOutputFormat(options, &result);
|
|
|
|
|
|
|
|
if (result.success()) {
|
|
|
|
/*
|
|
|
|
* Perform actions specified by options.
|
|
|
|
*/
|
2016-05-24 23:06:36 +00:00
|
|
|
RunInternal(filesystem, options, &output, &result);
|
2016-03-15 18:14:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Serialize the result into the output.
|
|
|
|
*/
|
|
|
|
result.write(&output);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Write out the output in the specified output format.
|
|
|
|
*/
|
|
|
|
ext::optional<std::vector<uint8_t>> outputContents = output.serialize(outputFormat);
|
|
|
|
if (outputContents) {
|
|
|
|
std::copy(outputContents->begin(), outputContents->end(), std::ostream_iterator<char>(std::cout));
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "error: unable to serialize output\n");
|
2016-03-09 01:01:27 +00:00
|
|
|
}
|
|
|
|
|
2016-03-15 18:14:27 +00:00
|
|
|
return (result.success() ? 0 : 1);
|
2016-03-09 01:01:27 +00:00
|
|
|
}
|