Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ftlRegex ERROR: No match #4

Open
GaidaiIgor opened this issue Feb 13, 2020 · 12 comments
Open

ftlRegex ERROR: No match #4

GaidaiIgor opened this issue Feb 13, 2020 · 12 comments
Labels

Comments

@GaidaiIgor
Copy link

GaidaiIgor commented Feb 13, 2020

Hello,
I tried to execute example code from the wiki page:

type(ftlString) :: line
type(ftlRegex) :: r
type(ftlRegexMatch), allocatable :: m(:)

line = 'keyword option1=value option2=othervalue'
call r%New('(\w+)\s*=\s*(\w+)')
m = r%Match(line)

! m(1)%text now holds 'option1=value'
! m(2)%text now holds 'option2=othervalue'
! m(:)%group is also populated with the contents of the capture groups.
! e.g. m(1)%group(2)%text holds 'value'

However, when the program tries to execute r%Match(line), it just starts printing the same error until I stop it:

ftlRegex ERROR: No match

The library was compiled using the provided makefile with platform set to intel (ifort 19.0.3.199 20190206). Any ideas what can be wrong?

@robertrueger
Copy link
Member

I could not reproduce this on Linux with either ifort 19.0.3.199 20190206 or the newer 19.1.0.166 20191121. Which platform are you on? Are both debug and release builds affected by this?

ftlRegex can under the hood use both the POSIX regex.h and the PCRE library. By default the makefile assumes you have PCRE installed, but you can disable it and go for POSIX instead, see USE_PCRE in the makefile. Does this make a difference for your issue?

robertrueger added a commit that referenced this issue Feb 19, 2020
@robertrueger
Copy link
Member

robertrueger commented Feb 19, 2020

I've added your example to the unit tests, see: c8eba0b

Can you try running the full set of unit tests, just to see if ftlRegex is the only component that causes problems for you. For me all regression tests work (on Linux) with various versions of GCC >=6.4 and ifort >= 17.

@GaidaiIgor
Copy link
Author

So, I tried to execute the unit tests and all of them passed, even the one you just added. I looked at the way the tests are compiled and it turned out I did not use -lpcreposix flag in my program (only -lftl and -lpcre, but -lpcre does not even seem to have any effect). After I added -lpcreposix everything started working.

@GaidaiIgor
Copy link
Author

GaidaiIgor commented Feb 19, 2020

And, replying to the first comment, my platform is SUSE Linux Enterprise Server 15, both debug and release were affected by this and setting USE_PCRE to false did not solve it.

@robertrueger
Copy link
Member

Ah, I see. I use the POSIX compatible API from PCRE instead of their native API. I think in the configure_ftlRegex.c file, it picked up the values of the enums for the PCRE POSIX API from pcreposix.h, but then you linked against the standard POSIX regular expressions from regex.h, which have other numeric values for all these enums ...

I think everything should also work for you if you "make cleanall" and then make with USE_PCRE=false (aka not linking to PCRE). Either way, the enum numerical values just need to be consistent between the configure and linking step ...

@robertrueger
Copy link
Member

I added some documentation on how to build ftlRegex to the Wiki. So far there was only a giant TODO there ;-) ...
Thanks for reporting this!

@GaidaiIgor
Copy link
Author

GaidaiIgor commented Feb 19, 2020

The second option in the building instructions (Compile without "-DUSE_PCRE" and link with nothing) does not seem to work for me. It produces the same error at runtime. Only the first one works.

Also, in the first option, -lpcre seems to have no effect, just -lpcreposix is sufficient, at least on my system.

@robertrueger
Copy link
Member

It's the PCRE documentation (https://www.pcre.org/original/doc/html/pcreposix.html) that suggests you need both:

The functions described here are just wrapper functions that ultimately call the PCRE native API. Their prototypes are defined in the pcreposix.h header file, and on Unix systems the library itself is called pcreposix.a, so can be accessed by adding -lpcreposix to the command for linking an application that uses them. Because the POSIX functions call the native ones, it is also necessary to add -lpcre.

I think the unit tests should also work without PCRE (they do for me), but you need to make sure the configure_ftlRegex.inc does not have the numerical values for the PCRE enums in there. Can you try:

make cleanall
make test USE_PCRE=false

If this does not pass, then something is still wrong.

@robertrueger robertrueger reopened this Feb 20, 2020
@GaidaiIgor
Copy link
Author

GaidaiIgor commented Feb 20, 2020

make cleanall
make test USE_PCRE=false

passes.
However, the makefile links object files directly when it builds tests. This way indeed works.

The error shows up if you try to link the library (libftl.so) instead of object files (via -lftl). In this case using USE_PCRE=false together with no other libraries at the linking stage (no -lprce and -lpcreposix) generates the error at runtime.
The library way only seems to work with building option 1.

Additionally, you can reproduce this error in unit tests if you try to:

make test USE_PCRE=false
make clean
make test USE_PCRE=true

i.e. without cleaning configure_ftlRegex.inc

@robertrueger
Copy link
Member

I talked a bit with a colleague about how linkers work, I think I understand what is going on now.

  • If you have a shared library of the FTL built with USE_PCRE=true, you will need to link the program using it with -lftl -lpcreposix.
  • If you have a shared FTL library built without PCRE, you need to link it just with -lftl.

The reason is this: When compiling your program the C standard library is implicitly included as the last shared library. It will be used after all libraries you linked against explicitly, but before their dependencies. A libftl built with PCRE will depend on libpcreposix (you should be able to check that with ldd, issue #7 seems to be unrelated). If you specify just -lftl on the command line, what you will actually get is -lftl -lc -lpcreposix. Remember: First what you specify, then the implicit libc, then the dependencies of what you specified explicitly. Now the problem is that libc already provides the regex functions we actually wanted from libpcreposix, and the linker picks them up from libc because it comes first. This causes problems at run-time. The solution is to specify -lpcreposix explicitly, so that it comes before the implicit -lc.

This explains the behavior you observe, right?

@GaidaiIgor
Copy link
Author

GaidaiIgor commented Sep 18, 2020

The case I described here does not involve PCRE. I tried to compile the library with USE_PCRE=false, so -lpcreposix is not needed at all (and I did not specify it). And it crashed at runtime. However, I don't remember what I did to reproduce it. I tried it again just now and it seems to be working. I don't think issue #7 is related here.

@Terobero
Copy link

Terobero commented Dec 4, 2020

I had the same error and compiling with -lpcreposix solved the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants