FreeBASIC bindings for Rust regex

Headers, Bindings, Libraries for use with FreeBASIC, Please include example of use to help ensure they are tested and usable.
Post Reply
Roland Chastain
Posts: 1008
Joined: Nov 24, 2011 19:49
Location: France
Contact:

FreeBASIC bindings for Rust regex

Post by Roland Chastain »

Hello everybody!

Someone made bindings for Rust regex.

I would have liked to write some examples but I it has been a long time since I didn't write something for FB, and I don't know how to start. If someone is interested and would like to help...

For now I can compile this:

Code: Select all

#include "rure.bi"
I installed Rust, from the package manager of my Linux distribution. It seems that there is nothing else to do.
badidea
Posts: 2609
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: FreeBASIC bindings for Rust regex

Post by badidea »

Hi Roland, I downloaded regex-master.zip and unzipped it.
I had the rust compiler already installed some time ago. And I play a bit with it before.
Then I ran from the terminal: cargo build, which creates libregex.rlib in target/debug/
You can also run cargo build --release, which creates a libregex.rlib in target/release/

Code: Select all

~/Downloads/regex-master$ cargo build
    Updating crates.io index
  Downloaded aho-corasick v0.7.20
  Downloaded memchr v2.5.0
  Downloaded 2 crates (177.3 KB) in 0.62s
   Compiling memchr v2.5.0
   Compiling regex-syntax v0.6.28 (/home/badidea/Downloads/regex-master/regex-syntax)
   Compiling aho-corasick v0.7.20
   Compiling regex v1.7.1 (/home/badidea/Downloads/regex-master)
    Finished dev [unoptimized + debuginfo] target(s) in 1m 20s

Code: Select all

~/Downloads/regex-master$ cargo build --release
   Compiling memchr v2.5.0
   Compiling regex-syntax v0.6.28 (/home/badidea/Downloads/regex-master/regex-syntax)
   Compiling aho-corasick v0.7.20
   Compiling regex v1.7.1 (/home/badidea/Downloads/regex-master)
    Finished release [optimized + debuginfo] target(s) in 28.77s
As you can see, compiling rust code is not fast. But it does a lot of smart stuff in the process.
Normally you run it with cargo run, but this is a library, not an executable.
More info: https://doc.rust-lang.org/stable/book/c ... go-project

I did not try to link the library with freebasic, you asked for a start :-)
badidea
Posts: 2609
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: FreeBASIC bindings for Rust regex

Post by badidea »

Oh, I just read that you don't want a rlib, see:
https://stackoverflow.com/questions/405 ... -with-diff
Roland Chastain
Posts: 1008
Joined: Nov 24, 2011 19:49
Location: France
Contact:

Re: FreeBASIC bindings for Rust regex

Post by Roland Chastain »

@badidea

Thanks for the infos. I will come back as soon as I have something. :wink:
badidea
Posts: 2609
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: FreeBASIC bindings for Rust regex

Post by badidea »

By adding

Code: Select all

crate-type = ["staticlib"]
or

Code: Select all

crate-type = ["cdylib"]
in the [lib] section in the cargo.toml file, you can build a libregex.a or libregex.so in target/debug/ or target/release/
But how to use this with freebasic, I do not know.

Also, I think that the library complex to use. In rust your have e.g. this re.is_match("2014-01-01") which seems to correspond to this declaration in freebasic:

Code: Select all

declare function rure_is_match(byval re as rure ptr, byval haystack as const ubyte ptr, byval length as uinteger, byval start as uinteger) as boolean
Which does not look like fun.
Roland Chastain
Posts: 1008
Joined: Nov 24, 2011 19:49
Location: France
Contact:

Re: FreeBASIC bindings for Rust regex

Post by Roland Chastain »

Thank you for the info about building static and dynamic libraries.

I built the static library and put the file libregex.a in the same folder where I have rure.bi and test.bas.

Code: Select all

' test.bas

#include "rure.bi"

#inclib "regex"

dim as rure ptr re

re = rure_compile_must("^\d{4}-\d{2}-\d{2}$")
Here is what I get:

Code: Select all

fbc -w all "test.bas" (dans le dossier : /home/roland/Documents/basic/rure/src)
/usr/bin/../bin/ld: test.o: in function `main':
test.c:(.text+0x3a): undefined reference to `rure_compile_must'
Last edited by Roland Chastain on Feb 17, 2023 1:15, edited 3 times in total.
Roland Chastain
Posts: 1008
Joined: Nov 24, 2011 19:49
Location: France
Contact:

Re: FreeBASIC bindings for Rust regex

Post by Roland Chastain »

Here is a first working example. It seems that I wasn't using the right method to build the library.

Code: Select all

' test1.bas (Rust regex library usage example) 

' 1. How to get librure.a
' -----------------------

/'
git clone https://github.com/rust-lang/regex
cd regex/regex-capi
cargo build --release
cd ../..              
cp regex/target/release/librure.a .
'/

' 2. How to get rure.bi
' ---------------------

/'
git clone https://github.com/thechampagne/rure-freebasic.git
cp rure-freebasic/src/rure.bi .
'/

' 3. How to build this example
' ----------------------------

/'
fbc -w all test1.bas -p . -l rure
'/

' Links
' -----
' https://github.com/rust-lang/regex/discussions/957
' https://github.com/thechampagne/rure-freebasic
' https://www.freebasic.net/forum/viewtopic.php?t=32048

#include "rure.bi"

#inclib "rure"

dim as rure ptr re

re = rure_compile_must("^\d{4}-\d{2}-\d{2}$")

dim as zstring*11 haystack => "0000-00-00"

dim as boolean match = rure_is_match(re, @haystack, len(haystack), 0)

print(match) ' true

haystack => "0000-00-0A"

match = rure_is_match(re, @haystack, len(haystack), 0)

print(match) ' false

rure_free(re)
When I have time I will write other examples.
Last edited by Roland Chastain on Feb 17, 2023 0:41, edited 2 times in total.
badidea
Posts: 2609
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: FreeBASIC bindings for Rust regex

Post by badidea »

Nice, I followed your steps and the Freebasic code compiles and runs as well here.
Roland Chastain
Posts: 1008
Joined: Nov 24, 2011 19:49
Location: France
Contact:

Re: FreeBASIC bindings for Rust regex

Post by Roland Chastain »

Thank you for the confirmation.
Roland Chastain
Posts: 1008
Joined: Nov 24, 2011 19:49
Location: France
Contact:

Re: FreeBASIC bindings for Rust regex

Post by Roland Chastain »

For the fun, an all-in-one bash script which downloads and builds the library, builds the C example, downloads the FB header, creates and builds the FB example. To be pasted and run in an empty directory.

Code: Select all

# rure-start.sh
# Usage:
#   chmod +x rure-start.sh
#   sh rure-start.sh

echo Download Rust regex library...
git clone https://github.com/rust-lang/regex

echo Build librure.a...
cd regex/regex-capi
cargo build --release
cd ../..

echo Copy librure.a to current directory...
cp regex/target/release/librure.a .

echo Copy test.c to current directory...
cp regex/regex-capi/ctest/test.c .

echo Build test.c...
gcc -o test test.c -I./regex/regex-capi/include -L. -lrure -lpthread -ldl

echo Download rure.bi...
git clone https://github.com/thechampagne/rure-freebasic.git
cp rure-freebasic/src/rure.bi .

echo Create test1.bas...
cat > test1.bas << EOF
#include "rure.bi"
#inclib "rure"
dim as rure ptr re
re = rure_compile_must("^\d{4}-\d{2}-\d{2}$")
dim as zstring*11 haystack => "0000-00-00"
dim as boolean match = rure_is_match(re, @haystack, len(haystack), 0)
assert(match)
haystack => "0000-00-0A"
match = rure_is_match(re, @haystack, len(haystack), 0)
assert(not match)
rure_free(re)
EOF

echo Build test1.bas...
fbc -g -w all test1.bas -p . -l rure

echo Good night!
Roland Chastain
Posts: 1008
Joined: Nov 24, 2011 19:49
Location: France
Contact:

Re: FreeBASIC bindings for Rust regex

Post by Roland Chastain »

Three examples.

Code: Select all

' match.bas

#include "rure.bi"

#inclib "rure"

dim subject(2) as zstring ptr = { _
  @"2012-03-14", _
  @"0000-00-00", _
  @"0000-00-0A" _
}

dim as rure ptr re = rure_compile_must("^\d{4}-\d{2}-\d{2}$")
' rure_compile_must aborts the process and prints an error message to
' stderr if the regex compilation fails.

dim success as boolean

for i as integer = 0 to ubound(subject)
  success = rure_is_match(re, subject(i), len(*subject(i)), 0)
  if not success then
    print("invalid string: " & *subject(i))
  end if
next

rure_free(re)

/'
invalid string: 0000-00-0A
'/

Code: Select all

' find.bas

#include "rure.bi"

#inclib "rure"

dim subject(2) as zstring ptr = { _
  @"2012-03-14", _
  @"0000-00-00", _
  @"0000-00-0A" _
}

dim as rure ptr re = rure_compile_must("-\d{2}")
dim match as rure_match
dim success as boolean

for i as integer = 0 to ubound(subject)
  success = rure_find(re, subject(i), len(*subject(i)), 0, @match)

  while success
    print("[i=" & str(i) & "] found: " & mid(*subject(i), match.start + 1, match.end - match.start))
    success = rure_find(re, subject(i), len(*subject(i)), match.end, @match)
  wend
next

rure_free(re)

/'
[i=0] found: -03
[i=0] found: -14
[i=1] found: -00
[i=1] found: -00
[i=2] found: -00
'/

Code: Select all

' capture.bas

#include "rure.bi"

#inclib "rure"

dim subject(2) as zstring ptr = { _
  @"2012-03-14", _
  @"0000-00-00", _
  @"0000-00-0A" _
}

dim as rure ptr re = rure_compile_must("-(\d{2})")
dim as rure_captures ptr caps = rure_captures_new(re)
dim match as rure_match
dim success as boolean

for i as integer = 0 to ubound(subject)
  success = rure_find_captures(re, subject(i), len(*subject(i)), 0, caps)
  
  while success
    for j as integer = 0 to rure_captures_len(caps) - 1
    
      if rure_captures_at(caps, j, @match) then
        print("[i=" & str(i) & "] group[" & str(j) & "]: " & mid(*subject(i), match.start + 1, match.end - match.start))
      else
        print("Something is rotten in this program.")
      end if
      
    next
    
    success = rure_find_captures(re, subject(i), len(*subject(i)), match.end, caps)
  wend
next

rure_captures_free(caps)
rure_free(re)

/'
[i=0] group[0]: -03
[i=0] group[1]: 03
[i=0] group[0]: -14
[i=0] group[1]: 14
[i=1] group[0]: -00
[i=1] group[1]: 00
[i=1] group[0]: -00
[i=1] group[1]: 00
[i=2] group[0]: -00
[i=2] group[1]: 00
'/
Roland Chastain
Posts: 1008
Joined: Nov 24, 2011 19:49
Location: France
Contact:

Re: FreeBASIC bindings for Rust regex

Post by Roland Chastain »

A last one (still capture, but using iterator).

Code: Select all

' capture2.bas

#include "rure.bi"

#inclib "rure"

dim subject(2) as zstring ptr = { _
  @"2012-03-14", _
  @"0000-00-00", _
  @"0000-00-0A" _
}

dim as rure ptr re = rure_compile_must("-(\d{2})")
dim as rure_captures ptr caps = rure_captures_new(re)
dim it as rure_iter ptr
dim match as rure_match
dim success as boolean

for i as integer = 0 to ubound(subject)
  it = rure_iter_new(re)
  
  while rure_iter_next_captures(it, subject(i), len(*subject(i)), caps)
    for j as integer = 0 to rure_captures_len(caps) - 1
      success = rure_captures_at(caps, j, @match)
      print("[i = " & str(i) & "] capture[" & str(j) & "] = " & mid(*subject(i), match.start + 1, match.end - match.start))
    next
  wend
  
  rure_iter_free(it)
next

rure_captures_free(caps)
rure_free(re)

/'
[i = 0] capture[0] = -03
[i = 0] capture[1] = 03
[i = 0] capture[0] = -14
[i = 0] capture[1] = 14
[i = 1] capture[0] = -00
[i = 1] capture[1] = 00
[i = 1] capture[0] = -00
[i = 1] capture[1] = 00
[i = 2] capture[0] = -00
[i = 2] capture[1] = 00
'/
Post Reply