Using PCRE on ILE - regex

I am trying to use the pcre library (from AIX) on IBM iseries.
It should be possible using PASE.
I installed the pcre library with the rpm provided by yips.
I tried to use it in c ile source, but i couldn't achieve it.
Exemples : yips, ibm, ibm redbook
I can't find the way to do it.
Here is what i have done so far.
#include <stdio.h>
#include <qp2shell2.h>
#include <qp2user.h>
#define JOB_CCSID 0
int main(int argc, char *argv[])
{
int rc;
QP2_ptr64_t id;
void *getpid_pase;
const QP2_arg_type_t signature[] = { QP2_ARG_END };
QP2_word_t result;
/*
* Call QP2SHELL2 to run the OS/400 PASE program
* /usr/lib/start32, which starts OS/400 PASE in
* 32-bit mode (and leaves it active on return)
*/
QP2SHELL2("/usr/lib/start32");
/*
* Qp2dlopen opens the global name space (rather than
* loading a new shared executable) when the first
* argument is a null pointer. Qp2dlsym locates the
* function descriptor for the OS/400 PASE getpid
* subroutine (exported by shared library libc.a)
*/
id = Qp2dlopen("/usr/lib/libpcre.a", QP2_RTLD_NOW, JOB_CCSID);
getpid_pase = Qp2dlsym(id, "pcrecpp::RE", JOB_CCSID, NULL);
//id = Qp2dlopen(NULL, QP2_RTLD_NOW, JOB_CCSID);
//getpid_pase = Qp2dlsym(id, "getpid", JOB_CCSID, NULL);
/*
* Call Qp2CallPase to run the OS/400 PASE getpid
* function, and print the result. Use Qp2errnop
* to find and print the OS/400 PASE errno if the
* function result was -1
*/
rc = Qp2CallPase(getpid_pase,
NULL, // no argument list
signature,
QP2_RESULT_WORD,
&result);
printf("OS/400 PASE getpid() = %i\n", result);
if (result == -1)
printf("OS/400 errno = %i\n", *Qp2errnop());
/*
* Close the Qp2dlopen instance, and then call
* Qp2EndPase to end OS/400 PASE in this job
*/
Qp2dlclose(id);
Qp2EndPase();
return 0;
}

Today I tried the same and I could compile pcre to ILE using CRTCMOD.
In the zip-file of pcre you can find a file named NON_AUTOTOOLS_BUILD (if I remember the name correctly) with with all information needed to compile it.
In fact you only need to:
edit config.h to match your environment (available functions like memmove, features like pthreads, EBCDIC support and NewLine=37 (x'25') )
compile dftables.c using CRTBNDC DEFINE(HAVE_CONFIG_H) ...
CALL DFTABLES to generate the character tables for EBCDIC (this step was a bit tricky, because it couldn't open the IFS-File for output. so I put the output in a source member and used CPYTOSTMF to get it in the IFS)
compile the all the .c files unsing CRTCMOD DEFINE(HAVE_CONFIG_H) ...
create a *SRVPGM from the modules
write the Prototypes for RPG
It works like a charm, except for a little problem with CCSIDs. I generated the chartables for CCSID 1141, but for some reason PCRE expects input to be CCSID 37.
Also note that, if you write the prototypes in RPG, pcre_free is special. This function is not implemented in PCRE (you could write your own and plug it in if you want) and defaults to free. Your prototype should look like
Dpcre_free PR EXTPROC('free')
D * value
*white spaces not accurate
Hope that helps

Related

fopen_s returns error code 2 with system account and win 32 but works fine on winx64 (c++)

I have a cpp program that uses fopen_s to open and read a file created under the directory C:\Windows\System32\config\systemprofile\AppData\Roaming.
My program needs to be compatible with winx64 and win32.
When I run this program with a system account (run using PSTools\PSExec -i -s C:\windows\system32\cmd.exe) and the Win32 compiled version of the program, fopen_s() on any file inside "C:\Windows\System32\config\systemprofile\AppData\Roaming" returns an error code 2, even though the file is present.
However, when I run the x64 compiled version of the same program, it works fine and fopen_s() is able to find and open the same file.
I am sure there are no mistakes as far as passing a valid filename to fopen_s() and I have verified this.
I make sure that the int variable that stores the return value from fopen_s() is set to 0 every time before calling fopen_s(). I am calling fopen_s() in "r" mode.
Also, elsewhere in the same program I am able to create files under the same directory.
I am using VS2019 and cpp +11 to compile my program.
My system is running windows 10 (64-bit) on an x64 processor (Intel(R) Xeon(R) Gold 6136)
Why would a win32 application fail to read a file created under "C:\Windows\System32\config\systemprofile\AppData\Roaming" with a system account while the x64 version of the same application works fine?
Code snippet:
int FileOpenFunc(FILE ** ppFile, std::string sFilename, std::string sOpenMode)
{
int errOpen = 0;
#ifdef _WIN32
errOpen = fopen_s(ppFile, sFilename.c_str(), sOpenMode.c_str());
#else
*ppFile = fopen(sFilename.c_str(), sOpenMode.c_str());
errOpen = errno;
#endif
return errOpen;
}
void func()
{
std::string sFileName = "C:\\Windows\\System32\\config\\systemprofile\\AppData\\Roaming\\Check\\sample.txt";
int errFopenErrNo = 0;
FILE* fp = NULL;
errFopenErrNo = FileOpenFunc(&fp, sFileName, "r");
if (fp!= NULL)
{
//do something
}
else
{
//do something else
}
}

undeclared identifier posix_fallocate() and fallocate() in macOS, clang 12.00 [duplicate]

Is there a fallocate() equivalent in OS X?
I would like to aggregate all of those equivalent in OS X questions into some doc/table or whatever for everyone. Anybody knows something familiar?
What about using:
mkfile -n 1m test.tmp
It's not the same command but serves the same purpose.
Note that fallocate uses decimal multipliers, whereas mkfile uses binary multipliers.
mkfile man
fallocate() doesn't exist on OSX. You can "fake" it though; Mozilla fakes it in their FileUtils class. See this file:
http://hg.mozilla.org/mozilla-central/file/3d846420a907/xpcom/glue/FileUtils.cpp#l61
Here's the code, in case that link goes stale:
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Taras Glek <tglek#mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#if defined(XP_UNIX)
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#elif defined(XP_WIN)
#include <windows.h>
#endif
#include "nscore.h"
#include "private/pprio.h"
#include "mozilla/FileUtils.h"
bool
mozilla::fallocate(PRFileDesc *aFD, PRInt64 aLength)
{
#if defined(HAVE_POSIX_FALLOCATE)
return posix_fallocate(PR_FileDesc2NativeHandle(aFD), 0, aLength) == 0;
#elif defined(XP_WIN)
return PR_Seek64(aFD, aLength, PR_SEEK_SET) == aLength
&& 0 != SetEndOfFile((HANDLE)PR_FileDesc2NativeHandle(aFD));
#elif defined(XP_MACOSX)
int fd = PR_FileDesc2NativeHandle(aFD);
fstore_t store = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, aLength};
// Try to get a continous chunk of disk space
int ret = fcntl(fd, F_PREALLOCATE, &store);
if(-1 == ret){
// OK, perhaps we are too fragmented, allocate non-continuous
store.fst_flags = F_ALLOCATEALL;
ret = fcntl(fd, F_PREALLOCATE, &store);
if (-1 == ret)
return false;
}
return 0 == ftruncate(fd, aLength);
#elif defined(XP_UNIX)
// The following is copied from fcntlSizeHint in sqlite
/* If the OS does not have posix_fallocate(), fake it. First use
** ftruncate() to set the file size, then write a single byte to
** the last byte in each block within the extended region. This
** is the same technique used by glibc to implement posix_fallocate()
** on systems that do not have a real fallocate() system call.
*/
struct stat buf;
int fd = PR_FileDesc2NativeHandle(aFD);
if (fstat(fd, &buf))
return false;
if (buf.st_size >= aLength)
return false;
const int nBlk = buf.st_blksize;
if (!nBlk)
return false;
if (ftruncate(fd, aLength))
return false;
int nWrite; // Return value from write()
PRInt64 iWrite = ((buf.st_size + 2 * nBlk - 1) / nBlk) * nBlk - 1; // Next offset to write to
do {
nWrite = 0;
if (PR_Seek64(aFD, iWrite, PR_SEEK_SET) == iWrite)
nWrite = PR_Write(aFD, "", 1);
iWrite += nBlk;
} while (nWrite == 1 && iWrite < aLength);
return nWrite == 1;
#endif
return false;
}
For those wanting to create fake data files for testing, mkfile is pretty elegant. An alternative is to use dd:
dd if=/dev/zero of=zfile count=1024 bs=1024
As you can see with od -b zfile, it's full of zeros. If you want random data (which you may want for testing workflows with data compression, for example), then use "/dev/random" in place of "/dev/zero":
dd if=/dev/random of=randfile count=1024 bs=1024

render a gvc (graohviz) from c++ console application / or qt gui application

I am writing a programme which can generate dot desctiption file that I would like to directly on the screen.
I got following code from graphviz.org on how to use it as a library and it works
int main(int argc, char *argv[])
{
Agraph_t* G;
GVC_t* gvc;
gvc = gvContext(); /* library function */
FILE* fl;
FILE* ot;
ot = fopen("/home/test.png", "w");
fl = fopen("/home/my.gv", "r");
G = agread(fl,0);
gvLayout (gvc, G, "dot"); /* library function */
gvRender(gvc, G,"png", ot);
gvFreeLayout(gvc, G); /* library function */
agclose (G); /* library function */
return (gvFreeContext(gvc));
}
When I run it from the qt console application project, it just gives
Press <RETURN> to close this window...
I can see it does generate this test.png file. I am thinking there must be a way that I can show the gvc directly without like opening an png file, right?
Because writing a GUI application for this from scratch seems like an awesomely bad idea, how about using an external program to achieve this?
You can even launch it from within your generating program if you insist:
system("feh -dR1 test.png");

cstdio fopen and fclose not working correctly on osx

I'm using tinyxml through openframeworks which uses cstdio for file access. I can see the example program quite happily create and write files but there is no delete so my plan is to implement remove, but after trying to run this code in my own project it doesn't seem to create a file or notify me of an error.
This code runs as expected on windows, just not on mac osx 10.8.5, no file is generated.
#include <cstdio>
int main(int argc, const char * argv[])
{
bool bClosed = false;
bool bWritten = false;
FILE* testFile;
testFile = fopen(".\\test.xml", "w");
if(testFile)
{
bWritten = fputs("test writing.", testFile);
bClosed = !fclose(testFile);
}
return 0;
}
edit: i now know the file exists as can read from it, i just cant view it in finder, i have hidden files shown, its not found its way into the app's package contents.
On a unix-like system (e.g. Mac OS X and Linux) a Windows path as
".\\test.xml"
should rather be
"./test.xml"
Anyway the simplest solution for this case might just be
"test.xml"

Wt a.exe file won't run

I am trying to start developing in WT, but it's not working out. I am using Windows 8, downloaded Wt 3.3.1, and had downloaded the codeblocks-12.11mingw-setup_user.exe which has the GCC compiler and GDB debugger. But I am not using code blocks, because the compiler didn't like the cmake preproccessor directives in WtConfig.h. So I tried to compile manually (I am a newb at using this type of technique, so I had to look it up).
I have my project as:
└───HelloWorldWt
└───source
├───bin
│ ├───Debug
│ │ └───CMakeFiles
│ │ └───CMakeFiles
│ └───Release
├───build
└───source
| └───CMakeFiles
| └───wt_project.wt.dir
| |___CMakeLists.txt
| |
| |___main.cpp
|____CMakeLists.txt
The main.cpp has (this is the HelloWorld example from http://www.webtoolkit.eu/wt/examples/):
/*
* Copyright (C) 2008 Emweb bvba, Heverlee, Belgium.
*
* See the LICENSE file for terms of use.
*/
#include <Wt/WApplication>
#include <Wt/WBreak>
#include <Wt/WContainerWidget>
#include <Wt/WLineEdit>
#include <Wt/WPushButton>
#include <Wt/WText>
// c++0x only, for std::bind
// #include <functional>
using namespace Wt;
/*
* A simple hello world application class which demonstrates how to react
* to events, read input, and give feed-back.
*/
class HelloApplication : public WApplication
{
public:
HelloApplication(const WEnvironment& env);
private:
WLineEdit *nameEdit_;
WText *greeting_;
void greet();
};
/*
* The env argument contains information about the new session, and
* the initial request. It must be passed to the WApplication
* constructor so it is typically also an argument for your custom
* application constructor.
*/
HelloApplication::HelloApplication(const WEnvironment& env)
: WApplication(env)
{
setTitle("Hello world"); // application title
root()->addWidget(new WText("Your name, please ? ")); // show some text
nameEdit_ = new WLineEdit(root()); // allow text input
nameEdit_->setFocus(); // give focus
WPushButton *button
= new WPushButton("Greet me.", root()); // create a button
button->setMargin(5, Left); // add 5 pixels margin
root()->addWidget(new WBreak()); // insert a line break
greeting_ = new WText(root()); // empty text
/*
* Connect signals with slots
*
* - simple Wt-way
*/
button->clicked().connect(this, &HelloApplication::greet);
/*
* - using an arbitrary function object (binding values with boost::bind())
*/
nameEdit_->enterPressed().connect
(boost::bind(&HelloApplication::greet, this));
/*
* - using a c++0x lambda:
*/
// b->clicked().connect(std::bind([=]() {
// greeting_->setText("Hello there, " + nameEdit_->text());
// }));
}
void HelloApplication::greet()
{
/*
* Update the text, using text input into the nameEdit_ field.
*/
greeting_->setText("Hello there, " + nameEdit_->text());
}
WApplication *createApplication(const WEnvironment& env)
{
/*
* You could read information from the environment to decide whether
* the user has permission to start a new application
*/
return new HelloApplication(env);
}
int main(int argc, char **argv)
{
/*
* Your main method may set up some shared resources, but should then
* start the server application (FastCGI or httpd) that starts listening
* for requests, and handles all of the application life cycles.
*
* The last argument to WRun specifies the function that will instantiate
* new application objects. That function is executed when a new user surfs
* to the Wt application, and after the library has negotiated browser
* support. The function should return a newly instantiated application
* object.
*/
int retval = WRun(argc, argv, &createApplication);
char* ch = new ch();
cin() >> ch;
return retval;
}
The HelloWorldWt/CMakeLists.txt has:
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(WT_HELLO_WORLD)
SET (WT_CONNECTOR "wtfcgi" CACHE STRING "Connector used (wthttp or wtfcgi)")
ADD_SUBDIRECTORY(source)
The HelloWorldWt/source/CMakeLists.txt has
SET(WT_PROJECT_SOURCE
main.cpp
)
SET(WT_PROJECT_TARGET wt_project.wt)
ADD_EXECUTABLE(${WT_PROJECT_TARGET} ${WT_PROJECT_SOURCE})
TARGET_LINK_LIBRARIES(${WT_PROJECT_TARGET} ${WT_CONNECTOR} wt)
INCLUDE_DIRECTORIES("C:/Users/Me/My Code Libraries/wt-3.3.1/src")
I then ran
cmake .. -G "MinGW Makefiles" from the MyCode directory
That created a few files,
this created cmake_install.cmake, among other files.
I then ran: cmake .. -G "MinGW Makefiles" from HelloWorldWt/source
then I ran: cmake -P cmake_install.cmake
I then had:
My Code\HelloWorldWt\source\build\CMakeFiles\2.8.12\CompilerIdCXX\a.exe file, and I clicked that program to run it, and a console window just opened then closed.
what am I missing here?, I am trying to get a Wt application running, but can't seem to do it yet
(Maybe I should note that when I use the command:
cmake -P cmake_install.cmake
the cmd console, replies with
-- Install configuration: ""
and then goes back to the prompt. - If that helps).
My Code\HelloWorldWt\source\build\CMakeFiles\2.8.12\CompilerIdCXX\a.exe
Is not the file you want to run. It is an internal CMake test cmake creates during configuration to verify that the selected compiler even compiles and detect the target architecture.
You executable will be called
My Code\HelloWorldWt\source\build\wt_project.wt.exe
when you actually compile it.
To compile it, you either call make, or other appropriate build command depending on the selected generator, or you can ask cmake to call it for you with the command:
cmake --build .
The code you pasted contains syntax error—
cin() >> ch;
should be
std::cin >> ch;
(and ch should be a char, not char *)—which confirms you didn't yet try to compile it.
I should add that brief look at the WT documentation suggests the resulting executable should also need a bunch of options before it does anything interesting too.
We are using g++ since its a c++ interface (opposed to gcc), and scons as the build model. This works well and was pretty simple to deploy. I would suggest trying the next Ubuntu 14.04 release as it will contain a stable Wt version in its packages.