I am trying to use the module functionalities from libclang. Here is the context:
I have a clang module defined and a source file that call it:
module.modulemap
module test {
requires cplusplus
header "test.h"
}
test.h :
#pragma once
static inline int foo() { return 1; }
test.cpp :
// Try the following command:
// clang++ -fmodules -fcxx-modules -fmodules-cache-path=./cache_path -c test.cpp
// If you see stuff in the ./cache_path directory, then it works!
#include "test.h"
int main(int, char **) {
return foo();
}
cache_path is at first empty then after the command I can see stuff in it so this is working.
My problem is when I try to use libclang to parse the test.cpp file in order to get informations about module:
#include <stdio.h>
#include "clang-c/Index.h"
/*
compile with:
clang -lclang -o module_parser module_parser.c
*/
static enum CXChildVisitResult
visitor(CXCursor cursor, CXCursor parent, CXClientData data)
{
CXSourceLocation loc;
CXFile file;
CXString module_import;
CXModule module;
CXString module_name;
CXString module_full_name;
unsigned line;
unsigned column;
unsigned offset;
if (clang_getCursorKind(cursor) == CXCursor_ModuleImportDecl)
{
loc = clang_getCursorLocation(cursor);
clang_getSpellingLocation(loc,
&file,
&line,
&column,
&offset);
module_import = clang_getCursorSpelling(cursor);
printf("Module import dec at line: %d \"%s\"\n", line, clang_getCString(module_import));
clang_disposeString(module_import);
}
module = clang_Cursor_getModule(cursor);
module_name = clang_Module_getName(module);
module_full_name = clang_Module_getFullName(module);
printf("Module name %s , full name %s\n", clang_getCString(module_name),
clang_getCString(module_full_name));
clang_disposeString(module_name);
clang_disposeString(module_full_name);
return CXChildVisit_Recurse; // visit complete AST recursivly
}
int main(int argc, char *argv[]) {
CXIndex Index = clang_createIndex(0, 1);
const char *args[] = { "-x",
"c++",
"-fmodules",
"-fcxxmodules"//,
"-fmodules-cache-path",
"cache_path"
};
CXTranslationUnit TU = clang_createTranslationUnitFromSourceFile(Index,
"test.cpp",
6,
args,
0,
0);
clang_visitChildren(clang_getTranslationUnitCursor(TU), visitor, 0);
clang_disposeTranslationUnit(TU);
clang_disposeIndex(Index);
return 0;
}
The output of this code is :
...
Module name , full name
Module name , full name
Module name , full name
Module name , full name
Module name , full name
...
First it seems that clang doesn't detect any cursor of the kind CXCursor_ModuleImportDecl and then at any momment it find a valid module.
What am I doing wrong?
Related
I im writing sqlite3 wrapper with class to read db file. I im using ubuntu 64-bit and g++ compiler...and when i run code above i get this:
g++ ezserver.cpp -lsqlite3 -o ezserver
ezserver.cpp: In function int main():
ezserver.cpp:7:2: error: DataBase was not declared in this scope
DataBase = new EZServer();
^
database.h
#ifndef DATABASE_H
#define DATABASE_H
/* LIBRARY */
#include <sqlite3.h>
/* CLASS */
class EZServer {
public:
EZServer();
~EZServer();
int OpenDataBase(const char *TFileName);
int CreateDataBase(const char *TFileName);
private:
sqlite3 *DataBase;
sqlite3_stmt *QueryHandle[2];
};
#endif
database.cpp
#include "database.h"
/* CONSTRUCTOR */
EZServer::EZServer(): DataBase(0) {
QueryHandle[0] = NULL;
QueryHandle[1] = NULL;
}
/* DESTRUCTOR */
EZServer::~EZServer() {
/* CLOSE - database */
if (DataBase) {
sqlite3_close(DataBase);
}
}
/* LOAD - database file */
int EZServer::OpenDataBase(const char *TFileName) {
/* OPEN - database */
int Result = sqlite3_open_v2(TFileName, &DataBase, SQLITE_OPEN_READWRITE, NULL);
/* CHECK - database */
if (Result != SQLITE_OK) {
printf("OpenDataBase: %s\n", sqlite3_errmsg(DataBase));
sqlite3_close(DataBase);
return 0;
}
return 1;
}
/* CREATE - database file */
int EZServer::CreateDataBase(const char *TFileName) {
/* OPEN - database */
int Result = sqlite3_open_v2(TFileName, %DataBase, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
/* CHECK - database */
if (Result != SQLITE_OK) {
printf("OpenDataBaseCreate: %s\n", sqlite3_errmsg(DataBase));
sqlite3_close(DataBase);
return 0;
}
return 1;
}
ezserver.h
#ifndef EZSERVER_H
#define EZSERVER_H
/* FORWARD - declarations */
class EZServer;
/* CLASS */
class StatsClass {
public:
int Init();
private:
EZServer *DataBase;
};
#endif
ezserver.cpp
#include "ezserver.h"
#include "database.h"
int main() {
DataBase = new EZServer();
}
main file is ezserver.cpp.
i im beginner in c++ so i read posts here try solutions but always get DataBase was not declared in this scope...could some one give solution?
Thanks.
EDIT:
I need to call EZServer() class name that holds functions like OpenDataBase CreateDataBase.
// Load database that opens save and query
Database = new EZServer();
Database->OpenDatabase("ezserver.db");
so i need this above ->OpenDataBase to be called from EZServer.cpp (main file program) and return from class EZServer value that function is defined in database.cpp
I found another problem, you should compile all *.cpp files.
g++ ezserver.cpp database.cpp -lsqlite3 -o ezserver
here is log when i run this:
g++ ezserver.cpp database.cpp -lsqlite3 -o ezserver database.cpp:4:20:
error: definition of implicitly-declared ‘EZServer::EZServer()’
EZServer::EZServer(): DataBase(0) { ^ database.cpp:10:21: error:
definition of implicitly-declared ‘EZServer::~EZServer()’
EZServer::~EZServer() { ^ database.cpp: In member function ‘int
EZServer::OpenDataBase(const char*)’: database.cpp:20:76: error:
‘NULL’ was not declared in this scope int Result =
sqlite3_open_v2(TFileName, &DataBase, SQLITE_OPEN_READWRITE, NULL); ^
database.cpp:24:56: error: ‘printf’ was not declared in this scope
printf("OpenDataBase: %s\n", sqlite3_errmsg(DataBase)); ^
database.cpp: In member function ‘int EZServer::CreateDataBase(const
char*)’: database.cpp:34:42: error: expected primary-expression
before ‘%’ token int Result = sqlite3_open_v2(TFileName,
%DataBase, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); ^
database.cpp:34:97: error: ‘NULL’ was not declared in this scope
int Result = sqlite3_open_v2(TFileName, %DataBase,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); ^
database.cpp:38:62: error: ‘printf’ was not declared in this scope
printf("OpenDataBaseCreate: %s\n", sqlite3_errmsg(DataBase)); ^
Maybe you should write something like this:
EZServer* dataBase = new EZServer();
dataBase->OpenDataBase("ezserver.db");
Both tools are available over here: https://github.com/ninjablocks/433Utils/tree/master/RPi_utils
I really want a simple interface to manage my 433mhz devices. but i can't find a good one.
So I have worked all day now trying to make a wrapper for nodejs to the RCSwitch class. with 2 simple methods
- send[code]
- recieve[callback[code]]
I get this error when i try to make a new instance of the RCSwitch class.
node: symbol lookup error:
/root/nodemodule/example/build/Release/kaku.node:
undefined symbol: _ZN8RCSwitchC1Ev
It compiles perfectly with node-gyp but when I execute node it fails.
Now I use exec to execute sendCommand with the code. (UGLY I Know)
And I tried to make the RFSniffer work like this:
./RFSniffer > rfsniffer.log
.Then tail -f the rfsniffer.log
But RFSniffer wont give me any data.
So my question is can anybody help me to get RFsniffer working with tail -f
Or even beter can someone help me fix the c++ addon for nodejs:)
Here is the wrapper code:
#include "RCSwitch.h"
#include <node.h>
#include <v8.h>
using namespace v8;
Handle<Value> CodeSend(const Arguments& args) {
HandleScope scope;
int PIN = 0;
RCSwitch mySwitch = RCSwitch();
mySwitch.enableTransmit(PIN);
mySwitch.send(args[0]->IntegerValue(), 24);
return scope.Close(True());
}
Handle<Value> CodeRecieve(const Arguments& args) {
HandleScope scope;
// Entry check
if (args.Length() != 2) {
ThrowException(Exception::TypeError(String::New("Wrong number of arguments")));
return scope.Close(Undefined());
}
Local<String> name= args[0]->ToString();
Local<String> msg = name;
Local<Function> cb = Local<Function>::Cast(args[1]);
const unsigned argc = 1;
Local<Value> argv[argc] = { Local<Value>::New(msg) };
cb->Call(Context::GetCurrent()->Global(), argc, argv);
return scope.Close(Undefined());
}
extern "C" {
static void init(Handle<Object> target) {
if( wiringPiSetup() == -1 ) {
ThrowException( Exception::TypeError( String::New( "rcswitch: GPIO initialization failed" ) ) );
return;
}
NODE_SET_METHOD(target, "Send", CodeSend);
NODE_SET_METHOD(target, "Recieve", CodeRecieve);
}
NODE_MODULE(kaku, init);
}
nodejs code:
var addon = require('./build/Release/kaku');
console.log(addon.Send(1234));
addon.Recieve(1234, function (val) {
console.log(val);
});
I had the same problem than you and the reason why ./RFSniffer > rfsniffer.log doesn't work is that printf() function in RFSniffer code is not flushed.
Try with this source code :
/*
RF_Sniffer
Hacked from http://code.google.com/p/rc-switch/
by #justy to provide a handy RF code sniffer
*/
#include "RCSwitch.h"
#include <stdlib.h>
#include <stdio.h>
RCSwitch mySwitch;
int main(int argc, char *argv[]) {
// This pin is not the first pin on the RPi GPIO header!
// Consult https://projects.drogon.net/raspberry-pi/wiringpi/pins/
// for more information.
int PIN = 2;
if(wiringPiSetup() == -1)
return 0;
mySwitch = RCSwitch();
mySwitch.enableReceive(PIN); // Receiver on inerrupt 0 => that is pin #2
while(1) {
if (mySwitch.available()) {
int value = mySwitch.getReceivedValue();
if (value == 0) {
printf("Unknown encoding");
} else {
printf("Received %i\n", mySwitch.getReceivedValue() );
}
fflush(stdout); // Add this line to flush the previous printf()
mySwitch.resetAvailable();
}
}
exit(0);
}
And if you run the RFSniffer tool with sudo permission, you can execute with :
sudo ./RFSniffer | sudo tee rfsniffer.log
OR
sudo sh -c './RFSniffer >> rfsniffer.log'
I have some functions declared and initialized in .lua file. Then, when I receive signal, I read string_t variable with the name of function to call from file. The problem is that I don't know how to push function to stack by its name or call it.
For example:
test.lua
function iLoveVodka()
--some text
end
function iLoveFish()
--another text
end
C File:
string_t a = "iLoveVodka()"
How can i call function from C/C++ code iLoveVodka() only by having its name?
Here is some sample code that does two things:
Loads the file "test.lua" from the same directory.
Tries to call the function iLoveVodka(), if it can be found.
You should be able to build this easily enough:
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char *argv[])
{
lua_State *l = luaL_newstate ();
luaL_openlibs (l);
int error = luaL_dofile (l, "test.lua");
if (error)
{
printf( "Error loading test.lua: %s\n",luaL_checkstring (l, -1) );
exit(1);
}
/**
* Get the function and call it
*/
lua_getglobal(l, "iLoveVodka");
if ( lua_isnil(l,-1) )
{
printf("Failed to find global function iLoveVodka\n" );
exit(1);
}
lua_pcall(l,0,0,0);
/**
* Cleanup.
*/
lua_close (l);
return 0;
}
This can be compiled like this:
gcc -O -o test `pkg-config --libs --cflags lua5.1` test.c
Just define your iLoveVodka() function inside test.lua, and you should be OK.
I'm trying to extend Python 3 using instructions given here and I'm fairly confident I've followed the instructions correctly so far, but it asks me to include this code:
PyMODINIT_FUNC
PyInit_spam(void)
{
PyObject *m;
m = PyModule_Create(&spammodule);
if (m == NULL)
return NULL;
SpamError = PyErr_NewException("spam.error", NULL, NULL);
Py_INCREF(SpamError);
PyModule_AddObject(m, "error", SpamError);
return m;
}
I'm writing this in MSVC++ 2010 and it's warning me that &spammodule is undefined (the name of the module is spammodule.cpp), but it doesn't define it anywhere in the instructions so I assume that it should recognise it automatically as the name of the module.
The full code is:
#include <Python.h>
#include <iostream>
using namespace std;
static PyObject *SpamError;
int main()
{
cout << "Test" << endl;
system("PAUSE");
return(0);
}
static PyObject *spam_system(PyObject *self, PyObject *args)
{
const char *command;
int sts;
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
return PyLong_FromLong(sts);
}
PyMODINIT_FUNC
PyInit_spam(void)
{
PyObject *m;
m = PyModule_Create(&spammodule);
if (m == NULL)
return NULL;
SpamError = PyErr_NewException("spam.error", NULL, NULL);
Py_INCREF(SpamError);
PyModule_AddObject(m, "error", SpamError);
return m;
}
You're still writing C++, so you still need to declare spammodule somewhere. This is given later on the same page:
static struct PyModuleDef spammodule = {
PyModuleDef_HEAD_INIT,
"spam", /* name of module */
spam_doc, /* module documentation, may be NULL */
-1, /* size of per-interpreter state of the module,
or -1 if the module keeps state in global variables. */
SpamMethods
};
No no no, PyModule_Create() accepts a pointer to the module definition structure and has absolutely nothing to do with the name of the source file.
i would like to use the code generated by lex in another code that i have , but all the examples that i have seen is embedding the main function inside the lex file not the opposite.
is it possible to use(include) the c generated file from lex into other code that to have something like this (not necessarily the same) ?
#include<something>
int main(){
Lexer l = Lexer("some string or input file");
while (l.has_next()){
Token * token = l.get_next_token();
//somecode
}
//where token is just a simple object to hold the token type and lexeme
return 0;
}
This is what I would start with:
Note: this is an example of using a C interface
To use the C++ interface add %option c++ See below
Test.lex
IdentPart1 [A-Za-z_]
Identifier {IdentPart1}[A-Za-z_0-9]*
WHITESPACE [ \t\r\n]
%option noyywrap
%%
{Identifier} {return 257;}
{WHITESPACE} {/* Ignore */}
. {return 258;}
%%
// This is the bit you want.
// It is best just to put this at the bottom of the lex file
// By default functions are extern. So you can create a header file with
// these as extern then included that header file in your code (See Lexer.h)
void* setUpBuffer(char const* text)
{
YY_BUFFER_STATE buffer = yy_scan_string(text);
yy_switch_to_buffer(buffer);
return buffer;
}
void tearDownBuffer(void* buffer)
{
yy_delete_buffer((YY_BUFFER_STATE)buffer);
}
Lexer.h
#ifndef LOKI_A_LEXER_H
#define LOKI_A_LEXER_H
#include <string>
extern int yylex();
extern char* yytext;
extern int yyleng;
// Here is the interface to the lexer you set up above
extern void* setUpBuffer(char const* text);
extern void tearDownBuffer(void* buffer);
class Lexer
{
std::string token;
std::string text;
void* buffer;
public:
Lexer(std::string const& t)
: text(t)
{
// Use the interface to set up the buffer
buffer = setUpBuffer(text.c_str());
}
~Lexer()
{
// Tear down your interface
tearDownBuffer(buffer);
}
// Don't use RAW pointers
// This is only a quick and dirty example.
bool nextToken()
{
int val = yylex();
if (val != 0)
{
token = std::string(yytext, yyleng);
}
return val;
}
std::string const& theToken() const {return token;}
};
#endif
main.cpp
#include "Lexer.h"
#include <iostream>
int main()
{
Lexer l("some string or input file");
// Did not like your hasToken() interface.
// Just call nextToken() until it fails.
while (l.nextToken())
{
std::cout << l.theToken() << "\n";
delete token;
}
//where token is just a simple object to hold the token type and lexeme
return 0;
}
Build
> flext test.lex
> g++ main.cpp lex.yy.c
> ./a.out
some
string
or
input
file
>
Alternatively you can use the C++ interface to flex (its experimental)
test.lext
%option c++
IdentPart1 [A-Za-z_]
Identifier {IdentPart1}[A-Za-z_0-9]*
WHITESPACE [ \t\r\n]
%%
{Identifier} {return 257;}
{WHITESPACE} {/* Ignore */}
. {return 258;}
%%
// Note this needs to be here
// If you define no yywrap() in the options it gets added to the header file
// which leads to multiple definitions if you are not careful.
int yyFlexLexer::yywrap() { return 1;}
main.cpp
#include "MyLexer.h"
#include <iostream>
#include <sstream>
int main()
{
std::istringstream data("some string or input file");
yyFlexLexer l(&data, &std::cout);
while (l.yylex())
{
std::cout << std::string(l.YYText(), l.YYLeng()) << "\n";
}
//where token is just a simple object to hold the token type and lexeme
return 0;
}
build
> flex --header-file=MyLexer.h test.lex
> g++ main.cpp lex.yy.cc
> ./a.out
some
string
or
input
file
>
Sure. I'm not sure about the generated class; we use the C generated
parsers, and call them from C++. Or you can insert any sort of wrapper
code you want in the lex file, and call anything there from outside of
the generated file.
The keywords are %option reentrant or %option c++.
As an example here's the ncr2a scanner:
/** ncr2a_lex.l: Replace all NCRs by corresponding printable ASCII characters. */
%%
&#(1([01][0-9]|2[0-6])|3[2-9]|[4-9][0-9]); { /* accept 32..126 */
/** `+2` skips '&#', `atoi()` ignores ';' at the end */
fputc(atoi(yytext + 2), yyout); /* non-recursive version */
}
The scanner code can be left unchanged.
Here the program that uses it:
/** ncr2a.c */
#include "ncr2a_lex.h"
typedef struct {
int i,j; /** put here whatever you need to keep extra state */
} State;
int main () {
yyscan_t scanner;
State my_custom_data = {0,0};
yylex_init(&scanner);
yyset_extra(&my_custom_data, scanner);
yylex(scanner);
yylex_destroy(scanner);
return 0;
}
To build ncr2a executable:
flex -R -oncr2a_lex.c --header-file=ncr2a_lex.h ncr2a_lex.l
cc -c -o ncr2a_lex.o ncr2a_lex.c
cc -o ncr2a ncr2a_lex.o ncr2a.c -lfl
Example
$ echo 'three colons :::' | ./ncr2a
three colons :::
This example uses stdin/stdout as input/output and it calls yylex() once.
To read from a file:
yyin = fopen("input.txt", "r" );
#Loki Astari's answer shows how to read from a string (buffer = yy_scan_string(text, scanner); yy_switch_to_buffer(buffer, scanner))
.
To call yylex() once for each token add return inside rule definitions that yield full token in the *.l file.