ctags generator for CORBA IDL? - vim

I work in a multi-language environment and use Vim + ctags for navigating the code. However we also use CORBA and exuberant ctags does not parse IDL files.
Does anyone know of a ctags compatible tags generator for IDL?

If you use a simple regexp parser then it is a fairly trivial exercise to extend Exuberant Ctags to support another language.
For example, below is an example of a regexp parser taken from the Exuberant Ctags parser page:
/***************************************************************************
* make.c
* Regex-based parser for makefile macros
**************************************************************************/
/* INCLUDE FILES */
#include "general.h" /* always include first */
#include "parse.h" /* always include */
/* FUNCTION DEFINITIONS */
static void installMakefileRegex (const langType language)
{
addTagRegex (language, "(^|[ \t])([A-Z0-9_]+)[ \t]*:?=", "\\2", "m,macro", "i");
}
/* Create parser definition stucture */
extern parserDefinition* MakefileParser (void)
{
static const char *const patterns [] = { "[Mm]akefile", NULL };
static const char *const extensions [] = { "mak", NULL };
parserDefinition* const def = parserNew ("Makefile");
def->patterns = patterns;
def->extensions = extensions;
def->initialize = installMakefileRegex;
def->regex = TRUE;
return def;
}

It's quite easy to add another language to ctags using a few regular expressions and the ctags configuration file.

Related

Quickly (un)comment blocks of code in Rust

In languages such as Java, I often use the following pattern for quickly commenting/uncommenting whole blocks of code:
/* *
hello.world();
/* */
// I just have to add one '/' and the block is uncommented:
/* */
hello.world();
/* */
However, in Rust, the above code creates a syntax error, as it is not allowed to have unequal numbers of /* and */ in a Rust file.
But is there a similar way for quickly commenting/uncommenting blocks in Rust that does not involve using editor macro-commands?
You can use single-line comments to activate/deactivate your multi-lines comment, e.g.
/*
commented_out();
// */
//*
not_commented();
// */

Visual C++ lambdas always output debug information

If I instantiate a lambda somewhere (and the compiler doesn't inline it), I can find a string showing where the lambda is located in my c++ code like this:
... ?AV<lambda_1>#?0??MyFunction#MyScopedClass#MyNamespace##SAXXZ# ...
I don't want this information in the executable, as it could give away important names of classes and functions.
All kinds of output debug information are turned off. If I use a normal function instead, the final executable doesn't have this information, so manually converting all lambdas into normal functions would "fix it". But what's the best way to handle this? Can we tell the compiler to transform lambdas into normal functions?
UPDATE: I tested with other compilers: g++ and clang. They both leave the same references. I also found another unanswered question about this Gcc - why are lambdas not stripped during release build Please don't come with the "why do you care about a few symbols anyway".
Here's some code you can test with:
#include <iostream>
#include <functional>
class MyUnscopedClass
{
public:
MyUnscopedClass(const std::function<void(int x)>& f) :
f(f)
{
}
std::function<void(int x)> f;
};
namespace MyNamespace
{
class MyScopedClass
{
public:
static void temp1(int x)
{
std::cout << x * (x + 1);
}
static void MyFunction()
{
//MyUnscopedClass obj(temp1); // no symbols
MyUnscopedClass obj([](int x) // ?AV<lambda_1>#?0??MyFunction#MyScopedClass#MyNamespace##SAXXZ#
{
std::cout << x;
});
obj.f(23);
}
};
}
int main()
{
MyNamespace::MyScopedClass::MyFunction();
}
With the help of #dxiv in the comments, I found the problematic setting.
Configuration Properties > General > C++ Language Standard
can't be, for some reason,
Preview - Features from the Latest C++ Working Draft (std:c++latest)
So I set it to the second most recent one
ISO C++17 Standard (std:c++17)
and I get a random identifier instead.
AV<lambda_f65614ace4683bbc78b79ad57f781b7f>##
I'm still curious how this identifier is chosen though.

Unable to initialize static set of strings inside templatized class in CLang, works fine in GCC

I'm using Boost config_file_iterator to parse a parameters file for different modules in the standard Boost way:
[Module 1 name]
M1_Key1=value1
[Module 2 name]
M2_Key1=value2
For that, Boost has the nice feature to accept a std::set containing all the valid keys, to throw an exception in case a non-valid one is passed.
boost::program_options::detail::config_file_iterator cfgIt(configStream, ALLOWED_PARAMS);
In my code, I've a set of modules, each one with its own set of parameters, In each one of the module header I have (as non-member variables):
module1.h:
static const std::string MODULE1_NAME = "Module 1 name";
static const std::string MODULE1_KEY1 = "M1_Key1";
module2.h:
static const std::string MODULE2_NAME = "Module 2 name";
static const std::string MODULE2_KEY1 = "M2_Key1";
In the header file for the parameters parser:
class ParametersParser
{
static const std::set<std::string> ALLOWED_PARAMS;
}
Finally in the source file of that parameter parser groups all the allowed values for the config iterator from the different modules:
#include "module1.h"
#include "module2.h"
const std::set<std::string> ParametersParser::ALLOWED_PARAMS =
{{
MODULE1_NAME + std::string(".") + MODULE1_KEY1,
MODULE2_NAME + std::string(".") + MODULE2_KEY1
}};
since Boost expects that as the allowed parameters set, a set of string of the way "Module X Name.MX_KeyY", and that worked fine.
However, because of other reasons, I've templatized the class that parses the file, so now my set of strings is declared also in the same header file, as:
#include "module1.h"
#include "module2.h"
/* Class definition */
template <class T>
class ParametersParser
{
static const std::set<std::string> ALLOWED_PARAMS;
};
/* Static member initialization */
template <class T>
const std::set<std::string> ParametersParser<T>::ALLOWED_PARAMS =
{{
MODULE1_NAME + std::string(".") + MODULE1_KEY1,
MODULE2_NAME + std::string(".") + MODULE2_KEY1
}};
And here is where the problem arises: This compiles in both gcc 4.8.5 (CentOS 7.5 vanilla) and AppleClang 9.1.0.9020039 (MacOSX 10.3), but in MacOSX, the resulting set only contains a ".". It's like the static strings defined in the modules headers (MODULE1_NAME, MODULE1_KEY1, etc) are empty!!! In gcc/CentOS, it works fine. Unfortunately, I couldn't compile on gcc for MacOSX (It complains about unresolved dependencies with Boost), while CLang on CentOS (Apple LLVM version 9.1.0 (clang-902.0.39.2)) works fine too.
Do you have any clues what am I doing wrong? Is it something about using strings as static variables? I also tried declaring the set using the new initializer list syntax, const std::set<std::string> ParametersParser<T>::ALLOWED_PARAMS{{...}}, but didn't work either.
Thanks a lot for your help.

Unicode conversion in C++17 [duplicate]

A bit of foreground: my task required converting UTF-8 XML file to UTF-16 (with proper header, of course). And so I searched about usual ways of converting UTF-8 to UTF-16, and found out that one should use templates from <codecvt>.
But now when it is deprecated, I wonder what is the new common way of doing the same task?
(Don't mind using Boost at all, but other than that I prefer to stay as close to standard library as possible.)
Don't worry about that.
According to the same information source:
this library component should be retired to Annex D, along side ,
until a suitable replacement is standardized.
So, you can still use it until a new standardized, more-secure version is done.
std::codecvt template from <locale> itself isn't deprecated. For UTF-8 to UTF-16, there is still std::codecvt<char16_t, char, std::mbstate_t> specialization.
However, since std::wstring_convert and std::wbuffer_convert are deprecated along with the standard conversion facets, there isn't any easy way to convert strings using the facets.
So, as Bolas already answered: Implement it yourself (or you can use a third party library, as always) or keep using the deprecated API.
Since nobody really answers the question and provides usable replacement code, here is one but it's only for Windows:
#include <string>
#include <stdexcept>
#include <Windows.h>
std::wstring string_to_wide_string(const std::string& string)
{
if (string.empty())
{
return L"";
}
const auto size_needed = MultiByteToWideChar(CP_UTF8, 0, &string.at(0), (int)string.size(), nullptr, 0);
if (size_needed <= 0)
{
throw std::runtime_error("MultiByteToWideChar() failed: " + std::to_string(size_needed));
}
std::wstring result(size_needed, 0);
MultiByteToWideChar(CP_UTF8, 0, &string.at(0), (int)string.size(), &result.at(0), size_needed);
return result;
}
std::string wide_string_to_string(const std::wstring& wide_string)
{
if (wide_string.empty())
{
return "";
}
const auto size_needed = WideCharToMultiByte(CP_UTF8, 0, &wide_string.at(0), (int)wide_string.size(), nullptr, 0, nullptr, nullptr);
if (size_needed <= 0)
{
throw std::runtime_error("WideCharToMultiByte() failed: " + std::to_string(size_needed));
}
std::string result(size_needed, 0);
WideCharToMultiByte(CP_UTF8, 0, &wide_string.at(0), (int)wide_string.size(), &result.at(0), size_needed, nullptr, nullptr);
return result;
}
The new way is... you write it yourself. Or just rely on deprecated functionality. Hopefully, the standards committee won't actually remove codecvt until there is a functioning replacement.
But at present, there isn't one.

Equivalent of Java Scanner class in Haxe

In the Haxe programming language, is there anything equivalent to Java's scanner class (which reads input from the command line?) I'd like to find some way of reading text input from the command line.
Sys.stdin().readLine() is what you're looking for.
Here's an example from http://haxe.org/doc/start/neko#reading-user-input:
class Main {
static function main() {
Sys.println("What's your name?");
var input = Sys.stdin().readLine();
Sys.println(Std.format("Hello ${input}"));
Sys.exit(0);
}
}

Resources