We have a Hudson build server, and I have a fairly simple need. I'm wondering if a plugin exists for this, or if I should try to write one.
Basically, whenever a build occurs, I'd like to extract some C++ code and use it to produce an HTML table inside of an HTML file. The code specifically is a static array of structs like so:
typedef struct definition {
int val;
const char* name;
const char* desc;
} DEFINITION;
static const DEFINITION def[] =
{
{1, "abc", "def"},
{3, "ghi", "jkl"},
{5, "mno", "pqr"}
};
I'd like to extract the strings from the array and convert them into a two column HTML table. The code to write this would obviously be simple. I'm just new to Hudson and am not sure what the best approach is.
We already use Doxygen, but I'm not sure whether it can perform this job.
Related
Apologies if the title is misleading or if this question has been answered before.
I'm working with Eigen's Tensor module, particularly the Eigen::TensorFixedSize class as I know the shape at compile time.
Essentially, because this is a Lorentz problem, a rank-2 tensor would go like,
Eigen::TensorFixedSize<double, Eigen::Sizes<4,4>> t;
a rank-3 tensor,
Eigen::TensorFixedSize<double, Eigen::Sizes<4,4,4>> t;
and so on.
I'd like to write a class that is able to initialise a tensor depending on the rank. In pseudo-code,
template<typename RANK>
class Foo
{
public:
...
private:
Eigen::TensorFixedSize<double, Eigen::Sizes<4,4,4,...,RANK times>> _t;
}
somehow converting the template parameter from
<2> --> <4,4>
<3> --> <4,4,4>
up to an arbitrary unsigned int in <N>.
Would this be possible to do?
Yup.
template <class RankIdx>
struct TensorForRank;
template <std::size_t... RankIdx>
struct TensorForRank<std::index_sequence<RankIdx...>> {
using type = Eigen::TensorFixedSize<double, Eigen::Sizes<(void(RankIdx), 4)...>>;
};
template <std::size_t Rank>
using TensorForRank_t = typename TensorForRank<std::make_index_sequence<Rank>>::type;
Use as:
template<std::size_t Rank>
class Foo
{
// ...
private:
TensorForRank_t<Rank> _t;
};
See it live on Wandbox (with a placeholder test<...> template as Eigen is not available)
Quentin's answer is very good, and what I'd go with.
The only downside is the "useless" generation of an index sequence [0, 1, 2, ...] whose values we ignore, and substitute for our own.
If we want to directly create the repeated values, we can write our own generator code (which is quite a bit more verbose):
Start with creating a type that can hold a number of std::size_t values by aliasing a std::integer_sequence:
template<std::size_t... vals>
using value_sequence = std::integer_sequence<std::size_t, vals...>;
The goal is to ultimately create a value_sequence<4, 4, 4> and then instantiate an Eigen::Sizes using those 4s.
The next thing we need to be able to do is concatenate two sequences, because we're going to build it up like so:
concat(value_sequence<4>, value_sequence<4>) --> value_sequence<4, 4>
We can do this via a stub method that accepts two value_sequence types and returns the concatenated result. Note that we do not ever write a definition for this method; we're simply taking advantage of the type system to write less code than a template specialization would take:
template<std::size_t... lhs, std::size_t... rhs>
constexpr auto concat(value_sequence<lhs...>, value_sequence<rhs...>) -> value_sequence<lhs..., rhs...>;
At this point we have enough machinery to create a value_sequence<4,4,4>, so now we need a way to indicate the value we wish to use (4) and the number of times to repeat it (3) to produce it:
template<std::size_t value, std::size_t num_repeats>
struct repeated_value
{
using left_sequence = value_sequence<value>;
using right_sequence = typename repeated_value<value, num_repeats-1>::type;
using type = decltype(concat(left_sequence{}, right_sequence{}));
};
repeated_value<4, 3>::type produces a value_sequence<4, 4, 4>.
Since repeated_value<...>::type is recursive, we need to provide a base case via partial specialization:
template<std::size_t value>
struct repeated_value<value, 1>
{
using type = value_sequence<value>;
};
Great. All that's left is for us to receive an Eigen::Sizes class and a value_sequence<4, 4, 4> type, and produce Eigen::Sizes<4, 4, 4>.
We can do this with partial template specialization again:
template<template<std::size_t...> class T, class...>
struct InstantiateWithRepeatedVals;
template<template<std::size_t...> class T, std::size_t... vals>
struct InstantiateWithRepeatedVals<T, value_sequence<vals...>>
{
using type = T<vals...>;
};
That it! Throw in a few helpers to make using it easier, and we're done:
template<std::size_t value, std::size_t num_repeats>
using repeated_value_t = typename repeated_value<value, num_repeats>::type;
template<template<std::size_t...> class T, std::size_t Value, std::size_t N>
using InstantiateWithRepeatedVals_t = typename InstantiateWithRepeatedVals<T, repeated_value_t<Value, N>>::type;
Now we can use it like so:
using my_type = InstantiateWithRepeatedVals_t<EigenSizes, 4, 3>;
static_assert(std::is_same_v<my_type, EigenSizes<4, 4, 4>>);
Live Demo
The following code successfully sets up a ClangTool for parsing:
std::vector<std::string> source_files;
cl::OptionCategory option_category("options");
CommonOptionsParser options_parser(argc, argv, option_category);
ClangTool tool(options_parser.getCompilations(), source_files);
However, I created argc and argv on my own -- they didn't come from main(). Instead of an input file, is it possible to get the ClangTool to parse the contents of a string? E.g.,
const char *str = "extern int foo;\n";
mapVirtualFile() looked like what I wanted, but when I tried, foo didn't come out of it.
tool.mapVirtualFile(StringRef("faux_file.c"), StringRef(str));
// Then proceed to tool.run(...), etc.
I could create a temporary file in /tmp, but I'd like to simply read from the string.
Update:
Creating a temporary file works. It's kind of hack-ish, but it's stable and consistent. It would be nice to have a way of inputting from a string, but it doesn't seem possible with the existing implementation.
I have some tabular data:
Foo Bar
-------------
fooes 42
bars 666
...
So, I declare the entity structure:
type TFoo = record
Foo: string;
Bar: Integer
end;
and the table of entities:
const FOOES = array [M..N] of TFoo = (
// Have to specify the field names for each record...
(Foo: 'fooes'; Bar: 42),
(Foo: 'bars'; Bar: 666)
{ so on }
);
As you see, this looks quite verbose and redundant, and it is because I initialize all of the fields for all of the records. And there is a lot of editing if I copy tabular data prepared elsewhere. I'd prefer to not enumerate all of the fields and stick to the more laconic C style, that is, constants only. And here comes the record constructor...
Can record constructors help me in this case?
Here's an example in C. You'll notice that we don't have to specify the field names in each declaration:
#include <stdio.h>
typedef struct {
char foo[10];
int bar;
} foo;
int main(void) {
/* Look here */
foo FOOES[2] = {{"foo", 42}, {"bar", 666}};
int i = 0;
for (; i < 2; i++) {
printf("%s\t%d\n", FOOES[i].foo, FOOES[i].bar);
}
return 0;
}
A const is just a read-only var which is loaded/mapped within the code, when the executable is launched.
You can create a var record (or a const but overriding the writable const option), then initialize it in the initialization section of the unit.
var FOOES = array [M..N] of TFoo;
....
initialization
SetFooArray(FOOES,['fooes',42,'bar',230]);
...
end.
The custom SetFooArray() function will put all array of const parameters into FOOES.
I use this technique sometimes to initialize computable arrays (e.g. conversion or lookup tables). Sometimes, it does make sense to compute once at startup a huge array, saving some KB of const in the source code, with a few lines of code.
But I'm not sure it will be worth it in your case. The default const declaration is a bit verbose, but not a problem if you use Ctrl+C/Ctrl+V or a find and replace. It is the most standard, is secure if you change later the record layout (whereas the C construction may compile without error), and will create a true constant.
Record constructors are runtime only and so for constants your current solution is the only option.
If you want it done in source then what you have already typed is your answer. You could, of course, put the data in separate arrays and initialize them that way, but that can make your code look messy.
You could also store them in an text file (Foo=Bar format) and read them into a TStringList at run-time (SL.LoadFromFile()). But even with a sorted TStringList it will be far less efficient (MyVariable := SL.Values['Foo1']; for example).
There are a million ways to solve this problem outside of source code. Taking it from the other direction, put the data into Excel and create an Excel macro to build the source and put it into the clipboard to paste into your PAS file. This wouldn't be too difficult and probably easier than formatting the Delphi code within the IDE.
I want users of my C++ application to be able to provide anonymous functions to perform small chunks of work.
Small fragments like this would be ideal.
function(arg) return arg*5 end
Now I'd like to be able to write something as simple as this for my C code,
// Push the function onto the lua stack
lua_xxx(L, "function(arg) return arg*5 end" )
// Store it away for later
int reg_index = luaL_ref(L, LUA_REGISTRY_INDEX);
However I dont think lua_loadstring will do "the right thing".
Am I left with what feels to me like a horrible hack?
void push_lua_function_from_string( lua_State * L, std::string code )
{
// Wrap our string so that we can get something useful for luaL_loadstring
std::string wrapped_code = "return "+code;
luaL_loadstring(L, wrapped_code.c_str());
lua_pcall( L, 0, 1, 0 );
}
push_lua_function_from_string(L, "function(arg) return arg*5 end" );
int reg_index = luaL_ref(L, LUA_REGISTRY_INDEX);
Is there a better solution?
If you need access to parameters, the way you have written is correct. lua_loadstring returns a function that represents the chunk/code you are compiling. If you want to actually get a function back from the code, you have to return it. I also do this (in Lua) for little "expression evaluators", and I don't consider it a "horrible hack" :)
If you only need some callbacks, without any parameters, you can directly write the code and use the function returned by lua_tostring. You can even pass parameters to this chunk, it will be accessible as the ... expression. Then you can get the parameters as:
local arg1, arg2 = ...
-- rest of code
You decide what is better for you - "ugly code" inside your library codebase, or "ugly code" in your Lua functions.
Have a look at my ae. It caches functions from expressions so you can simply say ae_eval("a*x^2+b*x+c") and it'll only compile it once.
I'm working on some ActionScript code that needs to juggle a bunch of similar-but-not-interchangeable types (eg, position-in-pixels, internal-position, row-and-column-position) and I'm trying to come up with a naming scheme to minimize the complexity.
Additionally, I don't yet know what the best format for the "internal position" is – using int, uint and Number all have advantages and disadvantages.
Normally I'd solve this with a typedef:
typedef float pixelPos;
typedef int internalPos;
typedef int rowColPos;
Is there any way of getting similar functionality in ActionScript?
If you're using Flex or another command-line compiler to build your project, you could add a pass from an external preprocessor to your build process.
Doesn't get the type-safety, but otherwise appears to do what you want.
I have found an article titled Typedefs in ActionScript 3, which suggests using:
const pixelPos:Class = int;
But that doesn't work – the compiler complains that "Type was not found or was not a compile-time constant: pixelPos" (note: this also happens when I use Object instead of int).
Here is an example of code which doesn't compile:
const pixelPos:Class = int;
function add3(p:pixelPos):void { // <-- type not found on this line
return p + 3;
}
Just make it static const and you can register your own class. Like this:
static const MyClass:Class = int;
And you can't make a variable with this type:
var ert:MyClass; //error
private function ert2():MyClass {}; //error
But you can make an instance:
var ert:* = new MyClass();