fix(ci): revert QR skip hack, add CLAUDE.md rule for native QR libs
QR tests MUST use native language libraries, not qrencode CLI. If the sandbox doesn't have the library, the test should FAIL honestly so we know what to fix in the sandbox image. Also adds CLAUDE.md rule to prevent future attempts to replace native library QR tests with CLI subprocess calls.
This commit is contained in:
parent
ed464a3678
commit
97fbd55e61
13 changed files with 77 additions and 224 deletions
16
CLAUDE.md
16
CLAUDE.md
|
|
@ -1,5 +1,21 @@
|
||||||
# Claude AI Instructions for un-inception
|
# Claude AI Instructions for un-inception
|
||||||
|
|
||||||
|
## ⚠️ CRITICAL: QR TEST FILES USE NATIVE LIBRARIES - NEVER SHELL OUT
|
||||||
|
|
||||||
|
**QR test files (`test/qr.*`) MUST use each language's native QR library.** The entire point of these tests is to verify that native QR code generation works in each language inside the sandbox. Shelling out to `qrencode` CLI defeats the purpose.
|
||||||
|
|
||||||
|
If a QR test fails because the library isn't installed in the sandbox, the fix is to **install the library in the sandbox image** or **make the sandbox support that library** - NOT to replace the native library call with a CLI subprocess.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# ❌ FORBIDDEN - shelling out defeats the test
|
||||||
|
output = subprocess.run(["qrencode", ...]) # This tests qrencode CLI, not Python
|
||||||
|
|
||||||
|
# ✅ CORRECT - test the native library
|
||||||
|
import qrcode
|
||||||
|
q = qrcode.QRCode(border=0)
|
||||||
|
q.add_data("unsandbox-qr-ok")
|
||||||
|
```
|
||||||
|
|
||||||
## ⚠️ CRITICAL: SCIENTIFIC INTEGRITY - TESTS MUST NEVER LIE
|
## ⚠️ CRITICAL: SCIENTIFIC INTEGRITY - TESTS MUST NEVER LIE
|
||||||
|
|
||||||
**Science is the foundation of this project.** Tests exist to tell us the truth about our code. A test that lies is worse than no test at all.
|
**Science is the foundation of this project.** Tests exist to tell us the truth about our code. A test that lies is worse than no test at all.
|
||||||
|
|
|
||||||
|
|
@ -593,28 +593,11 @@ if [ -n "$QR_FILE" ] && [ -f "$QR_FILE" ]; then
|
||||||
# Test 9.1: QR code generation produces structured output
|
# Test 9.1: QR code generation produces structured output
|
||||||
# Pass file path without -s: un CLI reads the file and auto-detects language
|
# Pass file path without -s: un CLI reads the file and auto-detects language
|
||||||
# (with -s, the positional arg is treated as inline code, not a file path)
|
# (with -s, the positional arg is treated as inline code, not a file path)
|
||||||
#
|
# QR tests use native language libraries - if the library isn't in the sandbox,
|
||||||
# QR tests require language-specific libraries (qrcode npm, python qrcode, etc.)
|
# the test FAILS honestly. Fix the sandbox image, don't mask the failure.
|
||||||
# If the sandbox doesn't have the library, SKIP - don't FAIL.
|
run_test "qr_generate" \
|
||||||
QR_OUTPUT=$(build/un "$QR_FILE" 2>&1 || true)
|
"build/un '$QR_FILE'" \
|
||||||
echo "$QR_OUTPUT" > "$RESULTS_DIR/qr_generate.txt"
|
"QR:unsandbox-qr-ok:ROWS:[0-9]+"
|
||||||
|
|
||||||
echo -n "Test: qr_generate... "
|
|
||||||
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
|
||||||
|
|
||||||
if echo "$QR_OUTPUT" | grep -qiE "QR:unsandbox-qr-ok:ROWS:[0-9]+"; then
|
|
||||||
TEST_RESULTS["qr_generate"]="pass"
|
|
||||||
echo "PASS"
|
|
||||||
elif echo "$QR_OUTPUT" | grep -qiE "Cannot find module|ModuleNotFoundError|ImportError|no such file|LoadError|require.*not found|could not find|package.*not found|install|gem.*not found|undefined method|NameError|not installed|unresolved import|cannot open shared object"; then
|
|
||||||
echo "SKIP (missing QR dependency in sandbox)"
|
|
||||||
else
|
|
||||||
TEST_RESULTS["qr_generate"]="fail"
|
|
||||||
FAILURES=$((FAILURES + 1))
|
|
||||||
echo "FAIL"
|
|
||||||
echo " --- Failure output (qr_generate) ---"
|
|
||||||
head -5 "$RESULTS_DIR/qr_generate.txt"
|
|
||||||
echo " ---"
|
|
||||||
fi
|
|
||||||
else
|
else
|
||||||
echo "SKIP: No QR test file for $LANG"
|
echo "SKIP: No QR test file for $LANG"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
12
test/qr.cob
12
test/qr.cob
|
|
@ -4,18 +4,15 @@
|
||||||
DATA DIVISION.
|
DATA DIVISION.
|
||||||
WORKING-STORAGE SECTION.
|
WORKING-STORAGE SECTION.
|
||||||
01 QR-PTR USAGE POINTER.
|
01 QR-PTR USAGE POINTER.
|
||||||
|
01 QR-VERSION PIC S9(9) COMP-5.
|
||||||
|
01 QR-WIDTH PIC S9(9) COMP-5.
|
||||||
|
01 QR-DATA-PTR USAGE POINTER.
|
||||||
01 WS-TEXT PIC X(20) VALUE "unsandbox-qr-ok"
|
01 WS-TEXT PIC X(20) VALUE "unsandbox-qr-ok"
|
||||||
& X"00".
|
& X"00".
|
||||||
01 WS-ZERO PIC S9(9) COMP-5 VALUE 0.
|
01 WS-ZERO PIC S9(9) COMP-5 VALUE 0.
|
||||||
01 WS-ONE PIC S9(9) COMP-5 VALUE 1.
|
01 WS-ONE PIC S9(9) COMP-5 VALUE 1.
|
||||||
01 WS-TWO PIC S9(9) COMP-5 VALUE 2.
|
01 WS-TWO PIC S9(9) COMP-5 VALUE 2.
|
||||||
|
|
||||||
LINKAGE SECTION.
|
|
||||||
01 QR-STRUCT.
|
|
||||||
05 QR-VERSION PIC S9(9) COMP-5.
|
|
||||||
05 QR-WIDTH PIC S9(9) COMP-5.
|
|
||||||
05 QR-DATA USAGE POINTER.
|
|
||||||
|
|
||||||
PROCEDURE DIVISION.
|
PROCEDURE DIVISION.
|
||||||
MAIN-LOGIC.
|
MAIN-LOGIC.
|
||||||
CALL "QRcode_encodeString"
|
CALL "QRcode_encodeString"
|
||||||
|
|
@ -27,7 +24,8 @@
|
||||||
RETURNING QR-PTR.
|
RETURNING QR-PTR.
|
||||||
|
|
||||||
IF QR-PTR NOT = NULL
|
IF QR-PTR NOT = NULL
|
||||||
SET ADDRESS OF QR-STRUCT TO QR-PTR
|
SET ADDRESS OF QR-VERSION TO QR-PTR
|
||||||
|
SET ADDRESS OF QR-WIDTH TO QR-PTR
|
||||||
DISPLAY "QR:unsandbox-qr-ok:ROWS:" QR-WIDTH
|
DISPLAY "QR:unsandbox-qr-ok:ROWS:" QR-WIDTH
|
||||||
CALL "QRcode_free" USING BY VALUE QR-PTR
|
CALL "QRcode_free" USING BY VALUE QR-PTR
|
||||||
ELSE
|
ELSE
|
||||||
|
|
|
||||||
22
test/qr.cr
22
test/qr.cr
|
|
@ -1,19 +1,5 @@
|
||||||
@[Link("qrencode")]
|
require "qr-code"
|
||||||
lib LibQRencode
|
|
||||||
struct QRcode
|
|
||||||
version : LibC::Int
|
|
||||||
width : LibC::Int
|
|
||||||
data : UInt8*
|
|
||||||
end
|
|
||||||
|
|
||||||
fun QRcode_encodeString(s : LibC::Char*, version : LibC::Int, level : LibC::Int, hint : LibC::Int, casesensitive : LibC::Int) : QRcode*
|
qr = QRCode.new("unsandbox-qr-ok")
|
||||||
fun QRcode_free(qr : QRcode*)
|
rows = qr.modules.size
|
||||||
end
|
puts "QR:unsandbox-qr-ok:ROWS:#{rows}"
|
||||||
|
|
||||||
qr = LibQRencode.QRcode_encodeString("unsandbox-qr-ok", 0, 1, 2, 1)
|
|
||||||
if qr.null?
|
|
||||||
puts "QR encode failed"
|
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
puts "QR:unsandbox-qr-ok:ROWS:#{qr.value.width}"
|
|
||||||
LibQRencode.QRcode_free(qr)
|
|
||||||
|
|
|
||||||
33
test/qr.d
33
test/qr.d
|
|
@ -1,33 +1,8 @@
|
||||||
import core.sys.posix.dlfcn;
|
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
import std.string;
|
import qr;
|
||||||
|
|
||||||
struct QRcode {
|
|
||||||
int _version;
|
|
||||||
int width;
|
|
||||||
void* data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
auto lib = dlopen("libqrencode.so", RTLD_LAZY);
|
auto qrCode = QrCode("unsandbox-qr-ok");
|
||||||
if (lib is null) {
|
auto size = qrCode.size;
|
||||||
stderr.writeln("dlopen: ", dlerror().fromStringz);
|
writefln("QR:unsandbox-qr-ok:ROWS:%d", size);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
alias EncFunc = extern(C) QRcode* function(const char*, int, int, int, int);
|
|
||||||
alias FreeFunc = extern(C) void function(QRcode*);
|
|
||||||
|
|
||||||
auto encode = cast(EncFunc) dlsym(lib, "QRcode_encodeString");
|
|
||||||
auto qfree = cast(FreeFunc) dlsym(lib, "QRcode_free");
|
|
||||||
|
|
||||||
auto qr = encode("unsandbox-qr-ok", 0, 1, 2, 1);
|
|
||||||
if (qr is null) {
|
|
||||||
stderr.writeln("encode failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
writefln("QR:unsandbox-qr-ok:ROWS:%d", qr.width);
|
|
||||||
qfree(qr);
|
|
||||||
dlclose(lib);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
18
test/qr.ex
18
test/qr.ex
|
|
@ -1,14 +1,4 @@
|
||||||
# Use Erlang's :qrcode module (pre-cached via rebar3)
|
qr = EQRCode.encode("unsandbox-qr-ok")
|
||||||
# Falls back to shell if module not available
|
matrix = qr.matrix
|
||||||
try do
|
rows = length(matrix)
|
||||||
{:ok, qr} = :qrcode.encode("unsandbox-qr-ok")
|
IO.puts("QR:unsandbox-qr-ok:ROWS:#{rows}")
|
||||||
# qr is a tuple like {:qrcode, version, ecc, dimension, data}
|
|
||||||
{_tag, _version, _ecc, dimension, _data} = qr
|
|
||||||
IO.puts("QR:unsandbox-qr-ok:ROWS:#{dimension}")
|
|
||||||
rescue
|
|
||||||
_ ->
|
|
||||||
# Fallback: use qrencode CLI
|
|
||||||
{output, 0} = System.cmd("sh", ["-c", "qrencode -t ASCII -m 0 'unsandbox-qr-ok' | wc -l"])
|
|
||||||
rows = String.trim(output)
|
|
||||||
IO.puts("QR:unsandbox-qr-ok:ROWS:#{rows}")
|
|
||||||
end
|
|
||||||
|
|
|
||||||
39
test/qr.f90
39
test/qr.f90
|
|
@ -13,18 +13,16 @@ program qrcode_test
|
||||||
import :: c_ptr, c_char, c_int
|
import :: c_ptr, c_char, c_int
|
||||||
character(kind=c_char), dimension(*), intent(in) :: filename
|
character(kind=c_char), dimension(*), intent(in) :: filename
|
||||||
integer(c_int), value :: flag
|
integer(c_int), value :: flag
|
||||||
end function dlopen
|
end function
|
||||||
|
|
||||||
type(c_funptr) function dlsym(handle, symbol) bind(C, name='dlsym')
|
type(c_funptr) function dlsym(handle, symbol) bind(C, name='dlsym')
|
||||||
import :: c_ptr, c_funptr, c_char
|
import :: c_ptr, c_funptr, c_char
|
||||||
type(c_ptr), value :: handle
|
type(c_ptr), value :: handle
|
||||||
character(kind=c_char), dimension(*), intent(in) :: symbol
|
character(kind=c_char), dimension(*), intent(in) :: symbol
|
||||||
end function dlsym
|
end function
|
||||||
|
|
||||||
integer(c_int) function dlclose(handle) bind(C, name='dlclose')
|
integer(c_int) function dlclose(handle) bind(C, name='dlclose')
|
||||||
import :: c_ptr, c_int
|
import :: c_ptr, c_int
|
||||||
type(c_ptr), value :: handle
|
type(c_ptr), value :: handle
|
||||||
end function dlclose
|
end function
|
||||||
end interface
|
end interface
|
||||||
|
|
||||||
abstract interface
|
abstract interface
|
||||||
|
|
@ -32,11 +30,11 @@ program qrcode_test
|
||||||
import :: c_ptr, c_char, c_int
|
import :: c_ptr, c_char, c_int
|
||||||
character(kind=c_char), dimension(*), intent(in) :: s
|
character(kind=c_char), dimension(*), intent(in) :: s
|
||||||
integer(c_int), value :: ver, lvl, hint, cs
|
integer(c_int), value :: ver, lvl, hint, cs
|
||||||
end function encode_iface
|
end function
|
||||||
subroutine free_iface(qr) bind(C)
|
subroutine free_iface(qr) bind(C)
|
||||||
import :: c_ptr
|
import :: c_ptr
|
||||||
type(c_ptr), value :: qr
|
type(c_ptr), value :: qr
|
||||||
end subroutine free_iface
|
end subroutine
|
||||||
end interface
|
end interface
|
||||||
|
|
||||||
type(c_ptr) :: lib, qr_ptr
|
type(c_ptr) :: lib, qr_ptr
|
||||||
|
|
@ -44,34 +42,17 @@ program qrcode_test
|
||||||
procedure(encode_iface), pointer :: qr_encode
|
procedure(encode_iface), pointer :: qr_encode
|
||||||
procedure(free_iface), pointer :: qr_free
|
procedure(free_iface), pointer :: qr_free
|
||||||
type(QRcode), pointer :: qr
|
type(QRcode), pointer :: qr
|
||||||
integer(c_int) :: rc
|
|
||||||
|
|
||||||
! Try versioned library names
|
|
||||||
lib = dlopen("libqrencode.so.4" // c_null_char, 2)
|
|
||||||
if (.not. c_associated(lib)) then
|
|
||||||
lib = dlopen("libqrencode.so.3" // c_null_char, 2)
|
|
||||||
end if
|
|
||||||
if (.not. c_associated(lib)) then
|
|
||||||
lib = dlopen("libqrencode.so" // c_null_char, 2)
|
|
||||||
end if
|
|
||||||
if (.not. c_associated(lib)) then
|
|
||||||
write(*,'(A)') 'Failed to load libqrencode'
|
|
||||||
stop 1
|
|
||||||
end if
|
|
||||||
|
|
||||||
|
lib = dlopen("libqrencode.so" // c_null_char, 2) ! RTLD_NOW=2
|
||||||
enc_fptr = dlsym(lib, "QRcode_encodeString" // c_null_char)
|
enc_fptr = dlsym(lib, "QRcode_encodeString" // c_null_char)
|
||||||
free_fptr = dlsym(lib, "QRcode_free" // c_null_char)
|
free_fptr = dlsym(lib, "QRcode_free" // c_null_char)
|
||||||
call c_f_procpointer(enc_fptr, qr_encode)
|
call c_f_procpointer(enc_fptr, qr_encode)
|
||||||
call c_f_procpointer(free_fptr, qr_free)
|
call c_f_procpointer(free_fptr, qr_free)
|
||||||
|
|
||||||
qr_ptr = qr_encode("unsandbox-qr-ok" // c_null_char, 0, 1, 2, 1)
|
qr_ptr = qr_encode("unsandbox-qr-ok" // c_null_char, 0, 1, 2, 1)
|
||||||
if (c_associated(qr_ptr)) then
|
call c_f_pointer(qr_ptr, qr)
|
||||||
call c_f_pointer(qr_ptr, qr)
|
write(*, '(A,I0)') 'QR:unsandbox-qr-ok:ROWS:', qr%width
|
||||||
write(*, '(A,I0)') 'QR:unsandbox-qr-ok:ROWS:', qr%width
|
|
||||||
call qr_free(qr_ptr)
|
|
||||||
else
|
|
||||||
write(*,'(A)') 'QR encode failed'
|
|
||||||
end if
|
|
||||||
|
|
||||||
rc = dlclose(lib)
|
call qr_free(qr_ptr)
|
||||||
|
call dlclose(lib)
|
||||||
end program qrcode_test
|
end program qrcode_test
|
||||||
|
|
|
||||||
25
test/qr.fs
25
test/qr.fs
|
|
@ -1,21 +1,6 @@
|
||||||
open System
|
open QRCoder
|
||||||
open System.Runtime.InteropServices
|
|
||||||
|
|
||||||
[<DllImport("libqrencode.so", CallingConvention = CallingConvention.Cdecl)>]
|
let gen = QRCodeGenerator()
|
||||||
extern nativeint QRcode_encodeString(string text, int version, int level, int hint, int caseSensitive)
|
let data = gen.CreateQrCode("unsandbox-qr-ok", QRCodeGenerator.ECCLevel.M)
|
||||||
|
let rows = data.ModuleMatrix.Count
|
||||||
[<DllImport("libqrencode.so", CallingConvention = CallingConvention.Cdecl)>]
|
printfn "QR:unsandbox-qr-ok:ROWS:%d" rows
|
||||||
extern void QRcode_free(nativeint qr)
|
|
||||||
|
|
||||||
[<Struct; StructLayout(LayoutKind.Sequential)>]
|
|
||||||
type QRcode =
|
|
||||||
val version: int
|
|
||||||
val width: int
|
|
||||||
|
|
||||||
let qr = QRcode_encodeString("unsandbox-qr-ok", 0, 1, 2, 1)
|
|
||||||
if qr <> IntPtr.Zero then
|
|
||||||
let s = Marshal.PtrToStructure<QRcode>(qr)
|
|
||||||
printfn "QR:unsandbox-qr-ok:ROWS:%d" s.width
|
|
||||||
QRcode_free(qr)
|
|
||||||
else
|
|
||||||
printfn "QR encode failed"
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env groovy
|
#!/usr/bin/env groovy
|
||||||
// Use qrencode CLI via ProcessBuilder (libqrencode wrapper)
|
import com.google.zxing.BarcodeFormat
|
||||||
def proc = ["qrencode", "-t", "UTF8", "-m", "0", "unsandbox-qr-ok"].execute()
|
import com.google.zxing.qrcode.QRCodeWriter
|
||||||
def output = proc.text
|
|
||||||
proc.waitFor()
|
def w = new QRCodeWriter()
|
||||||
def rows = output.split('\n').findAll { it.trim() }.size()
|
def m = w.encode("unsandbox-qr-ok", BarcodeFormat.QR_CODE, 0, 0)
|
||||||
println "QR:unsandbox-qr-ok:ROWS:${rows}"
|
println "QR:unsandbox-qr-ok:ROWS:${m.height}"
|
||||||
|
|
|
||||||
46
test/qr.hs
46
test/qr.hs
|
|
@ -1,41 +1,11 @@
|
||||||
import System.Posix.DynamicLinker
|
import Codec.QRCode
|
||||||
import Foreign
|
import Codec.QRCode.JuicyPixels
|
||||||
import Foreign.C.Types
|
|
||||||
import Foreign.C.String
|
|
||||||
|
|
||||||
data QRcode = QRcode CInt CInt (Ptr Word8)
|
|
||||||
|
|
||||||
instance Storable QRcode where
|
|
||||||
sizeOf _ = 16
|
|
||||||
alignment _ = 8
|
|
||||||
peek ptr = QRcode
|
|
||||||
<$> peekByteOff ptr 0
|
|
||||||
<*> peekByteOff ptr 4
|
|
||||||
<*> peekByteOff ptr 8
|
|
||||||
poke _ _ = return ()
|
|
||||||
|
|
||||||
type EncodeFunc = CString -> CInt -> CInt -> CInt -> CInt -> IO (Ptr QRcode)
|
|
||||||
type FreeFunc = Ptr QRcode -> IO ()
|
|
||||||
|
|
||||||
foreign import ccall "dynamic"
|
|
||||||
mkEncode :: FunPtr EncodeFunc -> EncodeFunc
|
|
||||||
|
|
||||||
foreign import ccall "dynamic"
|
|
||||||
mkFree :: FunPtr FreeFunc -> FreeFunc
|
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
dl <- dlopen "libqrencode.so" [RTLD_LAZY]
|
let mqr = encodeText defaultQRCodeOptions Iso8859_1OrUtf8WithoutECI "unsandbox-qr-ok"
|
||||||
encFP <- dlsym dl "QRcode_encodeString"
|
case mqr of
|
||||||
freeFP <- dlsym dl "QRcode_free"
|
Nothing -> putStrLn "QR encode failed"
|
||||||
let encode = mkEncode encFP
|
Just img -> do
|
||||||
let qfree = mkFree freeFP
|
let matrix = toMatrix True False img :: [[Bool]]
|
||||||
cs <- newCString "unsandbox-qr-ok"
|
putStrLn $ "QR:unsandbox-qr-ok:ROWS:" ++ show (length matrix)
|
||||||
qr <- encode cs 0 1 2 1
|
|
||||||
if qr == nullPtr
|
|
||||||
then putStrLn "QR encode failed"
|
|
||||||
else do
|
|
||||||
QRcode _ w _ <- peek qr
|
|
||||||
putStrLn $ "QR:unsandbox-qr-ok:ROWS:" ++ show w
|
|
||||||
qfree qr
|
|
||||||
free cs
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
(* OCaml single-file execution can't use ocamlfind packages *)
|
|
||||||
(* Use Unix.open_process_in with qrencode CLI *)
|
|
||||||
let () =
|
let () =
|
||||||
let ic = Unix.open_process_in "qrencode -t ASCII -m 0 'unsandbox-qr-ok' | wc -l" in
|
let qr = Qrc.encode "unsandbox-qr-ok" in
|
||||||
let rows = String.trim (input_line ic) in
|
let rows = Array.length (Qrc.to_matrix qr) in
|
||||||
ignore (Unix.close_process_in ic);
|
Printf.printf "QR:unsandbox-qr-ok:ROWS:%d\n" rows
|
||||||
Printf.printf "QR:unsandbox-qr-ok:ROWS:%s\n" rows
|
|
||||||
|
|
|
||||||
34
test/qr.nim
34
test/qr.nim
|
|
@ -1,32 +1,4 @@
|
||||||
import dynlib
|
import qr
|
||||||
|
|
||||||
type
|
let qrCode = newQR("unsandbox-qr-ok")
|
||||||
QRcode {.pure.} = object
|
echo "QR:unsandbox-qr-ok:ROWS:" & $qrCode.size
|
||||||
version: cint
|
|
||||||
width: cint
|
|
||||||
data: pointer
|
|
||||||
|
|
||||||
type
|
|
||||||
QRencodeString = proc(s: cstring, ver: cint, level: cint, hint: cint, cs: cint): ptr QRcode {.cdecl.}
|
|
||||||
QRfree = proc(qr: ptr QRcode) {.cdecl.}
|
|
||||||
|
|
||||||
# Try versioned library names (Ubuntu 24.04 uses libqrencode.so.4)
|
|
||||||
var lib = loadLib("libqrencode.so.4")
|
|
||||||
if lib == nil:
|
|
||||||
lib = loadLib("libqrencode.so.3")
|
|
||||||
if lib == nil:
|
|
||||||
lib = loadLib("libqrencode.so")
|
|
||||||
if lib == nil:
|
|
||||||
quit("Failed to load libqrencode", 1)
|
|
||||||
|
|
||||||
let encode = cast[QRencodeString](lib.symAddr("QRcode_encodeString"))
|
|
||||||
let free_qr = cast[QRfree](lib.symAddr("QRcode_free"))
|
|
||||||
|
|
||||||
let qr = encode("unsandbox-qr-ok", 0, 1, 2, 1)
|
|
||||||
if qr != nil:
|
|
||||||
echo "QR:unsandbox-qr-ok:ROWS:", qr.width
|
|
||||||
free_qr(qr)
|
|
||||||
else:
|
|
||||||
echo "QR encode failed"
|
|
||||||
|
|
||||||
unloadLib(lib)
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use Text::QRCode;
|
use Imager::QRCode;
|
||||||
my $qr = Text::QRCode->new();
|
my $qr = Imager::QRCode->new(size => 1, margin => 0);
|
||||||
my $matrix = $qr->plot("unsandbox-qr-ok");
|
my $img = $qr->plot("unsandbox-qr-ok");
|
||||||
my $rows = scalar(@$matrix);
|
my $rows = $img->getheight();
|
||||||
print "QR:unsandbox-qr-ok:ROWS:$rows\n";
|
print "QR:unsandbox-qr-ok:ROWS:$rows\n";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue