Interfacing readline into Rust - readline

I try to do this tutorial in rust, so far I have a lot of problems interfacing the C library into Rust.
C equivalent code:
#include <stdio.h>
#include <stdlib.h>
#include <editline/readline.h>
#include <editline/history.h>
int main(int argc, char** argv) {
/* Print Version and Exit Information */
puts("Lispy Version 0.0.0.0.1");
puts("Press Ctrl+c to Exit\n");
/* In a never ending loop */
while (1) {
/* Output our prompt and get input */
char* input = readline("lispy> ");
/* Add input to history */
add_history(input);
/* Echo input back to user */
printf("No you're a %s\n", input);
/* Free retrived input */
free(input);
}
return 0;
}
So far i got this:
extern crate libc;
use std::c_str;
#[link(name = "readline")]
extern {
fn readline (p: *const libc::c_char) -> *const libc::c_char;
}
fn rust_readline (prompt: &str) -> Option<Box<str>> {
let cprmt = prompt.to_c_str();
cprmt.with_ref(|c_buf| {
unsafe {
let ret = c_str::CString::new (readline (c_buf), true);
ret.as_str().map(|ret| ret.to_owned())
}
})
}
fn main() {
println!("Lispy Version 0.0.1");
println!("Press Ctrl+c to Exit.\n");
// I want to have "history" in Linux of this:
//
// loop {
// print!("lispy> ");
// let input = io::stdin().read_line().unwrap();
// print!("No you're a {}", input);
// }
loop {
let val = rust_readline ("lispy> ");
match val {
None => { break }
_ => {
let input = val.unwrap();
println!("No you're a {}", input);
}
}
}
}
Especifically, I'm having issues with rust_readline function, i don't understand very well what's doing inside.

Edit Cargo.toml, put this:
[dependencies.readline]
git = "https://github.com/shaleh/rust-readline"
Code corrected:
extern crate readline;
fn main() {
println!("Lispy Version 0.0.1");
println!("Press Ctrl+c to Exit.\n");
loop {
let input = readline::readline("lispy> ").unwrap();
readline::add_history(input.as_str());
println!("No you're a {}", input);
}
}
Happy Lisping :-) .

Funny thing is, that I found this question reading the very same book, but not including any book specific information in my search query.
There is now a crate for this. Facon's solution worked for me, but the prompt string always printed as garbage using that library, so I looked for another crate and found one working nicely. Here is an updated example:
cargo.toml:
[dependencies]
# https://crates.io/crates/rustyline
rustyline = "3.0.0"
main.rs:
extern crate rustyline;
use rustyline::error::ReadlineError;
use rustyline::Editor;
const HISTORY_FILENAME: &str = "history.txt";
fn main() {
println!("Lispy Version 0.0.1");
println!("Press Ctrl+c to Exit.\n");
// We create an editor for the readline history.
let mut readline_editor = Editor::<()>::new();
// And then load the history, if it exists.
if readline_editor.load_history(HISTORY_FILENAME).is_err() {
println!("No previous history.");
}
loop {
// We read some input from CLI.
let readline = readline_editor.readline("LISPY>> ");
// The reading of the input could fail, if a user uses special
// key combinations. So we match against the readline Result
// type. Result can either be some `Ok` or an some `Err`.
match readline {
Ok(line) => {
readline_editor.add_history_entry(line.as_ref());
println!("No, you are {}", line);
},
Err(ReadlineError::Interrupted) => {
println!("CTRL-C");
break
},
Err(ReadlineError::Eof) => {
println!("CTRL-D");
break
},
Err(err) => {
println!("Error: {:?}", err);
break
}
}
readline_editor.save_history(HISTORY_FILENAME).expect("Could not save to readline history.");
}
}

Related

How to get memory rd/wr trace for a specific function call using PIN tools

I am trying to dump mem rd/wr trace for a specific function call from my application and after researching a bit I came across a solution to do so.
But since I am very new to PIN usage, I am not sure how to pass routine names (refer to Routine(RTN rtn, VOID *v)) from application to pin tools so that the right callback function gets trigerred. Can someone please help?
As of now If I run the given pin tools, my trace.out is empty because "!isROI" is always set to false.
#include <stdio.h>
#include "pin.H"
#include <string>
const CHAR * ROI_BEGIN = "__parsec_roi_begin";
const CHAR * ROI_END = "__parsec_roi_end";
FILE * trace;
bool isROI = false;
// Print a memory read record
VOID RecordMemRead(VOID * ip, VOID * addr, CHAR * rtn)
{
// Return if not in ROI
if(!isROI)
{
return;
}
// Log memory access in CSV
fprintf(trace,"%p,R,%p,%s\n", ip, addr, rtn);
}
// Print a memory write record
VOID RecordMemWrite(VOID * ip, VOID * addr, CHAR * rtn)
{
// Return if not in ROI
if(!isROI)
{
return;
}
// Log memory access in CSV
fprintf(trace,"%p,W,%p,%s\n", ip, addr, rtn);
}
// Set ROI flag
VOID StartROI()
{
isROI = true;
}
// Set ROI flag
VOID StopROI()
{
isROI = false;
}
// Is called for every instruction and instruments reads and writes
VOID Instruction(INS ins, VOID *v)
{
// Instruments memory accesses using a predicated call, i.e.
// the instrumentation is called iff the instruction will actually be executed.
//
// On the IA-32 and Intel(R) 64 architectures conditional moves and REP
// prefixed instructions appear as predicated instructions in Pin.
UINT32 memOperands = INS_MemoryOperandCount(ins);
// Iterate over each memory operand of the instruction.
for (UINT32 memOp = 0; memOp < memOperands; memOp++)
{
// Get routine name if valid
const CHAR * name = "invalid";
if(RTN_Valid(INS_Rtn(ins)))
{
name = RTN_Name(INS_Rtn(ins)).c_str();
}
if (INS_MemoryOperandIsRead(ins, memOp))
{
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead,
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
IARG_ADDRINT, name,
IARG_END);
}
// Note that in some architectures a single memory operand can be
// both read and written (for instance incl (%eax) on IA-32)
// In that case we instrument it once for read and once for write.
if (INS_MemoryOperandIsWritten(ins, memOp))
{
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite,
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
IARG_ADDRINT, name,
IARG_END);
}
}
}
// Pin calls this function every time a new rtn is executed
VOID Routine(RTN rtn, VOID *v)
{
// Get routine name
const CHAR * name = RTN_Name(rtn).c_str();
if(strcmp(name,ROI_BEGIN) == 0) {
// Start tracing after ROI begin exec
RTN_Open(rtn);
RTN_InsertCall(rtn, IPOINT_AFTER, (AFUNPTR)StartROI, IARG_END);
RTN_Close(rtn);
} else if (strcmp(name,ROI_END) == 0) {
// Stop tracing before ROI end exec
RTN_Open(rtn);
RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)StopROI, IARG_END);
RTN_Close(rtn);
}
}
// Pin calls this function at the end
VOID Fini(INT32 code, VOID *v)
{
fclose(trace);
}
/* ===================================================================== */
/* Print Help Message */
/* ===================================================================== */
INT32 Usage()
{
PIN_ERROR( "This Pintool prints a trace of memory addresses\n"
+ KNOB_BASE::StringKnobSummary() + "\n");
return -1;
}
/* ===================================================================== */
/* Main */
/* ===================================================================== */
int main(int argc, char *argv[])
{
// Initialize symbol table code, needed for rtn instrumentation
PIN_InitSymbols();
// Usage
if (PIN_Init(argc, argv)) return Usage();
// Open trace file and write header
trace = fopen("roitrace.csv", "w");
fprintf(trace,"pc,rw,addr,rtn\n");
// Add instrument functions
RTN_AddInstrumentFunction(Routine, 0);
INS_AddInstrumentFunction(Instruction, 0);
PIN_AddFiniFunction(Fini, 0);
// Never returns
PIN_StartProgram();
return 0;
}

Is there a simple way to convert a lua table to a C++ array or vector?

I am starting to make my own package manager and am starting to develop a dependency system.
The builfiles are written in lua, they look something like this:
package = {
name = "pfetch",
version = "0.6.0",
source = "https://github.com/dylanaraps/pfetch/archive/0.6.0.tar.gz",
git = false
}
dependencies = {
"some_dep",
"some_dep2"
}
function install()
quantum_install("pfetch", false)
end
Only problem,I have no idea how to convert
dependencies = {
"some_dep",
"some_dep2"
}
To a global c++ array: ["some_dep", "some_dep2"]
Anything in the list that's not valid as a string should be ignored.
Any good way to do this?
Thanks in advance
Note: I am using the C api to interface with lua in C++. I don't know whether Lua's errors use longjmp or C++ exceptions.
Based on the clarification in your comment, something like this will work for you:
#include <iostream>
#include <string>
#include <vector>
#include <lua5.3/lua.hpp>
std::vector<std::string> dependencies;
static int q64795651_set_dependencies(lua_State *L) {
dependencies.clear();
lua_settop(L, 1);
for(lua_Integer i = 1; lua_geti(L, 1, i) != LUA_TNIL; ++i) {
size_t len;
const char *str = lua_tolstring(L, 2, &len);
if(str) {
dependencies.push_back(std::string{str, len});
}
lua_settop(L, 1);
}
return 0;
}
static int q64795651_print_dependencies(lua_State *) {
for(const auto &dep : dependencies) {
std::cout << dep << std::endl;
}
return 0;
}
static const luaL_Reg q64795651lib[] = {
{"set_dependencies", q64795651_set_dependencies},
{"print_dependencies", q64795651_print_dependencies},
{nullptr, nullptr}
};
extern "C"
int luaopen_q64795651(lua_State *L) {
luaL_newlib(L, q64795651lib);
return 1;
}
Demo:
$ g++ -fPIC -shared q64795651.cpp -o q64795651.so
$ lua5.3
Lua 5.3.3 Copyright (C) 1994-2016 Lua.org, PUC-Rio
> q64795651 = require('q64795651')
> dependencies = {
>> "some_dep",
>> "some_dep2"
>> }
> q64795651.set_dependencies(dependencies)
> q64795651.print_dependencies()
some_dep
some_dep2
>
One important pitfall: since you're not sure if Lua is compiled to use longjmp or exceptions for its errors, you need to make sure that you don't have any automatic variables with destructors anywhere that a Lua error could happen. (This is already the case in the code in my answer; just make sure you don't accidentally add any such places when incorporating this into your program.)

Lua 'require' but files are only in memory

Setting: I'm using Lua from a C/C++ environment.
I have several lua files on disk. Those are read into memory and some more memory-only lua files become available during runtime. Think e.g. of an editor, with additional unsaved lua files.
So, I have a list<identifier, lua_file_content> in memory. Some of these files have require statements in them. When I try to load all these files to a lua instance (currently via lua_dostring) I get attempt to call global require (a nil value).
Is there a possibility to provide a require function, which replaces the old one and just uses the provided in memory files (those files are on the C side)?
Is there another way of allowing require in these files without having the required files on disk?
An example would be to load the lua stdlib from memory only without altering it. (This is actually my test case.)
Instead of replacing require, why not add a function to package.loaders? The code is nearly the same.
int my_loader(lua_State* state) {
// get the module name
const char* name = lua_tostring(state);
// find if you have such module loaded
if (mymodules.find(name) != mymodules.end())
{
luaL_loadbuffer(state, buffer, size, name);
// the chunk is now at the top of the stack
return 1;
}
// didn't find anything
return 0;
}
// When you load the lua state, insert this into package.loaders
http://www.lua.org/manual/5.1/manual.html#pdf-package.loaders
A pretty straightforward C++ function that would mimic require could be: (pseudocode)
int my_require(lua_State* state) {
// get the module name
const char* name = lua_tostring(state);
// find if you have such module loaded
if (mymodules.find(name) != mymodules.end())
luaL_loadbuffer(state, buffer, size, name);
// the chunk is now at the top of the stack
lua_call(state)
return 1;
}
Expose this function to Lua as require and you're good to go.
I'd also like to add that to completely mimic require's behaviour, you'd probably need to take care of package.loaded, to avoid the code to be loaded twice.
There is no package.loaders in lua 5.2
It called package.searchers now.
#include <stdio.h>
#include <string>
#include <lua.hpp>
std::string module_script;
int MyLoader(lua_State *L)
{
const char *name = luaL_checkstring(L, 1); // Module name
// std::string result = SearchScript(name); // Search your database.
std::string result = module_script; // Just for demo.
if( luaL_loadbuffer(L, result.c_str(), result.size(), name) )
{
printf("%s", lua_tostring(L, -1));
lua_pop(L, 1);
}
return 1;
}
void SetLoader(lua_State* L)
{
lua_register(L, "my_loader", MyLoader);
std::string str;
// str += "table.insert(package.loaders, 2, my_loader) \n"; // Older than lua v5.2
str += "table.insert(package.searchers, 2, my_loader) \n";
luaL_dostring(L, str.c_str());
}
void SetModule()
{
std::string str;
str += "print([[It is add.lua]]) \n";
str += "return { func = function() print([[message from add.lua]]) end } \n";
module_script=str;
}
void LoadMainScript(lua_State* L)
{
std::string str;
str += "dev = require [[add]] \n";
str += "print([[It is main.lua]]) \n";
str += "dev.func() \n";
if ( luaL_loadbuffer(L, str.c_str(), str.size(), "main") )
{
printf("%s", lua_tostring(L, -1));
lua_pop(L, 1);
return;
}
}
int main()
{
lua_State* L = luaL_newstate();
luaL_openlibs(L);
SetModule(L); // Write down module in memory. Lua not load it yet.
SetLoader(L);
LoadMainScript(L);
lua_pcall(L,0,0,0);
lua_close(L);
return 0;
}

Unable to setting up the Gecko SDK with Visual Studio 2010

I am creating simple XPCOM plugin for firefox by using the code from.
blog.peschla.net code is straight forward but Im getting following error:
Error 1 error MSB3073: The command "xpidl-build.bat IHelloWorld.idl
:VCEnd" exited with code 1. C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets 103 6 HelloWorld
I am using firefox 22 hence gecko-sdk version 22 and vs2010
I used following files.
I have given link above which contains all the code but I am giving code below as well
1)HelloWorld.h
#include "HelloWorld.h"
NS_IMPL_ISUPPORTS1(HelloWorld, IHelloWorld)
HelloWorld::HelloWorld()
{
mName.Assign(L"Nameless");
}
HelloWorld::~HelloWorld(){}
/* attribute AString name; */
NS_IMETHODIMP HelloWorld::GetName(nsAString & aName)
{
aName.Assign(mName);
return NS_OK;
}
NS_IMETHODIMP HelloWorld::SetName(const nsAString & aName)
{
mName.Assign(aName);
return NS_OK;
}
/* long add (in long a, in long b); */
NS_IMETHODIMP HelloWorld::Add(PRInt32 a, PRInt32 b, PRInt32 *_retval NS_OUTPARAM)
{
*_retval = a + b;
return NS_OK;
}
2)HelloWorld.cpp
#include "HelloWorld.h"
NS_IMPL_ISUPPORTS1(HelloWorld, IHelloWorld)
HelloWorld::HelloWorld()
{
mName.Assign(L"Nameless");
}
HelloWorld::~HelloWorld(){}
/* attribute AString name; */
NS_IMETHODIMP HelloWorld::GetName(nsAString & aName)
{
aName.Assign(mName);
return NS_OK;
}
NS_IMETHODIMP HelloWorld::SetName(const nsAString & aName)
{
mName.Assign(aName);
return NS_OK;
}
/* long add (in long a, in long b); */
NS_IMETHODIMP HelloWorld::Add(PRInt32 a, PRInt32 b, PRInt32 *_retval NS_OUTPARAM)
{
*_retval = a + b;
return NS_OK;
}
3)IHelloWorld.idl
#include "nsISupports.idl"
[scriptable, uuid(2f52e0f0-0eac-11e1-be50-0800200c9a66)]
interface IHelloWorld : nsISupports
{
attribute AString name;
long add(in long a, in long b);
}
4)HelloWorldModule.cpp
#include "mozilla/ModuleUtils.h"
#include "nsIClassInfoImpl.h"
#include "HelloWorld.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(HelloWorld)
// The following line defines a kHELLOWORLD_CID CID variable.
NS_DEFINE_NAMED_CID(HELLOWORLD_CID);
static const mozilla::Module::CIDEntry kSampleCIDs[] = {
{ &kHELLOWORLD_CID, false, NULL, HelloWorldConstructor },
{ NULL }
};
static const mozilla::Module::ContractIDEntry kSampleContracts[] = {
{ HELLOWORLD_CONTRACTID, &kHELLOWORLD_CID },
{ NULL }
};
static const mozilla::Module kSampleModule = {
mozilla::Module::kVersion,
kSampleCIDs,
kSampleContracts,
NULL /* or a category definition if you need it */
};
NSMODULE_DEFN(nsSampleModule) = &kSampleModule;
5)xpidl-build.bat (using as Command Line call to the Pre-Build Event)
..\..\xulrunner-sdk\sdk\bin\xpidl.exe -m header -I..\..\xulrunner-sdk\idl %1
..\..\xulrunner-sdk\sdk\bin\xpidl.exe -m typelib -I..\..\xulrunner-sdk\idl %1
I found my mistake.Reason for error: "I was putting gecko-sdk in wrong directory".Now my project is able to build.
Thanks to all who had replied for this thread.

How does a Lex & Yacc parser output values?

So for a project that I'm working on, I am using Lex and Yacc to parse a FTP configuration file. The configuration files look something like this:
global {
num_daemons = 10
etc = /etc/ftpd
};
host "ftp-1.foobar.com" {
ftproot = /var/ftp/server1
max_out_bandwidth = 20.7
};
host "ftp-2.foobar.com" {
ftproot = /var/ftp/server2
exclude = /var/ftp/server2/private
};
host "ftp-3.foobar.com" {
ftproot = /var/ftp/server3
};
Now, my question is, how do I obtain this information in a usable way? Let's say I wanted to put things like the address after the host token into a struct. How would I do that? Also, how would I simply print out the values that I've parsed to the command line? Also, to run it, do I just cat the config file and pipe in the compiled c program? Thanks in advance for any help!
Here is my code:
%{
// tokens.l
#include <stdio.h>
#include <stdlib.h>
#include "y.tab.h"
int yyparse();
%}
%option noyywrap
%x OPTION
%x OPTID
%%
<INITIAL>global { return GLOBAL; }
<INITIAL>host { return HOST; }
<INITIAL>"[a-zA-z1-9./-]+" { return NAME; }
<INITIAL>\{ { return CURLY_OPEN; BEGIN OPTION; }
<INITIAL>\n { return EOLN; }
<INITIAL><<EOF>> { return EOFTOK; }
<OPTION>[a-zA-z1-9./-_]+ { return ID_NAME; BEGIN OPTID; }
<OPTION>[\t] {}
<OPTION>[\};] { return OPTION_CLOSE; BEGIN INITIAL;}
<OPTID>[a-zA-z1-9./-]+ { return ID_STRING; BEGIN OPTION; }
<OPTID>[0-9.]+ { return ID_NUM; BEGIN OPTION; }
<OPTID>[\n] { return EOLN; }
%%
int main(int argc, char **argv) {
// Where I am confused..
}
and my yacc file:
%{
// parse.y
#include <stdio.h>
#include <stdlib.h>
int yyerror(char *);
int yylex(void);
%}
%token ERROR EOLN EOFTOK
%token OPTION_CLOSE GLOBAL HOST NAME ID_NAME ID_STRING ID_NUM CURLY_OPEN
%%
input
: lines EOFTOK { YYACCEPT; }
;
lines
:
| lines line
;
line
: option
| opident
| OPTION_CLOSE
;
option
: GLOBAL CURLY_OPEN
| HOST NAME CURLY_OPEN
;
opident
: ID_NAME '=' ID_STRING
| ID_NAME '=' ID_NUM
;
%%
int yyerror(char *msg) {}
You would generally have variables which were accessible and set up before calling the parser, like a linked list of key/value pairs:
typedef struct sNode {
char *key;
char *val;
struct sNode *next;
} tNode;
tNode *lookupHead = NULL;
Then, in your Yacc code, something like:
opident
: ID_NAME '=' ID_STRING { addLookupStr (lookupHead, $1, $3); }
| ID_NAME '=' ID_NUM { other function call here }
;
This would basically execute that code as the rules are found (replacing the $ variables with the item in the rule, $1 is the value for the ID_NAME token, $2 is the =, and so on).
The function would be something like:
void addLookupStr (char *newkey, char *newval) {
// Check for duplicate keys, then attempt to add. All premature returns
// should also be logging errors and setting error flags as needed.
tNode *curr = lookupHead;
while (curr != NULL) {
if (strcmp (curr->key, newkey) == 0)
return;
curr = curr->next;
}
if ((curr = malloc (sizeof (tNode))) == NULL)
return;
if ((curr->key = strdup (newkey)) == NULL) {
free (curr);
return;
}
if ((curr->val = strdup (newval)) == NULL) {
free (curr->newkey);
free (curr);
return;
}
// All possibly-failing ops complete, insert at head of list.
curr->next = lookupHead;
lookupHead = curr;
}

Resources