All BASIC

BASIC Developer & Support Resources => Open Forum => Topic started by: John on November 25, 2019, 06:45:24 PM

Title: RaspberryBASIC.org Forum
Post by: John on November 25, 2019, 06:45:24 PM
I have been ban from the RPi forum for giving a moderator my opinion what their job should be.  >:(

I'm now posting on the RaspberryBASIC.org (https://raspberrybasic.org/forum) forum with my RPi efforts. If you would like to join us there, register to be a member.

I created a challenge that tests a common program among 11 different languages. Attached is the results of that challenge. The code for each can be found on the RaspberryBASIC.org forum.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on November 26, 2019, 07:52:19 AM
Your bash code is doing string>int conversions.

I ran your original code on my macbook laptop (i5):

Middle
Plus:   1000000
Minus:  0

real    0m20.839s
user    0m19.425s
sys    0m1.391s


Then I ran an updated version where I eliminated the conversions:

Middle
Plus:   1000000
Minus:  0

real    0m16.380s
user    0m15.342s
sys    0m1.025s


The above were with Bash 3.2.57, which comes standard on macOS 10.13.6

Finally, I ran the updated script using Bash 5.0.11:

Middle
Plus:   1000000
Minus:  0

real    0m10.185s
user    0m10.060s
sys    0m0.108s


Updated script:

Code: Bash
  1. declare -i accum=0
  2. declare -i milvar=1000000
  3.  
  4. for i in {1..1000000}
  5. do
  6.   ((++accum))
  7.   ((--milvar))
  8.   if (( $accum == $milvar ));
  9.     then
  10.       echo "Middle"
  11.   fi
  12. done
  13.  
  14. echo "Plus:  " $accum
  15. echo "Minus: " $milvar

AIR.

PS:  For giggles, I ran the updated script on my local Debian server (i7, Bash 5.0.3):

Middle
Plus:   1000000
Minus:  0

real    0m3.722s
user    0m3.665s
sys    0m0.057s


Didn't run this on my Pi, which is a 3B model and slow as crap...LOL

Title: Re: RaspberryBASIC.org Forum
Post by: John on November 26, 2019, 10:00:28 AM
Thanks AIR for the updated Bash script. I'll update the challenge with your submission. It would be great if you join us on the RasperryBASIC.org forum. We could use a mentor of your skill level.

I'm looking for Ruby, Rust and 8th submissions that are run on a RPi 4B. I can run the 8th submission if a binary is attached along with the source.

Update: I didn't realize Ruby comes pre-installed on the RPi.

Title: Re: RaspberryBASIC.org Forum
Post by: jalih on November 28, 2019, 06:36:51 AM

I'm looking for Ruby, Rust and 8th submissions that are run on a RPi 4B. I can run the 8th submission if a binary is attached along with the source.

Here is a 8th version using just the stack...
Code: [Select]
: plus-minus
  n:1+
  swap
  n:1-
  swap
  2dup n:= if
    "Middle\n" .
  then ;

: app:main
  1000000 0
  ' plus-minus 1000000 times
  "Plus: %d\nMinus: %d\n" s:strfmt .
  bye ;

RPI binary available here (https://www.dropbox.com/s/q6fkbhd86nbrfgj/mil.zip?dl=0)
Title: Re: RaspberryBASIC.org Forum
Post by: John on November 28, 2019, 09:40:34 AM
Thanks Jalih for the 8th submission! I'll update the forum and chart with your submission. Any chance of a round 3 submission that addresses arrays and strings?

Curious. Is your name pronounced like the month of July?
Title: Re: RaspberryBASIC.org Forum
Post by: John on November 29, 2019, 01:28:22 PM
Hi AIR,

Do you have time to slap together a C submission for the third round? Maybe some pointer magic would make it scream.

Title: Re: RaspberryBASIC.org Forum
Post by: jalih on November 30, 2019, 04:44:21 AM
Thanks Jalih for the 8th submission! I'll update the forum and chart with your submission. Any chance of a round 3 submission that addresses arrays and strings?

Curious. Is your name pronounced like the month of July?

Here is my round 3 submission... I used buffer to build string for speed as string concatenation is quite slow, as you are copying stuff around a lot.

Code: [Select]
1000000 constant LIMIT
LIMIT dup 26 n:mod n:- constant SLICE

LIMIT b:new true b:writable b:clear var, b
a:new 0 a:push var, a

: iterate
  dup >r n:1- dup 26 n:mod 65 n:+ b:!
  a @ r> a:push drop ;

: app:main
  b @ ' iterate 1 LIMIT loop
  0 SLICE b:slice b:rev >s
  s:len "r LEN: %d\n" s:strfmt .
  dup 26 s:lsub "Front: %s\n" s:strfmt .
  26 s:rsub "Back:  %s\n" s:strfmt .
  a @ LIMIT a:@ nip "UBVal: %d\n" s:strfmt .
  bye ;

RPI binary is available here (https://www.dropbox.com/s/vfy0sg5c3rbnojf/round3.zip?dl=0)

My name is pronounced more like: ja-li
Title: Re: RaspberryBASIC.org Forum
Post by: John on November 30, 2019, 09:02:59 AM
The whole purpose of round 3 is to see how well the language does with strings. I was hoping for some garbage collection along the way. Using a static buffer defeats the purpose.

Steps:

1. Build a character
2  Build alphabet string
3. Apend to result string
4. Reverse result string
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on November 30, 2019, 10:28:51 AM
Not sure why in the Python submission you're using Numpy to create a sized and initialized list.

You can simply do:

Code: Python
  1. a = [None] * 1000001

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on November 30, 2019, 10:35:34 AM
The whole purpose of round 3 is to see how well the language does with strings. I was hoping for some garbage collection along the way. Using a static buffer defeats the purpose.

Steps:

1. Build a character
2  Build alphabet string
3. Apend to result string
4. Reverse result string

Here is a version using strings instead of a buffer. I still convert the end result string to buffer, reverse and convert back to string. String reverse was very slow with 8th as it uses UTF8 strings. Developer of the 8th added optimization for the next version of 8th, if the string is just ASCII. Programming languages using ascii buffers for strings have a huge benefit in this challenge (remember that UTF-8 can have 1 to 4 bytes per character).

Code: [Select]
1000000 constant LIMIT

a:new 0 a:push var, a
"" var, s
"" var, t

: rev  \ s -- s
  b:new b:rev >s ;

: iterate
  s @ over n:1- 26 n:mod 65 n:+ s:+ s !
  s @ s:len 26 n:< not if
    t @ swap s:+ t !
    "" s !
  else
    drop
  then
  a:push ;

: app:main
  a @ ' iterate 1 LIMIT loop
  t @ rev s:len "r LEN: %d\n" s:strfmt .
  dup 26 s:lsub "Front: %s\n" s:strfmt .
  26 s:rsub "Back:  %s\n" s:strfmt .
  LIMIT a:@ nip "UBVal: %d\n" s:strfmt .
  bye ;

I updated the file in my previous download link, if you like to test the performance
Title: Re: RaspberryBASIC.org Forum
Post by: John on November 30, 2019, 11:08:57 AM
Thanks Jalih for the updated submission that is more inline with the challenge.

Thanks AIR for the Python optimization.
Title: Re: RaspberryBASIC.org Forum
Post by: John on November 30, 2019, 01:13:54 PM
AIR,

Your  Python optimization doesn't seem to work.

Code: Python
  1. # Python 3 - 1mil3.py
  2.  
  3. s = ""
  4. t = ""
  5. a = [None] * 1000001
  6.  
  7. for x in range(1000000):
  8.   s += chr(((x) % 26) + 65)
  9.   a[x] = x
  10.   if len(s) == 26:
  11.     t += s
  12.     s = ""
  13.  
  14. r = "".join(reversed(t))
  15.  
  16. print("r LEN: {}".format(len(r)))
  17. print("Front: {}".format(r[:26]))
  18. print("Back:  {}".format(r[-26:]))
  19. print("UBVal: {}".format(a[1000000]))
  20.  


pi@RPi4B:~/python-dev/examples $ /usr/bin/time python3 1mil3.py
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: None
1.84user 0.10system 0:01.94elapsed 99%CPU (0avgtext+0avgdata 32640maxresident)k
0inputs+0outputs (0major+7192minor)pagefaults 0swaps
pi@RPi4B:~/python-dev/examples $

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on November 30, 2019, 01:25:00 PM
try:

Code: Python
  1. for x in range(1000001):

Title: Re: RaspberryBASIC.org Forum
Post by: John on November 30, 2019, 01:32:29 PM
Nope.

Code: Python
  1. # Python 3 - 1mil3.py
  2.  
  3. s = ""
  4. t = ""
  5. for a in range(1000001):
  6.  
  7. for x in range(1000000):
  8.   s += chr(((x) % 26) + 65)
  9.   a[x] = x
  10.   if len(s) == 26:
  11.     t += s
  12.     s = ""
  13.  
  14. r = "".join(reversed(t))
  15.  
  16. print("r LEN: {}".format(len(r)))
  17. print("Front: {}".format(r[:26]))
  18. print("Back:  {}".format(r[-26:]))
  19. print("UBVal: {}".format(a[1000000]))
  20.  


pi@RPi4B:~/python-dev/examples $ /usr/bin/time python3 1mil3.py
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: None
1.88user 0.15system 0:02.04elapsed 99%CPU (0avgtext+0avgdata 32624maxresident)k
0inputs+0outputs (0major+7192minor)pagefaults 0swaps
pi@RPi4B:~/python-dev/examples $

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on November 30, 2019, 01:33:23 PM
You didn't make the change I posted.
Title: Re: RaspberryBASIC.org Forum
Post by: John on November 30, 2019, 01:46:34 PM
Can you post the complete script?
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on November 30, 2019, 01:50:12 PM
Can you post the complete script?

I think AIR ment:
Code: [Select]
# Python 3 - 1mil3.py

s = ""
t = ""
a = [None] * 1000001

for x in range(1000001):
  s += chr(((x) % 26) + 65)
  a[x] = x
  if len(s) == 26:
    t += s
    s = ""

r = "".join(reversed(t))

print("r LEN: {}".format(len(r)))
print("Front: {}".format(r[:26]))
print("Back:  {}".format(r[-26:]))
print("UBVal: {}".format(a[1000000]))
Title: Re: RaspberryBASIC.org Forum
Post by: John on November 30, 2019, 02:15:25 PM
That code returns the following.


pi@RPi4B:~/python-dev/examples $ /usr/bin/time python3 1mil3.py
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: None
1.92user 0.05system 0:01.97elapsed 99%CPU (0avgtext+0avgdata 32552maxresident)k
0inputs+0outputs (0major+7191minor)pagefaults 0swaps
pi@RPi4B:~/python-dev/examples $

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on November 30, 2019, 03:30:12 PM
something is not right on your end.

On my RPI 3B+

time python3 1mil3.py
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000

real    0m6.103s
user    0m6.042s
sys    0m0.060s


Title: Re: RaspberryBASIC.org Forum
Post by: John on November 30, 2019, 03:48:34 PM
Seems I had some file cross corruption.

Works on Python 2 & 3 now.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on November 30, 2019, 09:34:25 PM
Hi AIR,

Do you have time to slap together a C submission for the third round? Maybe some pointer magic would make it scream.
Code: C
  1. #define _GNU_SOURCE
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6.  
  7. #define join(write_to,  ...) {           \
  8.     char *tmp_string_for_extend = (write_to); \
  9.     asprintf(&(write_to), __VA_ARGS__);       \
  10.     free(tmp_string_for_extend);              \
  11. }
  12.  
  13. char *strrev(char *str)
  14. {
  15.     if (!str || ! *str)
  16.         return str;
  17.  
  18.     int i = strlen(str) - 1, j = 0;
  19.  
  20.     char ch;
  21.     while (i > j) {
  22.         ch = str[i];
  23.         str[i] = str[j];
  24.         str[j] = ch;
  25.         i--;
  26.         j++;
  27.     }
  28.     return str;
  29. }
  30.  
  31.  
  32. int main() {
  33.     int a[1000001] = {0};
  34.     int i;
  35.     char *s=NULL,*t=NULL;
  36.  
  37.     join(s,"");
  38.     join(t,"");
  39.  
  40.     for (int x = 0; x < 1000001; x++) {
  41.         a[x] = x;
  42.  
  43.         join(s,"%s%c",s,(x%26)+65);
  44.  
  45.         if (strlen(s) == 26) {
  46.             join(t,"%s%s",t,s);
  47.             join(s,"");
  48.         }
  49.     }
  50.  
  51.     free(s);
  52.     strrev(t);
  53.  
  54.     printf("r LEN: %lu\n",strlen(t));
  55.     printf("Front: %.*s\n", 26, t);
  56.     printf("Back: %s\n", t + strlen(t) - 26);
  57.     printf("UBVal: %d\n",a[1000000]);
  58.  
  59. }

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on November 30, 2019, 10:40:38 PM
I'm working on the Swift round 3 submission and it is running really slow. I don't have the array part working yet but even compiled doesn't seem  to make  a big difference. Any suggestions or code would be appreciated.

Code: Text
  1. // Swift 5.1.2 - 1mil3.swift
  2.  
  3. var s = ""
  4. var t = ""
  5. // var a = [Int]()
  6.  
  7. for x in 1...1000000 {
  8.   s += String(UnicodeScalar(UInt8(((x - 1) % 26) + 65)))
  9. //  a[x] = x
  10.   if s.count == 26 {
  11.     t = t + s
  12.     s = ""
  13.   }
  14. }
  15.  
  16. let r = String(t.reversed())
  17.  
  18. print("r LEN: ", r.count)
  19. print("Front: \(r.prefix(26))")
  20. print("Back:  \(r.suffix(26))")
  21. // print("UBVal: ", a[100000])
  22.  


pi@RPi4B:~/swift-dev/examples $ /usr/bin/time ./main
r LEN:  999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
338.87user 35.15system 6:14.07elapsed 99%CPU (0avgtext+0avgdata 10344maxresident)k
0inputs+0outputs (0major+4026645minor)pagefaults 0swaps
pi@RPi4B:~/swift-dev/examples $

Title: Re: RaspberryBASIC.org Forum
Post by: jalih on November 30, 2019, 11:19:34 PM
I'm working on the Swift round 3 submission and if is running really slow. I don't have the array part working yet but even compiled doesn't seem  to make  a big difference. Any suggestions or code would be appreciated.

Test what is the time without reversing the string. It took 8th a very long time to finish the task and the culprit was the s:rev not trying to optimize in case of ASCII string (It's already fixed for the next release.). It took over 30 minutes to finish...

I don't know if it's cheating or not but just use:
Code: [Select]
t.reversed()
Instead of:
Code: [Select]
String(t.reversed())

It's a lot faster just enumerating the characters from back to front without building a new collection for a reversed string. Some call it cheating, I call it smart thing to do!
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 01, 2019, 07:07:09 AM
Great job on the C submission AIR!

I wasn't looking forward to having to do that one. My hero.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 01, 2019, 09:31:26 AM
It looks like string reverse is the problem with Swift.

Code: Text
  1. // Swift 5.1.2 - 1mil3.swift
  2.  
  3. var s = ""
  4. var t = ""
  5. var r = ""
  6.  
  7. // var a = [Int]()
  8.  
  9. for x in 1...1000000 {
  10.   s += String(UnicodeScalar(UInt8(((x - 1) % 26) + 65)))
  11. //  a[x] = x
  12.   if s.count == 26 {
  13. //  t += s
  14.     r += s  
  15.     s = ""
  16.   }
  17. }
  18.  
  19. // let r = String(t.reversed())
  20.  
  21. print("r LEN: ", r.count)
  22. print("Front: \(r.prefix(26))")
  23. print("Back:  \(r.suffix(26))")
  24. // print("UBVal: ", a[100000])
  25.  


pi@RPi4B:~/swift-dev/examples $ /usr/bin/time ./main
r LEN:  999986
Front: ABCDEFGHIJKLMNOPQRSTUVWXYZ
Back:  ABCDEFGHIJKLMNOPQRSTUVWXYZ
35.55user 0.01system 0:35.59elapsed 99%CPU (0avgtext+0avgdata 8508maxresident)k
800inputs+0outputs (3major+918minor)pagefaults 0swaps
pi@RPi4B:~/swift-dev/examples $



@Jalih: I tried your t.reversed() idea but Swift complained.


pi@RPi4B:~/swift-dev/examples $ swiftc 1mil3.swift
1mil3.swift:21:7: error: cannot assign value of type 'ReversedCollection<String>' to type 'String'
r = t.reversed()
    ~~^~~~~~~~~~
pi@RPi4B:~/swift-dev/examples $
[/tt\
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 01, 2019, 11:51:33 AM
AIR,

Here is the results of your C submission.


pi@RPi4B:~/c-dev/examples $ gcc -O3 1mil3.c -o 1mil3
pi@RPi4B:~/c-dev/examples $ ls -l 1mil3
-rwxr-xr-x 1 pi pi 8140 Dec  1 11:23 1mil3
pi@RPi4B:~/c-dev/examples $ /usr/bin/time ./1mil3
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back: ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
45.56user 63.56system 1:49.17elapsed 99%CPU (0avgtext+0avgdata 23956maxresident)k
0inputs+0outputs (0major+7535448minor)pagefaults 0swaps
pi@RPi4B:~/c-dev/examples $

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 01, 2019, 01:01:50 PM
AIR,

Here is the results of your C submission.


Yep, it's not the most optimized way of implementing this, but you didn't want predefined buffers.  This implementation creates a new buffer each time 'join' is called and concats the data, which is expensive.

BTW, your swift code compiles and runs fine on my Mac Mini.  There is a difference when compiled in debug mode (the default) and release mode.

[riveraa@mini ~/Projects/Swift/blah] $ time .build/x86_64-apple-macosx10.10/release/blah
r LEN:  999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA

real    0m1.979s
user    0m1.846s
sys    0m0.130s

[riveraa@mini ~/Projects/Swift/blah] $ time .build/x86_64-apple-macosx10.10/debug/blah
r LEN:  999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA

real    0m2.678s
user    0m2.541s
sys    0m0.132s


For comparison, the C code executed on my Mac Mini:

r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back: ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000

real    0m2.554s
user    0m2.405s
sys    0m0.145s
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 01, 2019, 02:08:20 PM
ScriptBasic is acting cooky about its 50 second run.

I wonder what FreeBasic is doing under the covers with its conversion to C? Damn fast.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 01, 2019, 03:41:55 PM
Code: Go
  1. package main
  2.  
  3. import (
  4.     "fmt"
  5. )
  6.  
  7. // Reverse returns its argument string reversed rune-wise left to right.
  8. // From: https://github.com/golang/example/blob/master/stringutil/reverse.go
  9. func Reverse(s string) string {
  10.     r := []rune(s)
  11.     for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
  12.         r[i], r[j] = r[j], r[i]
  13.     }
  14.     return string(r)
  15. }
  16.  
  17. func main() {
  18.     var s = ""
  19.     var t = ""
  20.     var a [1000001]int
  21.  
  22.     for x := 0; x < 1000001; x++ {
  23.         a[x] = x
  24.  
  25.         s += string((x % 26) + 65)
  26.  
  27.         if len(s) == 26 {
  28.             t += s
  29.             s = ""
  30.         }
  31.     }
  32.  
  33.     t = Reverse(t)
  34.  
  35.     fmt.Println("r LEN: ", len(t))
  36.     fmt.Println("Front: ", t[0:26])
  37.     fmt.Println("Back:  ", t[len(t)-26:])
  38.     fmt.Println("UBVal: ", a[1000000])
  39.  
  40. }
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 01, 2019, 03:53:14 PM
Nice GOing!


pi@RPi4B:~/go-dev/examples $ go build 1mil3.go
pi@RPi4B:~/go-dev/examples $ /usr/bin/time ./1mil3
r LEN:  999986
Front:  ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:   ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal:  1000000
22.88user 4.71system 0:21.92elapsed 125%CPU (0avgtext+0avgdata 27036maxresident)k
0inputs+0outputs (0major+6656minor)pagefaults 0swaps
pi@RPi4B:~/go-dev/examples $

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 01, 2019, 08:44:47 PM
Last one I'm doing.

NIM
Code: [Select]
proc reverse*(str: string): string =
  result = ""
  for index in countdown(str.high, 0):
    result.add(str[index])

type
    milarray = array[1000001, int]

var
    s = ""
    t = ""
    r:string
    a:milarray

for x in 0..1000000:
    a[x] = x

    s &= chr((x mod 26) + 65)

    if s.len == 26:
        t &= s
        s = ""


r = t.reverse
echo "r Len: ",r.len
echo "Front: ",r[0..25]
echo "Back:  ",r[r.len-26..r.len-1]
echo "UBVal: ",a[1000000]

On my RPI 3B+:

riveraa@dpi:~ $ time ./mil
r Len: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000

real    0m0.123s
user    0m0.104s
sys    0m0.019s


AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 01, 2019, 09:02:49 PM
Wow!

Nim is fast.


pi@RPi4B:~/nim-dev/examples $ nim c -d:release onemil3.nim
Hint: used config file '/etc/nim/nim.cfg' [Conf]
Hint: system [Processing]
Hint: onemil3 [Processing]
Hint:  [Link]
Hint: operation successful (12410 lines compiled; 0.566 sec total; 10.754MiB peakmem; Release Build) [SuccessX]
pi@RPi4B:~/nim-dev/examples $ ls -l onemil3
-rwxr-xr-x 1 pi pi 57548 Dec  1 21:21 onemil3
pi@RPi4B:~/nim-dev/examples $ /usr/bin/time ./onemil3
r Len: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.06user 0.05system 0:00.12elapsed 99%CPU (0avgtext+0avgdata 10048maxresident)k
0inputs+0outputs (0major+2294minor)pagefaults 0swaps
pi@RPi4B:~/nim-dev/examples $

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 02, 2019, 05:43:01 PM
Okay, one more, using JADE
Code: C++
  1. #include <jade.hpp>
  2.  
  3. MAIN
  4.     STRING s,t,r;
  5.     ARRAY<int> a;
  6.  
  7.     FOR( VAR x = 0 TO x<1000001 STEP x++ ) DO
  8.         a.push_back(x);
  9.         s += (CHAR)(x%26)+65;
  10.  
  11.         IF ( LEN(s) == 26 ) THEN
  12.             t += s;
  13.             s = "";
  14.         END
  15.     END
  16.  
  17.     r = REVERSE$(t);
  18.  
  19.     PRINT("r LEN: ",LEN(t));
  20.     PRINT("Front: ", LEFT$(r,26));
  21.     PRINT("Back:  ", RIGHT$(r,26));
  22.     PRINT("UBVal: ",a[1000000]);
  23. END

On my RPI 3B+:

riveraa@dpi:~/Projects/jade $ g++ -std=c++11 mil.cpp -ljade -o mil
riveraa@dpi:~/Projects/jade $ time ./mil
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000

real    0m0.194s
user    0m0.165s
sys    0m0.029s


AIR.

JadeLib Repository (https://git.binarymagic.net/AIR/JadeLib)

EDIT:  Compiled with -O3, this is what I get on my RPI:

riveraa@dpi:~/Projects/jade $ g++ -O3 -std=c++11 mil.cpp -ljade -o mil
riveraa@dpi:~/Projects/jade $ time ./mil
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000

real    0m0.070s
user    0m0.060s
sys    0m0.010s



Title: Re: RaspberryBASIC.org Forum
Post by: John on December 02, 2019, 06:26:35 PM
Nice!

I'll setup a child board for JADE on the Raspberry BASIC forum.

When it comes to strings, C++ has a definite advantage.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 02, 2019, 08:22:23 PM
AIR,

I get the following errors trying to make JADE.


pi@RPi4B:~/jade-dev/jadelib $ make
Creating regex.o
Creating ltrim.o
Creating rtrim.o
Creating lcase.o
Creating instr.o
Creating grab.o
Creating split.o
Creating right.o
Creating repeat.o
Creating replace.o
Creating pad.o
bin.cc: In function ‘STRING BIN$(long int)’:
bin.cc:4:30: error: ‘CHAR_BIT’ was not declared in this scope
     std::bitset< sizeof(num)*CHAR_BIT > bits( num );
                              ^~~~~~~~
bin.cc:4:30: note: ‘CHAR_BIT’ is defined in header ‘<climits>’; did you forget to ‘#include <climits>’?
bin.cc:2:1:
+#include <climits>
 
bin.cc:4:30:
     std::bitset< sizeof(num)*CHAR_BIT > bits( num );
                              ^~~~~~~~
bin.cc:4:39: error: template argument 1 is invalid
     std::bitset< sizeof(num)*CHAR_BIT > bits( num );
                                       ^
bin.cc:5:17: error: request for member ‘to_string’ in ‘bits’, which is of non-class type ‘int’
     RETURN bits.to_string();
                 ^~~~~~~~~
make: *** [Makefile:38: bin.o] Error 1
pi@RPi4B:~/jade-dev/jadelib $

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 02, 2019, 08:33:47 PM
Do:

make clean

git pull

make

I added the missing header file to the bin.cc file.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 02, 2019, 09:24:30 PM
That worked. Posted on RB forum.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 03, 2019, 08:37:40 AM
Updated C version:

Code: C
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. char *strrev(char *str)
  6. {
  7.     if (!str || ! *str)
  8.         return str;
  9.  
  10.     int i = strlen(str) - 1, j = 0;
  11.  
  12.     char ch;
  13.     while (i > j) {
  14.         ch = str[i];
  15.         str[i] = str[j];
  16.         str[j] = ch;
  17.         i--;
  18.         j++;
  19.     }
  20.     return str;
  21. }
  22.  
  23.  
  24. int main() {
  25.     int a[1000001] = {0};
  26.     char *t=NULL;
  27.     char tmp[2] = {0};
  28.     char s[27] = {0};
  29.     FILE *t_stream;
  30.     size_t len;
  31.  
  32.     t_stream = open_memstream(&t, &len);
  33.  
  34.     for (int x = 0; x < 1000001; x++) {
  35.         a[x] = x;
  36.         tmp[0] = (char)(x%26)+65;
  37.  
  38.         strncat(s,tmp,2);
  39.  
  40.         if (strlen(s) == 26) {
  41.             fprintf(t_stream, "%s",s);
  42.             s[0] = '\0';
  43.         }
  44.  
  45.     }
  46.  
  47.     fclose(t_stream);
  48.  
  49.     strrev(t);
  50.  
  51.     printf("r LEN: %lu\n",strlen(t));
  52.     printf("Front: %.*s\n", 26, t);
  53.     printf("Back:  %s\n", t + strlen(t) - 26);
  54.     printf("UBVal: %d\n",a[1000000]);
  55.  
  56.     free(t);
  57.  
  58. }
  59.  

On my RPI 3B+

riveraa@dpi:~/Projects/C/1mil3 $ gcc -O3 mil.c -o mil
riveraa@dpi:~/Projects/C/1mil3 $ time ./mil
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000

real    0m0.201s
user    0m0.190s
sys    0m0.011s


AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 03, 2019, 09:35:02 AM
Thanks AIR for the C update. C sometimes needs prosthetics to compete.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 03, 2019, 02:12:06 PM
Thanks AIR for the C update. C sometimes needs prosthetics to compete.


...and swift needs a full body replacement....
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 03, 2019, 02:23:24 PM
I'm curious to hear what the Swift maintainer for ARM has to say about my findings.

I'm still willing to give Swift a chance. It's a late comer to open source but seems to have a lot of interest by the industry. I like the transparent wide character / Unicode support, It seems swift on other platforms.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 03, 2019, 06:45:01 PM
AIR,

Can you put a Bash 1mil3 together while I work on the Java version? That will finalize the language set and I can create the result table. It would be great if Mike has time to contribute a Scheme version.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 03, 2019, 08:45:55 PM
Bash version is not worth the effort, would take far too long to complete.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 03, 2019, 09:10:06 PM
Okay.

The Java version is posted on the  RaspberryBASIC forum.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 04, 2019, 08:40:38 AM
Swift maintainer response.

Quote
Yes, that let r = String(t.reversed()) in particular is extremely slow. That reversed() is the generic reversal defined on Collections here, and appears to be executed lazily (has an internal _base String that points to the original t, but the actual reversal is an O(n) swap).
But what adds 5 minutes or so of execution time is the String(Collection) initializer , as we can see running this modified sample using an Array:

It should be an O(n) operation with some additional conversions performed on all 32-bit platforms, but clearly there is something more going on.

Corner case as it may be, I'd open a ticket on https://bugs.swift.org/.

I can't determine if this is a 32 bit or ARM issue. In either case Swift on the RPi is a dead language for me until it's fixed.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 04, 2019, 01:30:58 PM
It's a Swift issue, because it's slow on my Mac too.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 04, 2019, 01:33:27 PM
It seems fast on my Lenovo laptop (Ubuntu / Windows) and the Swift Online Playground. It's only a dog on the RPi.

String / Array Language Challenge Results

I'm also viewing ScriptBasic in a different light. I will use it for prototyping and one off tasks but will use something else (Nim?) for deliverables.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 04, 2019, 05:47:33 PM
GoLang as tested really bothered me, so I rewrote an optimized version:

Code: Go
  1. package main
  2.  
  3. import (
  4.     "fmt"
  5.     "strings"
  6. )
  7.  
  8. // Reverse returns its argument string reversed rune-wise left to right.
  9. // From: https://github.com/golang/example/blob/master/stringutil/reverse.go
  10. func Reverse(s string) string {
  11.     r := []rune(s)
  12.     for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
  13.         r[i], r[j] = r[j], r[i]
  14.     }
  15.     return string(r)
  16. }
  17.  
  18. func main() {
  19.     var s strings.Builder
  20.     var r = ""
  21.     var t strings.Builder
  22.     var a [1000001]int
  23.  
  24.     for x := 0; x < 1000001; x++ {
  25.         a[x] = x
  26.  
  27.         s.WriteByte(byte((x % 26) + 65))
  28.  
  29.         if s.Len() == 26 {
  30.             t.WriteString(s.String())
  31.             s.Reset()
  32.         }
  33.     }
  34.  
  35.     r = Reverse(t.String())
  36.  
  37.     fmt.Println("r LEN: ", len(r))
  38.     fmt.Println("Front: ", r[0:26])
  39.     fmt.Println("Back:  ", r[len(r)-26:])
  40.     fmt.Println("UBVal: ", a[1000000])
  41.  
  42. }

On my RPI 3B+, using GO version 1.13.4:

riveraa@dpi:~/Projects/go/1mil3 $ go build
riveraa@dpi:~/Projects/go/1mil3 $ time ./1mil3
r LEN:  999986
Front:  ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:   ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal:  1000000

real    0m0.222s
user    0m0.230s
sys    0m0.021s


BTW, I picked up a RPI 4B (4G) this evening, but haven't set it up yet.

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 04, 2019, 05:56:11 PM
I'll rerun the GO submission and update the chart.

Congrats on the addition to your family.

GO code and charts updated.

Trifecta + 1 for you.  8)
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 04, 2019, 09:21:49 PM
I downloaded and installed BaCon 3.9.3 that was recently release and was suppose to have string handling improvements. No change from the previous BaCon run and it still can't integrate with the FLTK BaConGUI  for the RPi.

Title: Re: RaspberryBASIC.org Forum
Post by: John on December 05, 2019, 06:33:03 PM
One thing I noticed doing this string/array challenge is how similar basic syntax is among the languages.

Maybe a fun project might be is to create a universal language syntax translator. Sort of like Google translate but for computer languages.

There seems to be an abundance of BASIC to C translators.

@AIR: I still think your JADE C++ effort has promise. Is there a language reference guide or looking at examples it?

 
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 05, 2019, 09:00:40 PM
examples, and PROTOTYPES.txt / KEYWORDS.txt
BTW, what distro are you running?  The standard "time" binary doesn't match what you're running.  Is that part of the distro or some 3rd party binary?Nevermind, found it.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 05, 2019, 09:31:17 PM
The new time format was suggested by @ejolson on the RPi forum. This doesn't disable the time function we are use to. I'm thinking of renaming it to timex so I don't have to use the full path each time.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 05, 2019, 09:33:32 PM
So which distro and sd card are you using?  I'm using DietPi with a seemingly crappy Kingston 64 Gb card that claims 80MB/s but I'm no where near that in testing.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 05, 2019, 09:43:58 PM
I started off with the default Raspian Buster but after doing an update of the OS the default file manager stopped working. I installed Nautalus and gEdit and to my surprise I'm now running the LXDE desktop. I like the multiple desktops (2) and clean lightweight GUI.

I'm using a Sandisk Extreme 256 GB SD. ($44 for 2 at Costco)
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 05, 2019, 11:56:37 PM
I  thought I  would recompile scriba in single threaded mode and not use Peter's MyAlloc memory manager. As it turns out, it's shade slower and still a memory hog. I guess the only advantage of single threaded mode is you can access ScriptBasic's variable prointers directly and use standard alloc for memory allocation.


pi@RPi4B:~/sbrt/examples $ timex sbsu 1mil3.sb
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
16.74user 34.57system 0:51.34elapsed 99%CPU (0avgtext+0avgdata 172592maxresident)k
8inputs+0outputs (0major+4122824minor)pagefaults 0swaps
pi@RPi4B:~/sbrt/examples $

Title: Re: RaspberryBASIC.org Forum
Post by: John on December 06, 2019, 12:48:40 AM
What are your thoughts about this stringbuilder (https://github.com/cavaliercoder/c-stringbuilder) library for C. I wonder if it would be worth making an extension module out of it.

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 06, 2019, 01:55:27 PM
The only advantage I see is that it *might* work on Windows.


Otherwise, I would just use open_memstream.

Here is their sample code redone using open_memstream:

Code: C
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5. int main(int argc, char *argv[])
  6. {
  7.     int                i = 0;
  8.     size_t          len;
  9.     char            *str = NULL;
  10.     FILE            *sb;
  11.  
  12.     sb = open_memstream(&str,&len);
  13.  
  14.     for (i = 1; i < argc; i++) {
  15.         if (1 < i)
  16.             fprintf(sb,"%s", "->");
  17.         fprintf(sb, "[%s]", argv[i]);
  18.         puts(str);
  19.     }
  20.  
  21.     fclose(sb);
  22.     free(str);
  23. }

AIR.


Title: Re: RaspberryBASIC.org Forum
Post by: John on December 06, 2019, 02:21:51 PM
Thanks AIR for checking it out. Hope you're happy with your new RPi 4B 4GB.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 06, 2019, 03:40:52 PM
I installed on Windows B4J (Basic for Java) which is free. It has a great IDE and an easy to use BASIC. The generated Java class code should run on the RPi and other platforms. One step closer to Java. I'm not trying to follow Peter's path but it happens to be the resulting language for B4J.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 06, 2019, 03:56:26 PM
Another direction I'm looking at is using Nim and IUP on the RPi. I built an IUP distribution for the RPi for ScriptBasic that can be repurposed for the Nim binding.

I'm really bummed out how much memory SB uses for strings and arrays besides them being slow. On the bright side SB is the fastest way to get something done.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 06, 2019, 05:15:11 PM
I made the commitment to learn Nim.

Nim in Action (https://www.amazon.com/dp/1617293431/ref=cm_sw_r_em_apa_i_YWV6Db4DWM591)
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 07, 2019, 07:49:05 AM
Cool, the more tools in one's tool shed, the easier it becomes to create those holiday gifts.... :D
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 07, 2019, 08:23:23 AM
I need to gather all the extensions I use with SB so it feels like home.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 07, 2019, 10:00:48 AM
Bacon, using open_memstream:

Code: Text
  1. ' BaCon - 1mil3.bac
  2.  
  3. OPTION PARSE FALSE
  4.  
  5. s$ = ""
  6. t$ = ""
  7.  
  8. DECLARE a[1000001] TYPE NUMBER
  9. DECLARE len TYPE uint
  10. DECLARE *stream TYPE FILE
  11.  
  12. stream = open_memstream(&t$,&len)
  13.  
  14. FOR x = 1 TO 1000000
  15.   s$ = s$ & CHR$(MOD((x - 1), 26) + 65)
  16.   a[x] = x
  17.   IF LEN(s$) = 26 THEN
  18.     fprintf(stream,s$)
  19.     s$ = ""
  20.   END IF
  21. NEXT
  22. CLOSE FILE stream
  23.  
  24. r$ = REVERSE$(t$)
  25. FREE t$
  26. PRINT "r LEN: ",len
  27. PRINT "Front: ",LEFT$(r$, 26)
  28. PRINT "Back:  ",RIGHT$(r$, 26)
  29. PRINT "UBVal: ",a[1000000]

riveraa@rpi:~/Projects/Bacon $ /usr/bin/time ./mil
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.94user 0.05system 0:01.00elapsed 99%CPU (0avgtext+0avgdata 8024maxresident)k
0inputs+0outputs (0major+2066minor)pagefaults 0swaps
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 07, 2019, 10:04:28 AM
I'll update post and chart.

Expect a HUG from Peter.  :)
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 07, 2019, 10:06:48 AM
Run it on your machine, there is a difference in the timing I'm getting vs yours on the other tests.  That's why I asked which OS you're running before.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 07, 2019, 10:12:56 AM
Are my times better or worse than what you are seeing on you new RPI 4B?
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 07, 2019, 11:34:55 AM
Yours are better
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 07, 2019, 12:05:53 PM
Since the APT UPDATE/UPGRADE and installing Nautilus/ gEdit and the suprising switch to Raspbian LXDE desktop, it seem to run faster than when I started.

Based on the BaCon results, it looks like my RPi 4B runs twice as fast.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 07, 2019, 02:00:12 PM
It seems the PHP .= works like the ScriptBasic &=. Post and table updated.

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 07, 2019, 02:50:51 PM
Based on the BaCon results, it looks like my RPi 4B runs twice as fast.

Could be the OS; I'm running DietPi which is supposed to be an optimized Raspbian but I'm beginning to wonder....even overclocking had no impact (I have a case with a fan, overclocking to 1900Mhz the temp went up only 2 degrees F in stress test).
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 07, 2019, 03:09:51 PM
It looks like the two winners are for compiled and interpretative are Nim and PHP.

I'm surprise how much this challenge affected how I view the toolchain.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 07, 2019, 03:50:06 PM
Well, turns out it was the OS.  I installed Raspbian-lite on a spare sd card, and now the timings match yours.  DietPi -> Kicked To The Curb.....
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 07, 2019, 04:34:55 PM
I have been tempted to experiment with other OS offerings but I don't want to add another layer when stuff stops working.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 07, 2019, 07:08:20 PM
So here's something interesting.

I modified the Python entry as follows:

Code: Python
  1. #!/usr/bin/python3
  2.  
  3. import string
  4.  
  5. s = ""
  6. t = ""
  7. i = 0
  8. a = [None] * 1000001
  9.  
  10. for x in range(1000001):
  11.   i += 1
  12.   a[x] = x
  13.   if i == 26:
  14.     t += string.ascii_uppercase
  15.     i = 0
  16.  
  17. r = ''.join(reversed(t))
  18.  
  19. print("r LEN: {}".format(len(r)))
  20. print("Front: {}".format(r[:26]))
  21. print("Back:  {}".format(r[-26:]))
  22. print("UBVal: {}".format(a[1000000]))
  23.  

riveraa@rpi:~ $ /usr/bin/time ./mil.py
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.74user 0.09system 0:00.83elapsed 99%CPU (0avgtext+0avgdata 32648maxresident)k
0inputs+0outputs (0major+7178minor)pagefaults 0swaps


HOWEVER, the same code executed using Python2 shows:

riveraa@rpi:~ $ /usr/bin/time ./mil.py
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.57user 0.11system 0:00.68elapsed 99%CPU (0avgtext+0avgdata 26680maxresident)k
0inputs+0outputs (0major+6956minor)pagefaults 0swaps


Personally, after years of using Python2 I still haven't made the switch.  This is potentially another reason why I won't.

Food for thought, anyway...

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 07, 2019, 07:37:27 PM
Nice but it doesn't meet the goals of the challenge.

No MOD function building a character
No sub-string that appends the result string then clears it for reuse.

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 07, 2019, 07:43:50 PM
I posted this to show the difference in string performance; Python 3's UNICODE strings introduce additional overhead vs Python 2.
Did you ever post a formal spec for this challenge?  If so I must have missed it.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 07, 2019, 08:16:16 PM
The ScriptBasic example was the template for the challenge. Jalih wanted to use buffers and I explained the challenge rules in the response to him.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 07, 2019, 08:18:36 PM
The ScriptBasic example was the template for the challenge. Jalih wanted to use buffers and I explained the challenge rules in the response to him.

A formal spec details what's required and what isn't allowed, John.  Code isn't a formal spec, it's just code.  No worries, just clarifying.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 07, 2019, 09:00:38 PM
Basically it's you and I contributing to this challenge. If one looks at the code for each language you will quickly see a pattern. I wasn't counting on anyone else jumping in. Thanks for your many contributions to make this have an informative result.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 07, 2019, 09:16:08 PM
FreeBasic could use a makeover of it's StringReverse code. A million MID()S has to be painful. I was thinking a pointer swap in a loop.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 07, 2019, 09:34:03 PM
ScriptBasic updated.

Code: Script BASIC
  1. ' ScriptBasic - 1milfs.sb
  2.  
  3. OPEN  "t_file" FOR OUTPUT AS #1
  4.  
  5. s = ""
  6. SPLITA STRING(1000001,"0") BY "" TO a
  7.  
  8. FOR x = 1 TO 1000000
  9.   s &= CHR(((x - 1) % 26) + 65)
  10.   a[x] = x
  11.   IF LEN(s) = 26 THEN
  12.     PRINT #1, s
  13.     s = ""
  14.   END IF
  15. NEXT
  16. CLOSE(1)
  17.  
  18. flen = FILELEN("t_file")
  19. OPEN "t_file" FOR INPUT AS #1
  20. t = INPUT(flen, 1)
  21. CLOSE(1)
  22. t = STRREVERSE(t)
  23.  
  24. PRINT "t LEN: ",LEN(t),"\n"
  25. PRINT "Front: ",LEFT(t, 26),"\n"
  26. PRINT "Back:  ",RIGHT(t, 26),"\n"
  27. PRINT "UBVal: ",a[1000000],"\n"
  28.  


pi@RPi4B:~/sbrt/examples $ timex scriba 1milsf.sb
t LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
7.03user 0.84system 0:07.89elapsed 99%CPU (0avgtext+0avgdata 171504maxresident)k
0inputs+1976outputs (0major+43080minor)pagefaults 0swaps
pi@RPi4B:~/sbrt/examples $

Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 08, 2019, 01:54:34 AM
I have an updated 8th code that uses buffers instead of strings and should be at least ten times faster than my previous version. I will post it later when I get back home.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 08, 2019, 04:35:07 AM
Here is updated 8th code:
Code: [Select]
1000000 constant LIMIT

a:new 0 a:push var, a
0 b:new true b:writable var, s
0 b:new true b:writable var, t


: iterate
  s @ "" 2 pick n:1- 26 n:mod 65 n:+ s:+ b:append
  b:len 26 n:< not if
    t @ swap b:append drop
    0 b:new true b:writable s !
  else
    drop
  then
  a:push ;

: app:main
  a @ ' iterate 1 LIMIT loop
  t @ b:rev >s s:len "r LEN: %d\n" s:strfmt .
  dup 26 s:lsub "Front: %s\n" s:strfmt .
  26 s:rsub "Back:  %s\n" s:strfmt .
  LIMIT a:@ nip "UBVal: %d\n" s:strfmt .
  bye ;

RPI binary available here (https://www.dropbox.com/s/pi8gfyx07r3s3c8/r3.zip?dl=0)
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 08, 2019, 08:13:55 AM
@Jalih:  I get an error when executing your binary:

./r3
Exception: Expected Variable but got Buffer: : G:@: task REPL


@John: If this challenge is about evaluating over-all string performance for a given language, wouldn't saving to a file (bypassing appending to a string in memory) run counter to evaluating over-all string performance?  I'm basing this on what you said about the original SB submission being the 'spec' for this challenge.

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 08, 2019, 08:23:45 AM
Big speed boost with Go and Strings.Builder comes from not having to allocate memory all the time, but using buffer for slice and only growing it some amount when needed.

There is a handy feature on 8th, that allows associating data item with some extra data. That allows one to easily write custom string builder for ascii strings.
Code: [Select]
1000000 constant LIMIT

a:new 0 a:push var, a
26 b:new true b:writable b:clear 0 extra! var, s
LIMIT b:new true b:writable b:clear 0 extra! var, t

: write-byte  \ b byte -- b
  swap extra@ rot b:!
  extra@ n:1+ extra! ;

: write  \ b1 b2 -- b1
  extra@ dup >r 0 swap b:slice >r
  extra@ r> swap b:splice
  extra@ r> n:+ extra! ;

: reset  \ b -- b
  b:clear
  0 extra! ;

: len  \ b -- b n
  extra@ ;

: slice
  extra@ 0 swap b:slice ;

: rev  \ b - b
  extra@ swap b:rev swap extra! ;

: iterate
  s @ over n:1- 26 n:mod 65 n:+ write-byte
  len 26 n:< not if
    t @ swap write drop
    s @ reset drop
  else
    drop
  then
  a:push ;

: app:main
  a @ ' iterate 1 LIMIT loop
  t @ slice rev >s s:len "r LEN: %d\n" s:strfmt .
  dup 26 s:lsub "Front: %s\n" s:strfmt .
  26 s:rsub "Back:  %s\n" s:strfmt .
  LIMIT a:@ nip "UBVal: %d\n" s:strfmt .
  bye ;

General purpose version should test if there is enough room on the buffer and grow buffer, if needed.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 08, 2019, 08:28:38 AM
@Jalih:  I get an error when executing your binary:

./r3
Exception: Expected Variable but got Buffer: : G:@: task REPL

Have to take look, I might have accidentally build some work in progress version...
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 08, 2019, 08:39:01 AM
Here should be working 8th binary (https://www.dropbox.com/s/pi8gfyx07r3s3c8/r3.zip?dl=0) for my version.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 08, 2019, 09:21:23 AM
AIR,

I used the same concept you did for BaCon to speed up its dynamic result 'string'.

The only rule is you can't use fixed size buffers. Storage needs to be dynamic.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 08, 2019, 09:21:54 AM
Python 3 update.  This is as tight as I can get it at the moment.

Code: Python
  1. #!/usr/bin/python3
  2.  
  3. r = ""
  4. a = [None] * 1000001
  5. b = bytearray(26)
  6.  
  7. for x in range(1000001):
  8.     b[x % 26] = (x % 26) + 65
  9.     a[x] = x
  10.     if x % 26 == 25:
  11.         r += b.decode()[::-1]
  12.  
  13. print("r LEN: {}".format(len(r)))
  14. print("Front: {}".format(r[:26]))
  15. print("Back:  {}".format(r[-26:]))
  16. print("UBVal: {}".format(a[1000000]))

riveraa@rpi:~/tmp $ /usr/bin/time ./mil2.py
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
1.32user 0.08system 0:01.41elapsed 99%CPU (0avgtext+0avgdata 27212maxresident)k
0inputs+0outputs (0major+5993minor)pagefaults 0swaps
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 08, 2019, 09:32:58 AM
AIR,

I used the same concept you did for BaCon to speed up its dynamic result 'string'.

Not exactly.  I'm not writing to or reading from a file in the filesystem.  I'm still accessing a string, as an object in memory that exposes methods usually associated with files.

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 08, 2019, 09:52:04 AM
The only rule is you can't use fixed size buffers. Storage needs to be dynamic.

Most of the libraries use some sort of pre-defined buffer size and grow that buffer only if capacity is reached. It makes no sense to use fully dynamic buffer as allocating new buffer and copying current buffer contents is a very costly operation to do 38461 times in this challenge!
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 08, 2019, 10:31:05 AM
Challenge Rules

1. Create an upper case A-Z  character based on the FOR index.

2. Capture the characters in a dynamic reusable string.

3. Maintain a dynamic result string / object / ...

4. Reverse the result.

ScriptBasic is still challenge compliant.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 08, 2019, 11:47:52 AM
Another Python3 update:

Code: Python
  1. #!/usr/bin/python3
  2.  
  3. def main():
  4.     r = ""
  5.     a = [None] * 1000001
  6.     b = bytearray(26)
  7.     decode = bytearray.decode
  8.     blah = range(1000001)
  9.  
  10.     for x in blah:
  11.         b[x % 26] = (x % 26) + 65
  12.         a[x] = x
  13.         if x % 26 == 25:
  14.             r += decode(b[::-1])
  15.  
  16.     print("r LEN: {}".format(len(r)))
  17.     print("Front: {}".format(r[:26]))
  18.     print("Back:  {}".format(r[-26:]))
  19.     print("UBVal: {}".format(a[1000000]))
  20.  
  21.  
  22.  
  23. if __name__ == "__main__":
  24.     main()

riveraa@rpi:~/tmp $ /usr/bin/time ./mil4.py
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.93user 0.13system 0:01.06elapsed 99%CPU (0avgtext+0avgdata 27276maxresident)k
0inputs+0outputs (0major+5997minor)pagefaults 0swaps


AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 08, 2019, 12:47:23 PM
Last Python update:

Code: Python
  1. #!/usr/bin/python3
  2.  
  3. def main():
  4.     t = []
  5.     r =""
  6.     a = [None] * 1000001
  7.     b = bytearray(26)
  8.     decode = bytearray.decode
  9.     blah = range(1000001)
  10.     append = list.append
  11.  
  12.     for x in blah:
  13.         b[x % 26] = (x % 26) + 65
  14.         a[x] = x
  15.         if x % 26 == 25:
  16.             append(t, decode(b[::-1]))
  17.  
  18.     r = ''.join(t)
  19.  
  20.     print("r LEN: {}".format(len(r)))
  21.     print("Front: {}".format(r[:26]))
  22.     print("Back:  {}".format(r[-26:]))
  23.     print("UBVal: {}".format(a[1000000]))
  24.  
  25.  
  26.  
  27. if __name__ == "__main__":
  28.     main()

r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.90user 0.09system 0:01.00elapsed 99%CPU (0avgtext+0avgdata 29532maxresident)k
0inputs+0outputs (0major+6508minor)pagefaults 0swaps


AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 08, 2019, 01:04:09 PM
Now I'm glad I had that second cup of coffee before updating the Python post.  :)

Is that doing the reverse on the fly rather than waiting until the result string is built?

You can't get any greyer with that submission.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 08, 2019, 01:24:33 PM
Yes doing it on the fly, the reversed() function is stupidly inefficient especially with large strings.

I'm doing the reversal with  "[::-1]", after generating the upper case alphabet.


Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 08, 2019, 01:43:12 PM
Hope you took the time for a third cup of coffee, John.   8)

FINAL PYTHON SUBMISSION

Code: Python
  1. #!/usr/bin/python3
  2.  
  3. def main():
  4.     t = []
  5.     r =""
  6.     a = [None] * 1000001
  7.     b = bytearray(26)
  8.     decode = bytearray.decode
  9.     blah = range(1000001)
  10.     append = list.append
  11.  
  12.     for x in blah:
  13.         alpha = x % 26
  14.         b[alpha] = alpha + 65
  15.         a[x] = x
  16.         if alpha == 25:
  17.             append(t, decode(b[::-1]))
  18.  
  19.     r = ''.join(t)
  20.  
  21.     print("r LEN: {}".format(len(r)))
  22.     print("Front: {}".format(r[:26]))
  23.     print("Back:  {}".format(r[-26:]))
  24.     print("UBVal: {}".format(a[1000000]))
  25.  
  26.  
  27.  
  28. if __name__ == "__main__":
  29.     main()

r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.59user 0.09system 0:00.68elapsed 99%CPU (0avgtext+0avgdata 29452maxresident)k
0inputs+0outputs (0major+6390minor)pagefaults 0swaps


I realized that I was calculating the modulo of 'x' multiple times; assigned it to a variable and it made a huge difference!

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 08, 2019, 02:30:06 PM
Saved by a litter box change.

I'll have it posted shortly.


pi@RPi4B:~/python-dev/examples $ timex python3 1mil3-2,py
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.68user 0.08system 0:00.78elapsed 99%CPU (0avgtext+0avgdata 29952maxresident)k
0inputs+0outputs (0major+6541minor)pagefaults 0swaps
pi@RPi4B:~/python-dev/examples $

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 08, 2019, 03:23:34 PM
The only rule is you can't use fixed size buffers. Storage needs to be dynamic.

Most of the libraries use some sort of pre-defined buffer size and grow that buffer only if capacity is reached. It makes no sense to use fully dynamic buffer as allocating new buffer and copying current buffer contents is a very costly operation to do 38461 times in this challenge!

You can mitigate some of this if you use some sort of mutable dynamic buffer/array/list/etc.

For my final Python submission, I switched from using straight strings to using a list, which is analogous to an array and added to it in place.  While the size was extended when needed, copying the existing data wasn't needed.

BTW, your 8th submission only runs 1 out of 4 times on my system; the error is the same as before.

Here's the timeing on my RasPi for a successful run:

riveraa@rpi:~/tmp $ timex ./r3
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
1.70user 0.15system 0:01.85elapsed 99%CPU (0avgtext+0avgdata 53088maxresident)k
0inputs+0outputs (0major+12363minor)pagefaults 0swaps


AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 08, 2019, 03:36:50 PM
Is a StringBuilder a buffer under the covers that one populates / resets with calls to it?
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 08, 2019, 03:39:59 PM
I'm waiting for Jalih to show us a 8th submission that lives within the generous rules stated. Exposed buffer code will surely get you busted.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 08, 2019, 03:50:05 PM
Is a StringBuilder a buffer under the covers that one populates / resets with calls to it?

Basically, yes.

Read this for some insight:  https://www.thecodingdelight.com/java-stringbuilder-class/
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 08, 2019, 04:03:48 PM
What open the door for me with StringBuilder in the Java submission was the string reverse example I found. Appling it to the rest of the code made all the difference.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 08, 2019, 04:25:05 PM
Here is some interesting info about ScriptBasic array memory usage. I remarked out the array code. I really need to get the Judy extension module built.


pi@RPi4B:~/sbrt/examples $ timex scriba 1milsf.sb
t LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
5.26user 0.29system 0:05.58elapsed 99%CPU (0avgtext+0avgdata 3696maxresident)k
272inputs+1968outputs (0major+846minor)pagefaults 0swaps
pi@RPi4B:~/sbrt/examples $


With Array


pi@RPi4B:~/sbrt/examples $ timex scriba 1milsf.sb
t LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
7.03user 0.84system 0:07.89elapsed 99%CPU (0avgtext+0avgdata 171504maxresident)k
0inputs+1976outputs (0major+43080minor)pagefaults 0swaps
pi@RPi4B:~/sbrt/examples $


I thought I would give the Linux memory drive device (/dev/shm) a try with ScriptBasic. It seems the SD drive is just as fast.


pi@RPi4B:~/sbrt/examples $ timex scriba 1milsf.sb
t LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
7.05user 0.47system 0:07.52elapsed 99%CPU (0avgtext+0avgdata 171472maxresident)k
0inputs+0outputs (0major+43081minor)pagefaults 0swaps
pi@RPi4B:~/sbrt/examples $


Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 08, 2019, 06:10:38 PM
It's not storage I/O, I think you're seeing the effect that Jalih was referring to, the fact that in most higher level languages strings are immutable by default.

So (potentially) the slowness is due to new strings being allocated to address the fact that the space the current string holds is not large enough for the concatenation. Then the current string's contents need to be copied over to the newly allocated string along with whatever you're trying to add.


This is even more noticeable is SB because essentially every object is a string.  I'm guessing that this is the reason for the higher than normal memory usage this challenge is showing for the SB submissions.

BTW, what's Judy?

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 08, 2019, 06:18:45 PM
Judy Array C Library (http://judy.sourceforge.net/)

SB"s variables are variant based. Flexible but costly to performace.

SB arrays are dynamic linked lists.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 08, 2019, 08:51:19 PM
I'm waiting for Jalih to show us a 8th submission that lives within the generous rules stated. Exposed buffer code will surely get you busted.

I will soon post version with fully featured string builder that can dynamically grow ascii character buffers, if need to. If you accept other entrys using string builders, then you must accept my 8th version.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 08, 2019, 08:54:13 PM
BTW, your 8th submission only runs 1 out of 4 times on my system; the error is the same as before.

Have to boot up my ROCK64, add some debug code and see why! On Windows, it works every time!
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 08, 2019, 09:14:04 PM
The keyword is dynamic.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 08, 2019, 10:06:54 PM
Was wondering how this would look if I used GLIB:

Code: C
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <glib.h>
  4. #include <glib/gprintf.h>
  5.  
  6. int main(int argc, char **argv) {
  7.         GString *s = g_string_new(NULL);
  8.         GString *t = g_string_new(NULL);
  9.         int a[1000001] = {0};
  10.  
  11.         for (int x = 0; x < 1000001; x++) {
  12.                 a[x] = x;
  13.                 g_string_append_c(s,(char)(x%26)+65);
  14.                 if (s->len == 26) {
  15.                         g_string_append(t,g_strreverse(s->str));
  16.                         g_string_assign(s,"");
  17.                 }
  18.         }
  19.  
  20.         g_printf("r LEN: %d\n",t->len);
  21.         g_printf("Front: %.*s\n", 26, t->str);
  22.         g_printf("Back:  %s\n", t->str + t->len - 26);
  23.         g_printf("UBVal: %d\n",a[1000000]);
  24.  
  25.         g_string_free (s,TRUE);
  26.         g_string_free (t,TRUE);
  27. }

riveraa@rpi:~/Projects/glib $ gcc -O3 mil.c  $(pkg-config --libs --cflags glib-2.0) -o mil
riveraa@rpi:~/Projects/glib $ timex ./mil
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.04user 0.02system 0:00.07elapsed 98%CPU (0avgtext+0avgdata 6384maxresident)k
0inputs+0outputs (0major+1334minor)pagefaults 0swaps


AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 08, 2019, 10:44:41 PM
The keyword is dynamic.
All the fast entries here don't use immutable strings. They use buffer that can grow, if needed! Less allocations and copying stuff around makes program faster! You can set the size for Go's string builders internal slice, so no new memory allocations and unnecessary copying is needed!
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 09, 2019, 06:48:42 AM
C finally leads the pack.

Nice job!
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 09, 2019, 08:53:14 AM
The keyword is dynamic.
All the fast entries here don't use immutable strings. They use buffer that can grow, if needed! Less allocations and copying stuff around makes program faster! You can set the size for Go's string builders internal slice, so no new memory allocations and unnecessary copying is needed!

Pre-allocating the buffer would be the most efficient way to do this, of course.  But as we've seen with multiple submissions, not pre-allocating the space highlights the issues with immutable strings which you've pointed out.  This challenge is interesting in that it forces us to come up with alternative approaches to string handling that could be used when the size of strings is unknown, while hopefully maintaining decent overall performance.

My submissions using the open_memstream function is a good example; I didn't even know this function existed prior to this challenge.  So I learned something new!

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 09, 2019, 09:00:20 AM
This challenge highlighted ScriptBasic's performance penalties and excessive memory using its strings and arrays. The challenge made me see that there are better solutions without a huge learning curve.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 09, 2019, 09:18:07 AM
Pre-allocating the buffer would be the most efficient way to do this, of course.  But as we've seen with multiple submissions, not pre-allocating the space highlights the issues with immutable strings which you've pointed out.  This challenge is interesting in that it forces us to come up with alternative approaches to string handling that could be used when the size of strings is unknown, while hopefully maintaining decent overall performance.
My point was that all the really fast versions here use pre-allocated buffer under the cover to store the string and grow the buffer some amount only, if needed. Go's string builder does that as well as GString. Not sure about the default allocated buffer sizes, but it makes sense to minimize allocations and copying. My current 8th version (not posted yet) uses buffer to store ascii string bytes and that buffer can dynamically grow, if needed.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 09, 2019, 09:52:06 AM
That sounds acceptable to me.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 09, 2019, 10:11:35 AM
My point was that all the really fast versions here use pre-allocated buffer under the cover to store the string and grow the buffer some amount only, if needed. Go's string builder does that as well as GString. Not sure about the default allocated buffer sizes, but it makes sense to minimize allocations and copying. My current 8th version (not posted yet) uses buffer to store ascii string bytes and that buffer can dynamically grow, if needed.

Well, yes.  You shouldn't assign to a char*, for example, unless you've allocated enouch space for it. 


I think the wording is what is confusing things;  what I mean by pre-allocated buffer is a STATIC buffer, for example char a[65535].  You can't call "realloc' on that, so you have to create a new string if you want to 'add' to it.

So now the question becomes, what is a 'fair' initial buffer size.  'g_string_new(NULL)', which is what I used in the GLIB submission, creates an initial buffer that is 2 bytes in size (according to the source code for GString).  I could have passed an initial size, like the 65K above, but I wanted to test how the default operated from a performance standpoint.


Anyway, I'm looking forward to seeing how you choose to implement this, Jalih.

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 09, 2019, 10:20:51 AM
Had a few minutes, decided to try a Ruby version

Code: Ruby
  1. #!/usr/bin/ruby
  2.  
  3. a = [10000001]
  4. s = ""
  5. t = ""
  6.  
  7.  
  8. (0..1000001).each do |x|
  9.         a << x+1
  10.         s << (x%26)+65
  11.         if s.length == 26
  12.                 t << s.reverse
  13.                 s.clear
  14.         end
  15. end
  16.  
  17. puts "r LEN: #{t.length}"
  18. puts "Front: #{t[0,26]}"
  19. puts "Back:  #{t[-26,26]}"
  20. puts "UBVal: #{a[1000000]}"
  21.  

riveraa@rpi:~/Projects/ruby $ timex ./mil.rb .
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.89user 0.03system 0:00.93elapsed 99%CPU (0avgtext+0avgdata 12084maxresident)k
0inputs+0outputs (0major+2161minor)pagefaults 0swaps


AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 09, 2019, 10:26:43 AM
Thanks!

I forgot to do Ruby for round three. There is a round two Ruby post in the challenge.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 09, 2019, 11:11:24 AM
Anyway, I'm looking forward to seeing how you choose to implement this, Jalih.

I will post my fully featured version for 8th using simple string builder later when I get back home. Here is naive version using dynamic buffers. Size of buffers is initially 0.
Code: [Select]
1000000 constant LIMIT

a:new 0 a:push var, a
0 b:new true b:writable var, s
0 b:new true b:writable var, t


: iterate
  s @ "" 2 pick n:1- 26 n:mod 65 n:+ s:+ b:append
  b:len 26 n:< not if
    t @ swap b:append drop
    0 b:new true b:writable s !
  else
    drop
  then
  a:push ;

: app:main
  a @ ' iterate 1 LIMIT loop
  t @ b:rev >s s:len "r LEN: %d\n" s:strfmt .
  dup 26 s:lsub "Front: %s\n" s:strfmt .
  26 s:rsub "Back:  %s\n" s:strfmt .
  LIMIT a:@ nip "UBVal: %d\n" s:strfmt .
  bye ;

RPI binary (https://www.dropbox.com/s/pi8gfyx07r3s3c8/r3.zip?dl=0)
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 09, 2019, 11:20:50 AM
AIR,

I seem to have a problem compiling your latest C  code.


pi@RPi4B:~/c-dev/examples $ gcc -O3 1mil3-3.c  $(pkg-config --libs --cflags glib-2.0) -o 1mil3-3
1mil3-3.c: In function ‘main’:
1mil3-3.c:28:9: error: expected declaration or statement at end of input
         g_string_free (t,TRUE);
         ^~~~~~~~~~~~~
pi@RPi4B:~/c-dev/examples $

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 09, 2019, 01:11:43 PM
Usually caused by a missing bracket or semi-colon.  You sure you copied all of the code including end bracket?

Edit:  I copy/pasted from the post onto another machine (a mac), compiled/executed fine here.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 09, 2019, 03:10:00 PM
Yep. Missed the final }.

Suggestion: Put your code tags on separate lines. I have got caught before not copying your code tags which had code attached.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 09, 2019, 04:59:41 PM
Rust.  Not liking this one too much personally from a syntax standpoint, but you had asked for a Rust submission in the beginning...

Code: Text
  1. fn main() {
  2.     let mut s = "".to_string();
  3.     let mut t = "".to_string();
  4.     let mut a = [0;1000001];
  5.  
  6.     for x in 0..1000001 {
  7.         a[x] = x;
  8.         let b   = ( x%26 ) as u8;
  9.         let c = ( b+65 ) as char;
  10.         s.push( c );
  11.         if s.len() == 26 {
  12.             let reversed: String = s.chars().rev().collect();
  13.             t.push_str( &reversed );
  14.             s.clear();
  15.         }
  16.     }
  17.     println!( "r LEN: {}",  t.len() );
  18.     println!( "Front: {}",  &t[..26] );
  19.     println!( "Back:  {}",  &t[t.len()-26..]);
  20.     println!( "UBVal: {}",  a[1000000] );
  21.  
  22. }
  23.  


riveraa@rpi:~/Projects/rust/1mil3/mil $ timex target/release/mil
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.07user 0.02system 0:00.10elapsed 99%CPU (0avgtext+0avgdata 6356maxresident)k
0inputs+0outputs (0major+1392minor)pagefaults 0swaps


AIR.

EDIT: arm binary attached.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 09, 2019, 05:44:15 PM
Thanks Air for the rust submission. Can you attach the binary so I don't have to install Rust?

Damn. That is one big executable. If Microsoft rewrites Windows in Rust, you will need a terabyte of space just to load the OS.

rwxr-xr-x 1 pi pi 2582500 Dec  9 17:47 1mil3

pi@RPi4B:~/rust-dev/examples $ timex ./1mil3
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.10user 0.02system 0:00.12elapsed 96%CPU (0avgtext+0avgdata 6336maxresident)k
0inputs+0outputs (0major+1392minor)pagefaults 0swaps
pi@RPi4B:~/rust-dev/examples $
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 09, 2019, 06:51:44 PM
The ARM Swift maintainer posted an alternative to my script which I'll try and post its results.

No improvement with his substitute string reverse function.

Code: Text
  1. // Swift 5.1.2 - 1mil3-2.swift
  2.  
  3. var s = ""
  4. var t = ""
  5. var a = [Int]()
  6.  
  7. for x in 1...1000000 {
  8.   s += String(UnicodeScalar(UInt8(((x - 1) % 26) + 65)))
  9.   a.append(x)
  10.   if s.count == 26 {
  11.     t += s
  12.     s = ""
  13.   }
  14. }
  15.  
  16. var r = Array(t)
  17. let count = t.count
  18. for i in 0..<count/2 {
  19.   r.swapAt(i, count - ((i + 1) as Int))
  20. }
  21.  
  22. let revstr=String(r)
  23.  
  24. print("r LEN: ", revstr.count)
  25. print("Front: \(revstr.prefix(26))")
  26. print("Back:  \(revstr.suffix(26))")
  27. print("UBVal: ", a[100000 - 1])
  28.  


pi@RPi4B:~/swift-dev/examples $ timex ./main
r LEN:  999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal:  100000
317.29user 0.09system 5:17.71elapsed 99%CPU (0avgtext+0avgdata 25444maxresident)k
7096inputs+0outputs (32major+6377minor)pagefaults 0swaps
pi@RPi4B:~/swift-dev/examples $



Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 09, 2019, 08:29:43 PM
Old School (Pascal)
FreePascal:

Code: Pascal
  1. program mil;
  2.  
  3. Uses StrUtils;
  4.  
  5. var
  6.     s:AnsiString;
  7.     t:AnsiString;
  8.     c:AnsiChar;
  9.     a:array[0..1000001] of int32;
  10.     x:int32;
  11. begin
  12.     s := '';
  13.     t := '';
  14.     for x := 0 to 1000001 do
  15.     begin
  16.         c :=  chr( (x mod 26)+65 );
  17.         a[x] := x;
  18.         s += c;
  19.         if Length(s) = 26 then
  20.         begin
  21.             t += ReverseString(s);
  22.             s := '';
  23.         end;
  24.     end;
  25.  
  26.     writeln( 'r len: ', Length(t) );
  27.     writeln( 'Front: ', LeftStr(t,26) );
  28.     writeln( 'Back:  ', RightStr(t,26) );
  29.     writeln( 'UBVal: ', a[1000000]);
  30. end.
  31.  
  32.  

riveraa@rpi:~/Projects/fpc/1mil3 $ fpc -O3 -XX -Xs  mil.pas

riveraa@rpi:~/Projects/fpc/1mil3 $ timex ./mil
r len: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.19user 0.02system 0:00.22elapsed 99%CPU (0avgtext+0avgdata 5604maxresident)k
0inputs+0outputs (0major+1430minor)pagefaults 0swaps


AIR.

EDIT:  Binary attached.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 09, 2019, 09:10:59 PM
Wow!

You're like a language machine.   8)
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 09, 2019, 09:20:46 PM
Pascal was my first "REAL" language (via Delphi 6 on Windows a long time ago).

As far a Swift:  The problem is not the Reverse, the problem is the adding to the string.  Looks like it's creating a new string each time you try to add to it.

Try changing "+=" to ".append". like this:

Code: Text
  1. s.append(String(UnicodeScalar(UInt8(((x - 1) % 26) + 65))))

and

Code: Text
  1. t.append(s)

On my Mac, with the array portion commented out, it took the execution from 0m2.056s down to 0m0.673s.

The next biggest issue is all of the intermediate objects that are created with the crazy casting you have to do to get the integer over to a Character then to a String.  That adds up quickly with the loop we have going.

AIR.

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 09, 2019, 10:11:08 PM
John, try this:

Code: Text
  1. / Swift 5.1.2 - 1mil3.swift
  2.  
  3. var s = ""
  4. var t = ""
  5. var a = [Int](repeating: 0, count: 1000001)
  6.  
  7. for x in 1...1000000 {
  8.   let c = (x - 1) % 26
  9.   s.append(String(UnicodeScalar(UInt8(c + 65))))
  10.   a[x] = x
  11.   if c == 25 {
  12.     t.append(String(s.reversed()))
  13.     s = ""
  14.   }
  15. }
  16.  
  17. // let r = t
  18.  
  19. print("r LEN: ", t.count)
  20. print("Front: \(t.prefix(26))")
  21. print("Back:  \(t.suffix(26))")
  22. print("UBVal: ", a[100000])
  23.  
  24.  

On my Mac, not installing Swift on my RPI:


[riveraa@mini ~/Projects/Swift/1mil3] $ swift build -c release
Compile Swift Module '_mil3' (1 sources)
Linking ./.build/x86_64-apple-macosx10.10/release/1mil3
[riveraa@mini ~/Projects/Swift/1mil3] $ time .build/release/1mil3
r LEN:  999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal:  100000

real    0m0.338s
user    0m0.323s
sys    0m0.010s


AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 09, 2019, 10:12:54 PM
With the append and doing string reverse on  the fly, we went from 5 minutes to 43 seconds.

Code: Text
  1. // Swift 5.1.2 - 1mil3-2.swift
  2.  
  3. var s = ""
  4. var t = ""
  5. var a = [Int]()
  6.  
  7. for x in 1...1000000 {
  8.   s.append(String(UnicodeScalar(UInt8(((x - 1) % 26) + 65))))
  9.   a.append(x)
  10.   if s.count == 26 {
  11.     let r = String(s.reversed())
  12.     t.append(r)
  13.     s = ""
  14.   }
  15. }
  16.  
  17. print("t LEN: ", t.count)
  18. print("Front: \(t.prefix(26))")
  19. print("Back:  \(t.suffix(26))")
  20. print("UBVal: ", a[100000 - 1])
  21.  


pi@RPi4B:~/swift-dev/examples $ swiftc  1mil3-2.swift
pi@RPi4B:~/swift-dev/examples $ timex ./main
t LEN:  999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal:  100000
43.64user 0.03system 0:43.69elapsed 99%CPU (0avgtext+0avgdata 12984maxresident)k
0inputs+0outputs (0major+2929minor)pagefaults 0swaps
pi@RPi4B:~/swift-dev/examples $

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 09, 2019, 10:15:37 PM
Try what I posted, making sure you build in "release" mode.  Default is "debug", which is slower.

[riveraa@mini ~/Projects/Swift/1mil3] $ /usr/bin/time .build/release/1mil3
r LEN:  999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal:  100000
        0.32 real         0.31 user         0.00 sys


/usr/bin/time is different on Mac.

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 09, 2019, 10:19:50 PM
I use swiftc to compile.

Your latest cut it in  half again.

Code: Text
  1. // Swift 5.1.2 - 1mil3-3.swift
  2.  
  3. var s = ""
  4. var t = ""
  5. var a = [Int](repeating: 0, count: 1000001)
  6.  
  7. for x in 1...1000000 {
  8.   let c = (x - 1) % 26
  9.   s.append(String(UnicodeScalar(UInt8(c + 65))))
  10.   a[x] = x
  11.   if c == 25 {
  12.     t.append(String(s.reversed()))
  13.     s = ""
  14.   }
  15. }
  16.  
  17. print("t LEN: ", t.count)
  18. print("Front: \(t.prefix(26))")
  19. print("Back:  \(t.suffix(26))")
  20. print("UBVal: ", a[100000])
  21.  


pi@RPi4B:~/swift-dev/examples $ swiftc  1mil3-3.swift
pi@RPi4B:~/swift-dev/examples $ timex ./main
t LEN:  999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal:  100000
24.09user 0.04system 0:24.19elapsed 99%CPU (0avgtext+0avgdata 12656maxresident)k
0inputs+0outputs (0major+1907minor)pagefaults 0swaps
pi@RPi4B:~/swift-dev/examples $

Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 10, 2019, 12:03:13 AM
Pascal was my first "REAL" language (via Delphi 6 on Windows a long time ago).
You seem to be using semicolons  more like C than Pascal... I personally have not programmed in Pascal after elementary school but have sometimes used Modula-2 or Component Pascal.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 10, 2019, 04:15:22 AM
I use swiftc to compile.

Right, which by default compiles with debugging enabled which of course will slow things down.

I did a test on my Mac, compiling using swiftc.  The first run with no optimization, the second with optimization:

[riveraa@mini ~/tmp/swift] $ time ./debug
r LEN:  999986
Front:  ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:   ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal:  100000

real    0m0.977s
user    0m0.961s
sys    0m0.011s

[riveraa@mini ~/tmp/swift] $ time ./release
r LEN:  999986
Front:  ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:   ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal:  100000

real    0m0.326s
user    0m0.313s
sys    0m0.009s


Optimized compile:  swiftc -O main.swift -o release

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 10, 2019, 06:32:53 AM
I timed following 8th code on ROCK64 (should be about the same as RPI4 speedwise):
Code: [Select]
1000000 constant LIMIT

a:new 0 a:push var, a
0 b:new true b:writable var, s
0 b:new true b:writable var, t


: iterate
  s @ "" 2 pick n:1- 26 n:mod 65 n:+ s:+ b:append
  b:len 26 n:< not if
    t @ swap b:append drop
    0 b:new true b:writable s !
  else
    drop
  then
  a:push ;

: app:main
  a @ ' iterate 1 LIMIT loop
  t @ b:rev >s s:len "r LEN: %d\n" s:strfmt .
  dup 26 s:lsub "Front: %s\n" s:strfmt .
  26 s:rsub "Back:  %s\n" s:strfmt .
  LIMIT a:@ nip "UBVal: %d\n" s:strfmt .
  bye ;

Result was:
Code: [Select]
root@DietPi:~/Downloads# time /opt/8th/bin/rpi64/8th r3.8th
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000

real 0m2,270s
user 0m2,160s
sys 0m0,100s
Memory usage was:
Code: [Select]
{"fault":0,"isrss":0,"rss":66452,"load15":0.30000,"ixrss":0,"load1":0.56000,"idrss":0,"swap":0,"load5":0.47000}

So, it's quite a lot faster than 40 seconds you have on the chart...
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 10, 2019, 09:08:21 AM
Nice, Jalih!

One thing I should point out:  I had installed DietPi on my Raspberry Pi 4 when I first got it, and my benchmarks were quite a bit slower than Raspbian installed on the same Pi, even when I overclocked it.

I didn't go too deep into determining why that was, in both cases I was running minimal installs instead of the full blown install, so it wasn't about additional resources being consumed by GUI processes since I don't use Linux like that (old school console/ssh access is all I need!  LOL).

AIR.



Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 10, 2019, 09:42:57 AM
One thing I should point out:  I had installed DietPi on my Raspberry Pi 4 when I first got it, and my benchmarks were quite a bit slower than Raspbian installed on the same Pi, even when I overclocked it.
I didn't test many distros, DietPi worked and was clean enough! Performance with 8th is actually a lot better in most tasks with ROCK64 than on my six core desktop PC running Windows! It seems Windows version of the 8th is the slowest version of all!     
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 10, 2019, 10:41:40 AM
Jalif,

I need a binary for your latest submission if you are ready to release your code.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 10, 2019, 11:51:10 AM
AIR,
I used -O with your last submission. Swift generates a main even if you use the -o option. There was about a second improvement over non-optimized.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 10, 2019, 11:55:21 AM
I'm hoping a FreeBasic fan sees this and submits an optimized version.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 10, 2019, 01:06:06 PM
Can we move this thread to the RaspberryBASIC forum? It isn't a blog and I'm wasting a lot of time being a messenger. I approved AIR's membership so he is free to post there. I'm sadden that @ejolson, heater, hippy and others didn't bother to join us. I miss the relationship.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 10, 2019, 01:35:06 PM
Ever since you approved me, this is what I get when logging in:

Quote from: FAIL
  An Error Has Occurred!    Your session timed out while posting.  Please go back and try again.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 10, 2019, 01:52:49 PM
Use the toolbar login method and it should save your cookie.

This seems to be happening with all the sites I host. Sorry!
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 10, 2019, 06:06:59 PM
John, what timing do you get with the following?

Code: Text
  1. // Swift 5.1.2 - 1mil3.swift
  2.  
  3. var s = ""
  4. var t = ""
  5. var a = [Int](repeating: 0, count: 1000001)
  6. var i = 0
  7.  
  8. for x in 1...1000000 {
  9.   let c = Character(UnicodeScalar(((x - 1) % 26)+65)!)
  10.   s.append(c)
  11.   i += 1
  12.   a[x] = x
  13.   if i == 26 {
  14.     t.append(String(s.reversed()))
  15.     s = ""
  16.     i = 0
  17.   }
  18. }
  19.  
  20. print("r LEN: ", t.count)
  21. print("Front:  \(t.prefix(26))")
  22. print("Back:   \(t.suffix(26))")
  23. print("UBVal: ", a[100000])
  24.  

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 10, 2019, 06:19:18 PM
No improvement.


pi@RPi4B:~/swift-dev/examples $ swiftc -O 1mil3-4.swift
pi@RPi4B:~/swift-dev/examples $ timex ./main
r LEN:  999986
Front:  ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:   ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal:  100000
23.33user 0.05system 0:23.51elapsed 99%CPU (0avgtext+0avgdata 12024maxresident)k
6368inputs+0outputs (25major+1877minor)pagefaults 0swaps
pi@RPi4B:~/swift-dev/examples $



You can download my Swift 5.1.2 RPi build here.
https://raspberrybasic.org/download/swift-5.1.2_armv7.tgz
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 10, 2019, 08:30:03 PM
The String object in Swift.org's RPI version of Swift is brain dead, on top of being slow.

I downloaded and installed the RPI deb from their site, tried a few things, but it reinforces the fact that I will never use Swift for any real code.  I'm about to uninstall it now.

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 10, 2019, 08:51:04 PM
My 5.1.2 of Swift was built from the latest Apple sources and native on the RPi 4B. The latest binary I was able to find for the RPi was 5.1.1 which has the compare bug I found.

I didn't see any RPi distributions on the swift.org site. Where did you get the .deb from and what version was it?

Title: Re: RaspberryBASIC.org Forum
Post by: John on December 10, 2019, 09:00:36 PM
I'm having pretty good luck with Nim on the RPi. Nimble makes it painless to install extensions. I have the following extensions installed and a quick test.

* IUP
* GMP
* SDL2 and GFX
* SQLite 3
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 11, 2019, 05:09:46 AM
I need a binary for your latest submission if you are ready to release your code.

I already gave link to 32-bit build earlier but you missed it. It's available  here (https://www.dropbox.com/s/pi8gfyx07r3s3c8/r3.zip?dl=0).

I use 64-bit version of 8th but currently build only packages 32-bit binary for arm. I asked about it on the 8th forum and developer fixed it for the next release. Most bug reports I have done have been fixed almost instantly!
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 11, 2019, 10:53:50 AM
pi@RPi4B:~/8th-dev/examples $ timex ./1mil3-2
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
2.09user 0.16system 0:02.28elapsed 99%CPU (0avgtext+0avgdata 53140maxresident)k
0inputs+0outputs (0major+12124minor)pagefaults 0swaps
pi@RPi4B:~/8th-dev/examples $


I thought Rust executables were huge. 8th takes the lead in this category.

-rwxr-xr-x 1 pi pi 7344807 Dec  9 21:02 1mil3-2
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 11, 2019, 11:07:09 AM
I thought Rust executables were huge. 8th takes the lead in this category.

That is to be expected! 8th currently always packages the full 8th into binary executable! Juce is used for providing graphics and sound functionality and can be used even for some programs not using GUI. Juce alone takes over 7 Megabytes! Also 8th currently always inits gui, even if it's not used. This is about to change for the next release and should lead to faster program startup times. I normally don't package programs into executables at all as it gives no speed increase compared to just running 8th with program source as commandline parameter...
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 17, 2019, 11:42:17 AM
This one is about second faster than my previous attempt on my ROCK64. I will post 64-bit binary, when the next version of 8th is released later this week:
Code: [Select]
1000000 constant LIMIT

a:new 0 a:push var, a
a:new var, s
0 b:new true b:writable var, t

: iterate
  s @ over n:1- 26 n:mod 65 n:+ a:push
  a:len 26 n:< not if
    b:new t @ swap b:append drop
    a:new s !
  else
    drop
  then
  a:push ;

: app:main
  a @ ' iterate 1 LIMIT loop
  t @ b:rev >s s:len "r LEN: %d\n" s:strfmt .
  dup 26 s:lsub "Front: %s\n" s:strfmt .
  26 s:rsub "Back:  %s\n" s:strfmt .
  LIMIT a:@ nip "UBVal: %d\n" s:strfmt .
  bye ;
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 17, 2019, 03:03:08 PM
AIR,

Can you run Jalih's latest on your Rasbian 32 RPi 4B? I'm only doing 64 bit on the RPi 4B going forward. If you can do the timex, I'll do the rest.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 17, 2019, 03:05:56 PM
Not without the binary...
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 17, 2019, 09:07:02 PM
Not without the binary...
You can find the 32-bit binary here (https://www.dropbox.com/s/swn6ywo99mfra2p/r3_2.zip?dl=0)

I will post the 64-bit binary later, when next version of 8th is released that writes 64-bit binaries. Program startup time should be then faster also...

The speed increase is due to that 8th can only append string or buffer into fully dynamic buffer. Previously I was converting characters to string before appending into buffer. Now, I push characters into dynamic array and convert the whole buffer to string before appending.

So, previously I had to do following for every appended character:
Code: [Select]
buffer "" ascii s:+ b:append

This challenge is a little bit unfair to 8th, as it needs to do number conversions when appending to buffer or if strings are used, a lot of copying...
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 17, 2019, 09:15:16 PM
Quote
This challenge is a little bit unfair to 8th, as it needs to do number conversions when appending to buffer or if strings are used, a lot of copying...

This is core functionality a language should perform well at.  Dynamic strings aren't new.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 17, 2019, 09:22:54 PM
Quote
This challenge is a little bit unfair to 8th, as it needs to do number conversions when appending to buffer or if strings are used, a lot of copying...

This is core functionality a language should perform well at.  Dynamic strings aren't new.
If language uses buffer of bytes to store string and strings are UTF-8 where each character can take 1 to 4 bytes, it's gonna be slower than just using ascii strings. Also mutable vs immutable makes a really big difference (using reference instead of allocating new string and copying old string every time).
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 18, 2019, 06:54:50 PM
Jalih,

I would focus on 64 bit for the RPi. It has been a long time coming. Prior to the 4B, our only option was a hobby OS and I'm done playing with toys.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 18, 2019, 07:18:28 PM
@John: Raspbian is not a hobby OS.  As someone who has built several dozen Linux systems from scratch (meaning 100% compiled from source) I have a great deal of admiration for the Raspbian team.  And really enjoyed using it (with no GUI).

@Jalih:  You make excellent points regarding strings, but 8th is not at a disadvantage here.  Just about EVERY programming language has the same issue with the default string implementation.  That's why StringBuilders came to be, but not every language has that (I'm looking at YOU, Python.  And for good measure, ScriptBasic).

A good StringBuilder just minimizes the amount of allocations required, AND doesn't simply do an allocation of space as needed and then a copy of the data (both are expensive time wise), but an actual move of the data into the reallocated (or newly allocated) buffer.

I said it before, the string challenge is a good opportunity for checking and optimizing how strings are put together, especially with either large data sets or with a large number of smaller strings being added sequentially to put together a final or master string.  I don't know about you, but I've enjoyed trying to get each language I've submitted to efficiently accomplish this.  And still have a few tricks up my sleeve that I haven't tried yet... ;D

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 18, 2019, 07:29:52 PM
Can you do the JADE C++ version for 64 bit? If your results match mine on other runs, I'll go with your timex results.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 18, 2019, 07:36:03 PM
I'm having issues getting IUP compiled on Ubuntu 64 for the RPi. Can't find glib 2.6 and the IUP make file keeps trying to use the OS type that requires-m64 which is invalid for 64 bit OS's.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 18, 2019, 07:50:23 PM
Can you do the JADE C++ version for 64 bit? If your results match mine on other runs, I'll go with your timex results.
riveraa@rpi:~/Projects/jade$ timex ./mil64
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.05user 0.01system 0:00.07elapsed 98%CPU (0avgtext+0avgdata 10136maxresident)k
0inputs+0outputs (0major+3069minor)pagefaults 0swaps


Title: Re: RaspberryBASIC.org Forum
Post by: John on December 19, 2019, 10:13:56 AM
I just read a thread on the RPi forum on how to make Rasbian run as a 64 bit OS. Seems to be having a lot of issues getting standard tools to run unlike the Ubuntu 64 solution.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 19, 2019, 11:59:48 AM
John, 64-bit 8th binary for string and array challenge is available here (https://www.dropbox.com/s/my09pjphml9fi61/r3_64.zip?dl=0)
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 19, 2019, 12:26:42 PM
Can you post the source as well?
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 19, 2019, 01:51:03 PM
AIR,

I've hit the wall trying to get IUP compiled from source on Ubuntu 64 RPi 4B. This is a critical tool for both Nim and embedded ScriptBasic efforts.

From what I can tell from the errors I'm getting, IUP make is having a problem determining the Linux platform, endian class and glib version..it's like if fell through its selection tree and trying to compile half baked.

Quote from: AIR@RB
Interestingly, the arch is "aarch64".

Can you take a look?
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 19, 2019, 04:12:43 PM
GO generating over a 2 meg executable seem excessive for a program this small.

8th still holds the crown at 8 megs.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 19, 2019, 04:17:54 PM
What I gained from these rounds of language comparisons is Nim, Swift and PHP is going to get a lot more of my attention.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 19, 2019, 05:40:12 PM
GO generating over a 2 meg executable seem excessive for a program this small.

8th still holds the crown at 8 megs.

Both include their runtimes, etc in the final executable.

Statically linking the C submission:

Code: C
  1. gcc -static mil.c $(pkg-config --libs --cflags glib-2.0) -lpthread -o mil64_s

Results in a binary that is 2.3MB in size.

For GO, try this:

Code: Go
  1. go build -ldflags="-s -w" mil64.go

On my raspi, I get a binary that is 1.4MB in size.

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 19, 2019, 06:06:55 PM
AIR,

I've hit the wall trying to get IUP compiled from source on Ubuntu 64 RPi 4B. This is a critical tool for both Nim and embedded ScriptBasic efforts.

From what I can tell from the errors I'm getting, IUP make is having a problem determining the Linux platform, endian class and glib version..it's like if fell through its selection tree and trying to compile half baked.

Quote from: AIR@RB
Interestingly, the arch is "aarch64".

Can you take a look?

Are you using 'tecmake' to regenerate the makefile?

tecmake functions essentially the same as "./configure" does.  If you look at the tecmake.mak file, you'll see:

Code: GNU make
  1.   ifneq ($(findstring aarch64, $(TEC_SYSARCH)), )
  2.     TEC_SYSARCH:=arm64
  3.   endif
  4.  

It will also set the proper endianness for you, but there is something you need to be aware of:
Code: GNU make
  1. ifeq ($(TEC_SYSARCH), arm64)
  2.       # Our dynamic library build is not working in arm64
  3.       NO_DYNAMIC ?= Yes
  4.       BUILD_64=Yes
  5.       TEC_UNAME:=$(TEC_UNAME)_arm64
  6. endif

Best guess is that only static libs will be built, if so your binaries will (ironically) be larger.

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 19, 2019, 06:19:09 PM
This is what I get when I try to make tecmake.mak.


ubuntu@rpi4b:~/iup-dev/lua53/src$ make -f tecmake.mak

Tecmake: starting [ lua53:Linux53_arm64 ]
if [ ! -d ../obj/Linux53_arm64 ] ; then mkdir -p ../obj/Linux53_arm64 ; fi
if [ ! -d ../lib/Linux53_arm64 ] ; then mkdir -p ../lib/Linux53_arm64 ; fi

Tecmake: compiling lapi.c ...
gcc -c -std=gnu99 -Wall -O2 -m64 -fPIC     -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -DTEC_UNAME=Linux53_arm64 -DTEC_SYSNAME=Linux -DLinux=5.3 -DTEC_LITTLEENDIAN -DTEC_64 -DFUNCPROTO=15 -DNDEBUG -o ../obj/Linux53_arm64/lapi.o lapi.c
gcc: error: unrecognized command line option ‘-m64’
make: *** [tecmake.mak:1701: ../obj/Linux53_arm64/lapi.o] Error 1
ubuntu@rpi4b:~/iup-dev/lua53/src$

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 19, 2019, 06:30:31 PM
You need to use TECMAKE (http://webserver2.tecgraf.puc-rio.br/tecmake/)
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 19, 2019, 06:52:12 PM
Can explain what you mean by use TECMAKE?
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 19, 2019, 06:52:49 PM
Is it configured for your system as the docs at that link specify?
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 19, 2019, 07:05:33 PM
I downloaded the TECMAKE zip and tried to use it and I get an error saying -f is missing.  I have spent hours on this and getting nowhere,

Can you try to build it on your end and send me a zip of the binaries.

I had no problems compiling this on Rasbain 32.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 19, 2019, 07:14:05 PM
NO, I don't do gui on my pi's...

I think the first issue is at around line 624 in the .mak file:

Code: GNU make
  1.     ifeq ($(TEC_SYSARCH), ia64)
  2.       STDFLAGS += -fPIC
  3.       X11_LIB := /usr/X11R6/lib
  4.     else
  5.       STDFLAGS += -m64 -fPIC
  6.       X11_LIB := /usr/X11R6/lib64
  7.     endif
  8.   else
  9.     X11_LIB := /usr/X11R6/lib
  10.   endif
  11.   X11_INC := /usr/X11R6/include
  12.   MOTIFGL_LIB :=
  13.   ifdef USE_OPENMP
  14.     STDFLAGS += -fopenmp
  15.     LIBS += gomp
  16.   endif
  17. endif
  18.  

There is no check for 'arm64' in that block, so it defaults to setting STDFLAGS to "-m64 -fpic" in line '5' above.

You can either add/fix that yourself, or file a bug report.

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 19, 2019, 07:19:19 PM
Removing the -m64 allowed me to compile Lua, IM. CD and IUP are still hosed. This is a major show stopper for me with Ubuntu 64 on the RPi.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 19, 2019, 07:23:22 PM
Simply removing that flag isn't the way to go.

You need to add a conditional statement to that block, and may need to check other sections as well.

Or create a new .mak file tailored to arm64 (not the best way to go about it, but if you're gonna take the brute-force approach, that's one way to do it while preserving the original .mak file so it's still portable).

If you want this bad enough, you'll find a way....


AIR.



Title: Re: RaspberryBASIC.org Forum
Post by: John on December 19, 2019, 08:12:45 PM
I'll shoot an e-mail off to Antonio and see if he can provide some guidance.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 20, 2019, 02:20:52 AM
Can you post the source as well?
It's the same source I posted earlier...
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 20, 2019, 02:39:36 AM
8th still holds the crown at 8 megs.
It's like I said to be expected! Full 8th functionality is bundled with binary. There is gui support, sound support, hardware support, network support, Bluetooth support, crypto support, database support and a lot more...

I can easily write all kinds of software without any 3rd party libraries. It's a big plus for me and normally I don't bother building executables, I just use 8th to run the source file.

Attached is a picture of the simple morphing program I wrote with 8th.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 20, 2019, 11:42:48 AM
Quote from: AIR
If you want this bad enough, you'll find a way....

The painful journey of being the first.

On a positive note, Eben Upton (lead RPi engineer) liked the concept of Ubuntu 64 on the RPi 4B. (Twitter conversation)
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 20, 2019, 08:44:50 PM
Can you do a Rust and Free Pascal timex if they are available for Ubuntu 64 on the RPi?
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 20, 2019, 10:08:13 PM
Quote from: AIR
If you want this bad enough, you'll find a way....

The painful journey of being the first.


Try the attached tecmake.mak file.  Place it in your IUP folder.  Then just run 'make -B'.

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 20, 2019, 10:19:47 PM
Freepascal 64bit:

riveraa@rpi:~/Projects/fpc/1mil3$ fpc -XX -CX -O3 mil64.pas
Free Pascal Compiler version 3.0.4+dfsg-22 [2019/01/24] for aarch64
Copyright (c) 1993-2017 by Florian Klaempfl and others
Target OS: Linux for AArch64
Compiling mil64.pas
Assembling mil
Linking mil64
31 lines compiled, 0.4 sec

riveraa@rpi:~/Projects/fpc/1mil3$ timex ./mil64
r len: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.15user 0.02system 0:00.17elapsed 98%CPU (0avgtext+0avgdata 5616maxresident)k
0inputs+0outputs (0major+1423minor)pagefaults 0swaps


AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 20, 2019, 10:34:14 PM
RUST 64bit:

riveraa@rpi:~/Projects/rust/1mil3$ rustc -O mil64.rs

riveraa@rpi:~/Projects/rust/1mil3$ timex ./mil64
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.02user 0.01system 0:00.04elapsed 100%CPU (0avgtext+0avgdata 10440maxresident)k
0inputs+0outputs (0major+2371minor)pagefaults 0swaps


AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 20, 2019, 10:53:23 PM
Thanks AIR!

Not without  a shit load of scary warnings along the way.

I used make -j 4 replacing the tecmake.mak in IM/CD/IUP with  yours.

Sucks this is static only.

The install and install_dev scripts need work for this platform. No ARM64 support.


Tecmake: Static Library (../lib/Linux53_arm64/libim.a) Done.
-rw-r--r-- 1 ubuntu ubuntu 2228190 Dec 20 22:28 libim.a
-rw-r--r-- 1 ubuntu ubuntu  317320 Dec 20 22:27 libim_fftw.a
-rw-r--r-- 1 ubuntu ubuntu  437912 Dec 20 22:26 libim_jp2.a
-rw-r--r-- 1 ubuntu ubuntu   12380 Dec 20 22:27 libim_lzo.a
-rw-r--r-- 1 ubuntu ubuntu  810614 Dec 20 22:27 libim_process.a
-rw-r--r-- 1 ubuntu ubuntu 1741958 Dec 20 22:28 libim_process_omp.a

Tecmake: Static Library (../lib/Linux53_arm64/libcd.a) Done.
-rw-r--r-- 1 ubuntu ubuntu 1284338 Dec 20 22:31 libcd.a
-rw-r--r-- 1 ubuntu ubuntu   50350 Dec 20 22:29 libcdpdf.a
-rw-r--r-- 1 ubuntu ubuntu 1923682 Dec 20 22:30 libpdflib.a

Tecmake: Static Library (../lib/Linux53_arm64/libiup.a) Done.
-rw-r--r-- 1 ubuntu ubuntu 2627956 Dec 20 22:34 libiup.a

gcc -std=gnu99 -o lua   lua.o liblua.a -lm -Wl,-E -ldl -lreadline
gcc -std=gnu99 -o luac   luac.o liblua.a -lm -Wl,-E -ldl -lreadline

ubuntu@rpi4b:~/iup-dev/lua53/src$ ./lua -i
Lua 5.3.5  Copyright (C) 1994-2018 Lua.org, PUC-Rio
>


I may try to do a Lua SALC Ubuntu 64 now that I have it working.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 21, 2019, 12:54:39 AM
I managed to compile dynamic arm64 libs.  Don't know if they work, but they're attached.

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 21, 2019, 01:12:11 AM
Wow!

That's great. What desktop did you install?

Can you share how you did it as I need to do the same for CD and IM.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 21, 2019, 01:36:02 AM
Seems to work.

Code: C
  1. #include <stdlib.h>
  2. #include <iup/iup.h>
  3.  
  4. int main(int argc, char **argv)
  5. {
  6.   IupOpen(&argc, &argv);
  7.  
  8.   IupMessage("Ubuntu 64 RPi 4B", "Hello world from IUP.");
  9.  
  10.   IupClose();
  11.   return EXIT_SUCCESS;
  12. }
  13.  
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 21, 2019, 02:53:20 PM
AIR,

Did you create a tecmake.mak that generates shared objects rather than static libraries? It would be great to have a set of dynamic and static IUP libries.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 21, 2019, 05:17:28 PM
I was curious how much the array part was consuming time and memory. A couple seconds faster but the eye opener is the memory use.


ubuntu@rpi4b:~/salc/sb-dev$ timex scriba 1mil4.sb
t LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
4.95user 0.31system 0:05.28elapsed 99%CPU (0avgtext+0avgdata 3924maxresident)k
424inputs+1960outputs (3major+883minor)pagefaults 0swaps
ubuntu@rpi4b:~/salc/sb-dev$

Title: Re: RaspberryBASIC.org Forum
Post by: John on December 21, 2019, 07:56:52 PM
Here is the tabs Nim IUP example using  the IUP shared objects you created and the Nim IUP interface. This is using the 1.1.1 version of Nim I built from source.

Code: Text
  1. # Example IUP program
  2.  
  3. # iupTabs: Creates a iupTabs control.
  4.  
  5. import iup
  6.  
  7. discard iup.open(nil, nil)
  8.  
  9. var vbox1 = iup.vbox(iup.label("Inside Tab A"), iup.button("Button A", ""), nil)
  10. var vbox2 = iup.vbox(iup.label("Inside Tab B"), iup.button("Button B", ""), nil)
  11.  
  12. iup.setAttribute(vbox1, "TABTITLE", "Tab A")
  13. iup.setAttribute(vbox2, "TABTITLE", "Tab B")
  14.  
  15. var tabs1 = iup.tabs(vbox1, vbox2, nil)
  16.  
  17. vbox1 = iup.vbox(iup.label("Inside Tab C"), iup.button("Button C", ""), nil)
  18. vbox2 = iup.vbox(iup.label("Inside Tab D"), iup.button("Button D", ""), nil)
  19.  
  20. iup.setAttribute(vbox1, "TABTITLE", "Tab C")
  21. iup.setAttribute(vbox2, "TABTITLE", "Tab D")
  22.  
  23. var tabs2 = iup.tabs(vbox1, vbox2, nil)
  24. iup.setAttribute(tabs2, "TABTYPE", "LEFT")
  25.  
  26. var box = iup.hbox(tabs1, tabs2, nil)
  27. iup.setAttribute(box, "MARGIN", "10x10")
  28. iup.setAttribute(box, "GAP", "10")
  29.  
  30. var dlg = iup.dialog(box)
  31. iup.setAttribute(dlg, "TITLE", "iupTabs")
  32. iup.setAttribute(dlg, "SIZE", "200x100")
  33.  
  34. discard showXY(dlg, IUP_CENTER, IUP_CENTER)
  35. discard mainLoop()
  36. close()
  37.  
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 21, 2019, 08:00:03 PM
AIR,

Did you create a tecmake.mak that generates shared objects rather than static libraries? It would be great to have a set of dynamic and static IUP libries.

IUP, as always, is a convoluted mess.


Why then wouldn't use pkg-config by default is beyond comprehension.

I switched shit to use pkg-config.


You need to build the following, in this order:

LUA (USE LUA53)
IM
CD
FTGL
IUP


IT'S IMPORTANT THAT YOU START FRESH, RE-DOWNLOAD THE LATEST VERSION OF EACH SOURCE PACKAGE TO BUILD.  I'M NOT TROUBLESHOOTING ANY OF THIS, ESPECIALLY WHEN YOU DON'T START CLEAN.


Use the attached Makefile-arm64 for building LUA.  The rest won't compile if you don't

Use the attached tecmake.mak file, overwriting the existing one in IM, CD, and IUP.

This will build both static and dynamic libraries.

To answer you earlier question, I didn't install a DM or a Window Manager.  I just installed the DEV libraries required to build the shit (and I mean shit).

Now to wipe my SDCARD since it now has a lot of flotsam I won't ever use....

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 21, 2019, 08:04:35 PM
Outstanding!

I'll try to maintain it from here. I  will start with fresh unziped downloaded IUP files.

Title: Re: RaspberryBASIC.org Forum
Post by: John on December 21, 2019, 09:25:11 PM
AIR,

I'm having a problem with CD.

Code: [Select]
ubuntu@rpi4b:~/iup-dev/cd/src$ make
Package webkit2gtk-4.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `webkit2gtk-4.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'webkit2gtk-4.0' found
Tecmake: Building Dependencies ... [ cd.dep ] (can be slow)
In file included from ./cairo/cdcairodbuf.c:7:
./cairo/cdcairoctx.h:20:47: error: missing binary operator before token "("
   20 | #define CAIRO_VERSION_110 CAIRO_VERSION_ENCODE(1, 10, 0)
      |                                               ^
./cairo/cdcairoctx.h:57:22: note: in expansion of macro ‘CAIRO_VERSION_110’
   57 | #if CAIRO_VERSION >= CAIRO_VERSION_110
      |                      ^~~~~~~~~~~~~~~~~
In file included from ./cairo/cdcairopdf.c:12:
./cairo/cdcairoctx.h:20:47: error: missing binary operator before token "("
   20 | #define CAIRO_VERSION_110 CAIRO_VERSION_ENCODE(1, 10, 0)
      |                                               ^
./cairo/cdcairoctx.h:57:22: note: in expansion of macro ‘CAIRO_VERSION_110’
   57 | #if CAIRO_VERSION >= CAIRO_VERSION_110
      |                      ^~~~~~~~~~~~~~~~~
In file included from ./cairo/cdcairosvg.c:13:
./cairo/cdcairoctx.h:20:47: error: missing binary operator before token "("
   20 | #define CAIRO_VERSION_110 CAIRO_VERSION_ENCODE(1, 10, 0)
      |                                               ^
./cairo/cdcairoctx.h:57:22: note: in expansion of macro ‘CAIRO_VERSION_110’
   57 | #if CAIRO_VERSION >= CAIRO_VERSION_110
      |                      ^~~~~~~~~~~~~~~~~
In file included from ./cairo/cdcairo.c:16:
./cairo/cdcairoctx.h:20:47: error: missing binary operator before token "("
   20 | #define CAIRO_VERSION_110 CAIRO_VERSION_ENCODE(1, 10, 0)
      |                                               ^
./cairo/cdcairoctx.h:57:22: note: in expansion of macro ‘CAIRO_VERSION_110’
   57 | #if CAIRO_VERSION >= CAIRO_VERSION_110
      |                      ^~~~~~~~~~~~~~~~~
./cairo/cdcairoctx.h:20:47: error: missing binary operator before token "("
   20 | #define CAIRO_VERSION_110 CAIRO_VERSION_ENCODE(1, 10, 0)
      |                                               ^
./cairo/cdcairo.c:118:22: note: in expansion of macro ‘CAIRO_VERSION_110’
  118 | #if CAIRO_VERSION >= CAIRO_VERSION_110
      |                      ^~~~~~~~~~~~~~~~~
./cairo/cdcairoctx.h:20:47: error: missing binary operator before token "("
   20 | #define CAIRO_VERSION_110 CAIRO_VERSION_ENCODE(1, 10, 0)
      |                                               ^
./cairo/cdcairo.c:852:22: note: in expansion of macro ‘CAIRO_VERSION_110’
  852 | #if CAIRO_VERSION >= CAIRO_VERSION_110
      |                      ^~~~~~~~~~~~~~~~~
./cairo/cdcairoctx.h:20:47: error: missing binary operator before token "("
   20 | #define CAIRO_VERSION_110 CAIRO_VERSION_ENCODE(1, 10, 0)
      |                                               ^
./cairo/cdcairo.c:1726:22: note: in expansion of macro ‘CAIRO_VERSION_110’
 1726 | #if CAIRO_VERSION >= CAIRO_VERSION_110
      |                      ^~~~~~~~~~~~~~~~~
./cairo/cdcairoctx.h:20:47: error: missing binary operator before token "("
   20 | #define CAIRO_VERSION_110 CAIRO_VERSION_ENCODE(1, 10, 0)
      |                                               ^
./cairo/cdcairo.c:1736:22: note: in expansion of macro ‘CAIRO_VERSION_110’
 1736 | #if CAIRO_VERSION >= CAIRO_VERSION_110
      |                      ^~~~~~~~~~~~~~~~~
./cairo/cdcairoctx.h:20:47: error: missing binary operator before token "("
   20 | #define CAIRO_VERSION_110 CAIRO_VERSION_ENCODE(1, 10, 0)
      |                                               ^
./cairo/cdcairo.c:1749:22: note: in expansion of macro ‘CAIRO_VERSION_110’
 1749 | #if CAIRO_VERSION >= CAIRO_VERSION_110
      |                      ^~~~~~~~~~~~~~~~~
./cairo/cdcairoctx.h:20:47: error: missing binary operator before token "("
   20 | #define CAIRO_VERSION_110 CAIRO_VERSION_ENCODE(1, 10, 0)
      |                                               ^
./cairo/cdcairo.c:1759:22: note: in expansion of macro ‘CAIRO_VERSION_110’
 1759 | #if CAIRO_VERSION >= CAIRO_VERSION_110
      |                      ^~~~~~~~~~~~~~~~~
In file included from ./cairo/cdcairoimg.c:9:
./cairo/cdcairoctx.h:20:47: error: missing binary operator before token "("
   20 | #define CAIRO_VERSION_110 CAIRO_VERSION_ENCODE(1, 10, 0)
      |                                               ^
./cairo/cdcairoctx.h:57:22: note: in expansion of macro ‘CAIRO_VERSION_110’
   57 | #if CAIRO_VERSION >= CAIRO_VERSION_110
      |                      ^~~~~~~~~~~~~~~~~
In file included from ./cairo/cdcairoirgb.c:13:
./cairo/cdcairoctx.h:20:47: error: missing binary operator before token "("
   20 | #define CAIRO_VERSION_110 CAIRO_VERSION_ENCODE(1, 10, 0)
      |                                               ^
./cairo/cdcairoctx.h:57:22: note: in expansion of macro ‘CAIRO_VERSION_110’
   57 | #if CAIRO_VERSION >= CAIRO_VERSION_110
      |                      ^~~~~~~~~~~~~~~~~
In file included from ./cairo/cdcairops.c:13:
./cairo/cdcairoctx.h:20:47: error: missing binary operator before token "("
   20 | #define CAIRO_VERSION_110 CAIRO_VERSION_ENCODE(1, 10, 0)
      |                                               ^
./cairo/cdcairoctx.h:57:22: note: in expansion of macro ‘CAIRO_VERSION_110’
   57 | #if CAIRO_VERSION >= CAIRO_VERSION_110
      |                      ^~~~~~~~~~~~~~~~~
In file included from ./cairo/cdcaironative_gdk.c:13:
./cairo/cdcairoctx.h:20:47: error: missing binary operator before token "("
   20 | #define CAIRO_VERSION_110 CAIRO_VERSION_ENCODE(1, 10, 0)
      |                                               ^
./cairo/cdcairoctx.h:57:22: note: in expansion of macro ‘CAIRO_VERSION_110’
   57 | #if CAIRO_VERSION >= CAIRO_VERSION_110
      |                      ^~~~~~~~~~~~~~~~~
./cairo/cdcaironative_gdk.c:28:22: error: missing binary operator before token "("
   28 | #if GTK_CHECK_VERSION(2, 22, 0)
      |                      ^
./cairo/cdcaironative_gdk.c:67:22: error: missing binary operator before token "("
   67 | #if GTK_CHECK_VERSION(3, 0, 0)
      |                      ^
./cairo/cdcaironative_gdk.c:82:22: error: missing binary operator before token "("
   82 | #if GTK_CHECK_VERSION(3, 0, 0) && !defined(GDK_NULL)
      |                      ^
./cairo/cdcaironative_gdk.c:132:23: error: missing binary operator before token "("
  132 | #if !GTK_CHECK_VERSION(3, 0, 0)
      |                       ^
./cairo/cdcaironative_gdk.c:137:22: error: missing binary operator before token "("
  137 | #if GTK_CHECK_VERSION(3, 0, 0)
      |                      ^
./cairo/cdcaironative_gdk.c:147:23: error: missing binary operator before token "("
  147 | #if !GTK_CHECK_VERSION(3, 0, 0)  /* always recreate in GTK3 */
      |                       ^
./cairo/cdcaironative_gdk.c:181:22: error: missing binary operator before token "("
  181 | #if GTK_CHECK_VERSION(3, 0, 0)
      |                      ^
./cairo/cdcaironative_gdk.c:188:22: error: missing binary operator before token "("
  188 | #if GTK_CHECK_VERSION(3, 0, 0)
      |                      ^
./cairo/cdcairoprn_unix.c:12:22: error: missing binary operator before token "("
   12 | #if GTK_CHECK_VERSION(3, 0, 0)
      |                      ^
./cairo/cdcairoprn_unix.c:14:24: error: missing binary operator before token "("
   14 | #elif GTK_CHECK_VERSION(2, 10, 0)
      |                        ^
In file included from ./cairo/cdcairoprn_unix.c:19:
./cairo/cdcairoctx.h:20:47: error: missing binary operator before token "("
   20 | #define CAIRO_VERSION_110 CAIRO_VERSION_ENCODE(1, 10, 0)
      |                                               ^
./cairo/cdcairoctx.h:57:22: note: in expansion of macro ‘CAIRO_VERSION_110’
   57 | #if CAIRO_VERSION >= CAIRO_VERSION_110
      |                      ^~~~~~~~~~~~~~~~~
./cairo/cdcairoprn_unix.c:22:22: error: missing binary operator before token "("
   22 | #if GTK_CHECK_VERSION(2, 10, 0)
      |                      ^

Tecmake: starting [ cd:Linux53_arm64 ]
if [ ! -d ../obj/Linux53_arm64 ] ; then mkdir -p ../obj/Linux53_arm64 ; fi
if [ ! -d ../lib/Linux53_arm64 ] ; then mkdir -p ../lib/Linux53_arm64 ; fi
Package webkit2gtk-4.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `webkit2gtk-4.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'webkit2gtk-4.0' found

Tecmake: compiling cd.c ...
gcc -c  -Wall -O2 -fPIC -I. -Idrv -Ix11 -Iwin32 -Iintcgm -Isim -Icairo -Isvg -I../include -I../../lua53/include -I/usr -I/include/gtk-3.0/unix-print -I/usr/include/freetype2   -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGSEAL_ENABLE -DUSE_GTK3 -DTEC_UNAME=Linux53_arm64 -DTEC_SYSNAME=Linux -DLinux=5.3 -DTEC_LITTLEENDIAN -DTEC_64 -DFUNCPROTO=15 -DNDEBUG -o ../obj/Linux53_arm64/cd.o cd.c
Package webkit2gtk-4.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `webkit2gtk-4.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'webkit2gtk-4.0' found

Tecmake: compiling wd.c ...
gcc -c  -Wall -O2 -fPIC -I. -Idrv -Ix11 -Iwin32 -Iintcgm -Isim -Icairo -Isvg -I../include -I../../lua53/include -I/usr -I/include/gtk-3.0/unix-print -I/usr/include/freetype2   -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGSEAL_ENABLE -DUSE_GTK3 -DTEC_UNAME=Linux53_arm64 -DTEC_SYSNAME=Linux -DLinux=5.3 -DTEC_LITTLEENDIAN -DTEC_64 -DFUNCPROTO=15 -DNDEBUG -o ../obj/Linux53_arm64/wd.o wd.c
Package webkit2gtk-4.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `webkit2gtk-4.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'webkit2gtk-4.0' found

Tecmake: compiling wdhdcpy.c ...
gcc -c  -Wall -O2 -fPIC -I. -Idrv -Ix11 -Iwin32 -Iintcgm -Isim -Icairo -Isvg -I../include -I../../lua53/include -I/usr -I/include/gtk-3.0/unix-print -I/usr/include/freetype2   -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGSEAL_ENABLE -DUSE_GTK3 -DTEC_UNAME=Linux53_arm64 -DTEC_SYSNAME=Linux -DLinux=5.3 -DTEC_LITTLEENDIAN -DTEC_64 -DFUNCPROTO=15 -DNDEBUG -o ../obj/Linux53_arm64/wdhdcpy.o wdhdcpy.c
Package webkit2gtk-4.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `webkit2gtk-4.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'webkit2gtk-4.0' found

Tecmake: compiling rgb2map.c ...
gcc -c  -Wall -O2 -fPIC -I. -Idrv -Ix11 -Iwin32 -Iintcgm -Isim -Icairo -Isvg -I../include -I../../lua53/include -I/usr -I/include/gtk-3.0/unix-print -I/usr/include/freetype2   -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGSEAL_ENABLE -DUSE_GTK3 -DTEC_UNAME=Linux53_arm64 -DTEC_SYSNAME=Linux -DLinux=5.3 -DTEC_LITTLEENDIAN -DTEC_64 -DFUNCPROTO=15 -DNDEBUG -o ../obj/Linux53_arm64/rgb2map.o rgb2map.c
Package webkit2gtk-4.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `webkit2gtk-4.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'webkit2gtk-4.0' found

Tecmake: compiling cd_vectortext.c ...
gcc -c  -Wall -O2 -fPIC -I. -Idrv -Ix11 -Iwin32 -Iintcgm -Isim -Icairo -Isvg -I../include -I../../lua53/include -I/usr -I/include/gtk-3.0/unix-print -I/usr/include/freetype2   -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGSEAL_ENABLE -DUSE_GTK3 -DTEC_UNAME=Linux53_arm64 -DTEC_SYSNAME=Linux -DLinux=5.3 -DTEC_LITTLEENDIAN -DTEC_64 -DFUNCPROTO=15 -DNDEBUG -o ../obj/Linux53_arm64/cd_vectortext.o cd_vectortext.c
Package webkit2gtk-4.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `webkit2gtk-4.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'webkit2gtk-4.0' found

Tecmake: compiling cd_active.c ...
gcc -c  -Wall -O2 -fPIC -I. -Idrv -Ix11 -Iwin32 -Iintcgm -Isim -Icairo -Isvg -I../include -I../../lua53/include -I/usr -I/include/gtk-3.0/unix-print -I/usr/include/freetype2   -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGSEAL_ENABLE -DUSE_GTK3 -DTEC_UNAME=Linux53_arm64 -DTEC_SYSNAME=Linux -DLinux=5.3 -DTEC_LITTLEENDIAN -DTEC_64 -DFUNCPROTO=15 -DNDEBUG -o ../obj/Linux53_arm64/cd_active.o cd_active.c
Package webkit2gtk-4.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `webkit2gtk-4.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'webkit2gtk-4.0' found

Tecmake: compiling cd_attributes.c ...
gcc -c  -Wall -O2 -fPIC -I. -Idrv -Ix11 -Iwin32 -Iintcgm -Isim -Icairo -Isvg -I../include -I../../lua53/include -I/usr -I/include/gtk-3.0/unix-print -I/usr/include/freetype2   -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGSEAL_ENABLE -DUSE_GTK3 -DTEC_UNAME=Linux53_arm64 -DTEC_SYSNAME=Linux -DLinux=5.3 -DTEC_LITTLEENDIAN -DTEC_64 -DFUNCPROTO=15 -DNDEBUG -o ../obj/Linux53_arm64/cd_attributes.o cd_attributes.c
Package webkit2gtk-4.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `webkit2gtk-4.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'webkit2gtk-4.0' found

Tecmake: compiling cd_bitmap.c ...
gcc -c  -Wall -O2 -fPIC -I. -Idrv -Ix11 -Iwin32 -Iintcgm -Isim -Icairo -Isvg -I../include -I../../lua53/include -I/usr -I/include/gtk-3.0/unix-print -I/usr/include/freetype2   -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGSEAL_ENABLE -DUSE_GTK3 -DTEC_UNAME=Linux53_arm64 -DTEC_SYSNAME=Linux -DLinux=5.3 -DTEC_LITTLEENDIAN -DTEC_64 -DFUNCPROTO=15 -DNDEBUG -o ../obj/Linux53_arm64/cd_bitmap.o cd_bitmap.c
Package webkit2gtk-4.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `webkit2gtk-4.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'webkit2gtk-4.0' found

Tecmake: compiling cd_image.c ...
gcc -c  -Wall -O2 -fPIC -I. -Idrv -Ix11 -Iwin32 -Iintcgm -Isim -Icairo -Isvg -I../include -I../../lua53/include -I/usr -I/include/gtk-3.0/unix-print -I/usr/include/freetype2   -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGSEAL_ENABLE -DUSE_GTK3 -DTEC_UNAME=Linux53_arm64 -DTEC_SYSNAME=Linux -DLinux=5.3 -DTEC_LITTLEENDIAN -DTEC_64 -DFUNCPROTO=15 -DNDEBUG -o ../obj/Linux53_arm64/cd_image.o cd_image.c
Package webkit2gtk-4.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `webkit2gtk-4.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'webkit2gtk-4.0' found

Tecmake: compiling cd_primitives.c ...
gcc -c  -Wall -O2 -fPIC -I. -Idrv -Ix11 -Iwin32 -Iintcgm -Isim -Icairo -Isvg -I../include -I../../lua53/include -I/usr -I/include/gtk-3.0/unix-print -I/usr/include/freetype2   -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGSEAL_ENABLE -DUSE_GTK3 -DTEC_UNAME=Linux53_arm64 -DTEC_SYSNAME=Linux -DLinux=5.3 -DTEC_LITTLEENDIAN -DTEC_64 -DFUNCPROTO=15 -DNDEBUG -o ../obj/Linux53_arm64/cd_primitives.o cd_primitives.c
Package webkit2gtk-4.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `webkit2gtk-4.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'webkit2gtk-4.0' found

Tecmake: compiling cd_text.c ...
gcc -c  -Wall -O2 -fPIC -I. -Idrv -Ix11 -Iwin32 -Iintcgm -Isim -Icairo -Isvg -I../include -I../../lua53/include -I/usr -I/include/gtk-3.0/unix-print -I/usr/include/freetype2   -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGSEAL_ENABLE -DUSE_GTK3 -DTEC_UNAME=Linux53_arm64 -DTEC_SYSNAME=Linux -DLinux=5.3 -DTEC_LITTLEENDIAN -DTEC_64 -DFUNCPROTO=15 -DNDEBUG -o ../obj/Linux53_arm64/cd_text.o cd_text.c
cd_text.c: In function ‘cdCanvasNativeFont’:
cd_text.c:310:30: warning: ‘%s’ directive writing up to 199 bytes into a region of size between 0 and 1023 [-Wformat-overflow=]
  310 |     sprintf(native_font, "%s,%s %d", canvas->font_type_face, style, canvas->font_size);
      |                              ^~                              ~~~~~
In file included from /usr/include/stdio.h:867,
                 from cd_text.c:8:
/usr/include/aarch64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 4 and 1236 bytes into a destination of size 1024
   36 |   return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   37 |       __bos (__s), __fmt, __va_arg_pack ());
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Package webkit2gtk-4.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `webkit2gtk-4.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'webkit2gtk-4.0' found

Tecmake: compiling cd_util.c ...
gcc -c  -Wall -O2 -fPIC -I. -Idrv -Ix11 -Iwin32 -Iintcgm -Isim -Icairo -Isvg -I../include -I../../lua53/include -I/usr -I/include/gtk-3.0/unix-print -I/usr/include/freetype2   -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGSEAL_ENABLE -DUSE_GTK3 -DTEC_UNAME=Linux53_arm64 -DTEC_SYSNAME=Linux -DLinux=5.3 -DTEC_LITTLEENDIAN -DTEC_64 -DFUNCPROTO=15 -DNDEBUG -o ../obj/Linux53_arm64/cd_util.o cd_util.c
cd_util.c:1081:10: fatal error: glib.h: No such file or directory
 1081 | #include <glib.h>
      |          ^~~~~~~~
compilation terminated.
make[1]: *** [../tecmake.mak:1713: ../obj/Linux53_arm64/cd_util.o] Error 1
make: *** [Makefile:14: cd] Error 2
ubuntu@rpi4b:~/iup-dev/cd/src$

Same problem with IUP.


Tecmake: compiling iup_thread.c ...
gcc -c  -Wall -O2 -fPIC -I../include -I. -Igtk -I../../lua53/include -I/usr/X11R6/include   -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGSEAL_ENABLE -DTEC_UNAME=Linux53_arm64 -DTEC_SYSNAME=Linux -DLinux=5.3 -DTEC_LITTLEENDIAN -DTEC_64 -DFUNCPROTO=15 -DNDEBUG -o ../obj/Linux53_arm64/iup_thread.o iup_thread.c
iup_thread.c:15:10: fatal error: glib.h: No such file or directory
   15 | #include <glib.h>
      |          ^~~~~~~~
compilation terminated.
make[1]: *** [../tecmake.mak:1713: ../obj/Linux53_arm64/iup_thread.o] Error 1
make: *** [Makefile:12: iup] Error 2
ubuntu@rpi4b:~/iup-dev/iup/src$

Title: Re: RaspberryBASIC.org Forum
Post by: John on December 21, 2019, 10:40:23 PM
I was  able to get things to compile with the following change to tecmake.mak.


Line 1413

WAS:
        STDINCS += $(GTK)/lib/glib-2.0/include

Now:
        STDINCS += $(GTK)/lib/glib-2.0


Tecmake: Dynamic Library (../lib/Linux53_arm64/Lua53/libimlua_fftw53.so) Done.

Tecmake: Dynamic Library (../lib/Linux53_arm64/Lua53/libcdluaim53.so) Done.

Tecmake: Dynamic Library (../lib/Linux53_arm64/libftgl.so) Done.

Tecmake: Dynamic Library (../lib/Linux53_arm64/libiup.so) Done.

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 21, 2019, 11:21:31 PM
If you are modifying STDINCS to get things to compile, then your development environment is not properly set up to use pkg-config and tecmake.
You also don't have the webkitgtk-4.0 development package installed.
It works on my pi, with a freshly installed OS, so I don't have all the potential conflicts you might have (this has happened before with your building stuff).  For example, installing previous builds into the system, and not removing them prior to a new build.  Recipe for trouble, as you've repeatedly experienced.


One thing you have to be VERY careful about is, when you have an issue building and you make a change, once you get it to finish compiling you need to compile again with the -B switch passed to make.  And don't use -j4 because that will continue compiling even if there are errors since it's spawning multiple threads (4 in this case) so if one fails, the others continue, making you think the compile was 100% successful.

Only use -j4 once a full rebuild is successful.

Regarding, libcd.so, that builds fine on my ready-to-be-nuked test system, are you sure you're looking in the right place?  I have the one you mentioned, but in the Lua53 sub-folder, which is correct.

ONE MORE THING:  For my final build, I nuked both the lib and obj folders from all of the components that had them.  Then I built the components in the order I posted previously, and other than a plethora of warnings (then really need to update their code) everything compiled successfully.

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 21, 2019, 11:46:04 PM
I installed the webkit before recompiling. Can't say why my default glib-dev doesn't use an include. Everything seemed to build fine with a lot less warnings this time. I didn't use the -j 4 and only make.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 22, 2019, 12:03:05 AM
My next concern is the Nim IUP interface is a complete. h  compatible match and not IUP Lite.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 22, 2019, 10:00:29 AM
Thanks AIR for the Lua contribution!
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 22, 2019, 12:51:49 PM
As an old OS/2 user, here is obligatory REXX version:

Code: [Select]
s = ''
t = ''

do i = 0 to 1000000
  a.i = i
  s = s || d2c(i // 26 + 65)
  if length(s) >= 26 then
    do
      t = t || s
      s = ''
    end
end

r = reverse(t)
say 'r LEN: ' || length(r)
say 'Front: ' || left(r, 26)
say 'Back:  ' || right(r, 26)
say 'UBVal: ' || a.1000000
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 22, 2019, 01:21:24 PM
Does REXX run on the RPi?

It's one of the challenge primary rules.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 22, 2019, 02:10:48 PM
Does REXX run on the RPi?

It's one of the challenge primary rules.

Regina REXX should be available and probably some others can be build also.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 22, 2019, 02:36:04 PM
We need to get more than AIR and I onboard with Ubuntu 64 on the RPi.

Title: Re: RaspberryBASIC.org Forum
Post by: John on December 22, 2019, 03:05:21 PM
AIR,

I just recieved an e-mail from Antonio and he will incorporate your changes for ARM64.

It's interesting that Ubuntu is classifying this as an IoT product.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 22, 2019, 06:47:42 PM
The Nim IUP extension seems to only cover the IUP part of the library set and CD / IM are missing. At lease I have a model to work with to add the others.

Title: Re: RaspberryBASIC.org Forum
Post by: John on December 23, 2019, 07:02:04 AM
AIR,

I think the way to go with the SBT extension module I'm converting to a generic embeddable ScriptBasic interface is pass and return pData structures. This is all well and fine for C as the host but Nim is my target. Do you think Nim can handle working with this structure?
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 23, 2019, 01:01:45 PM
The Nim IUP extension seems to only cover the IUP part of the library set and CD / IM are missing. At lease I have a model to work with to add the others.

NIUP includes the procs for IUP, CD and IM, don't use the plain IUP nimble package if you need CD and IM...

nimble install niup, then import niup

https://github.com/dariolah/niup (https://github.com/dariolah/niup)

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 23, 2019, 01:14:48 PM
I couldn't get it to work but I'll give niup another try now that the iup version works.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 24, 2019, 12:12:54 AM
This is the problem I ran into last time with niup.

Code: Text
  1. import niup
  2. import niupext
  3.  
  4. proc btn_exit_cb(ih:PIhandle):cint {.cdecl.}=
  5.   # Exits the main loop
  6.   return IUP_CLOSE
  7.  
  8. proc mainProc =
  9.   var dlg, button, label, vbox: PIhandle
  10.  
  11.   Open()
  12.  
  13.   label =  Label("Hello world from IUP.")
  14.   button = Button("OK", nil)
  15.  
  16.   vbox = Vbox(label, button, nil)
  17.   withPIhandle vbox:
  18.     "ALIGNMENT" "ACENTER"
  19.     "GAP"       "10"
  20.     "MARGIN"    "10x10"
  21.  
  22.   dlg = Dialog(vbox)
  23.   SetAttribute(dlg, "TITLE", "Hello World with callback")
  24.  
  25.   # Registers callbacks
  26.   SetCallback(button, "ACTION", btn_exit_cb)
  27.  
  28.   ShowXY(dlg, IUP_CENTER, IUP_CENTER)
  29.  
  30.   MainLoop()
  31.  
  32.   Close()
  33.  
  34. if isMainModule:
  35.   mainProc()
  36.  


ubuntu@rpi4b:~/repo/Nim/examples/niup-dev$ nim c -d:release hello_iup.nim
Hint: used config file '/home/ubuntu/repo/Nim/config/nim.cfg' [Conf]
Hint: used config file '/home/ubuntu/repo/Nim/config/config.nims' [Conf]
Hint: system [Processing]
Hint: widestrs [Processing]
Hint: io [Processing]
Hint: hello_iup [Processing]
Hint: niup [Processing]
fatal.nim(39)            sysFatal
Error: unhandled exception: 'ident' is not accessible using discriminant 'kind' of type 'TNode' [FieldError]
ubuntu@rpi4b:~/repo/Nim/examples/niup-dev$

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 24, 2019, 08:07:15 AM
Best guess is the use of 'Close()' in the code.

What happens if you change it to 'niup.Close()' ?

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 24, 2019, 10:47:59 AM
The example I used was from the niup site. One would think it should work.

Check out RB as I posted a more direct approach which sort of like DECLARE in ScriptBasic.

My Nim in Action book arrived today.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 24, 2019, 02:13:30 PM
There is something going wrong in the initialization of niup.

Code: Text
  1. import niup
  2.  
  3. echo "Got Here!"
  4.  


ubuntu@rpi4b:~/repo/Nim/examples$ nim c -d:release testniup.nim
Hint: used config file '/home/ubuntu/repo/Nim/config/nim.cfg' [Conf]
Hint: used config file '/home/ubuntu/repo/Nim/config/config.nims' [Conf]
Hint: system [Processing]
Hint: widestrs [Processing]
Hint: io [Processing]
Hint: testniup [Processing]
Hint: niup [Processing]
fatal.nim(39)            sysFatal
Error: unhandled exception: 'ident' is not accessible using discriminant 'kind' of type 'TNode' [FieldError]
ubuntu@rpi4b:~/repo/Nim/examples$

Title: Re: RaspberryBASIC.org Forum
Post by: John on December 24, 2019, 02:48:29 PM
I was able to include most of the IUP section of the niup interface file and got it to work. Who knows when this interface was done and is  it compatible with the current release of IUP?

iup.nim (my test include)
Code: Text
  1. #Lib IUP
  2.  
  3. const
  4.   IUP_NAME* = "IUP - Portable User Interface"
  5.   IUP_DESCRIPTION* = "Multi-platform Toolkit for Building Graphical User Interfaces"
  6.   IUP_COPYRIGHT* = "Copyright (C) 1994-2019 Tecgraf/PUC-Rio"
  7.  
  8.   libiupSONAME = "libiup.so"
  9.   libiupcdSONAME = "libiupcd.so"
  10.   libcdSONAME = "libcd.so"
  11.   libiupcontrolsSONAME = "libiupcontrols.so"
  12.   libiupglcontrolsSONAME = "libiupglcontrols.so"
  13.   libiupglSONAME = "libiupgl.so"
  14.   libiupimglibSONAME = "libiupimglib.so"
  15.   libiupimSONAME = "libiupim.so"
  16.   libiup_mglplotSONAME = "libiup_mglplot.so"
  17.   libiup_plotSONAME = "libiup_plot.so"
  18.   libiup_scintillaSONAME = "libiup_scintilla.so"
  19.   libiuptuioSONAME = "libiuptuio.so"
  20.   libiupwebSONAME = "libiupweb.so"
  21.  
  22.  
  23.   IUP_ERROR* = 1
  24.   IUP_NOERROR* = 0
  25.   IUP_OPENED* = -1
  26.   IUP_INVALID* = -1
  27.   IUP_INVALID_ID* = -10
  28.   IUP_IGNORE* = -1
  29.   IUP_DEFAULT* = -2
  30.   IUP_CLOSE* = -3
  31.   IUP_CONTINUE* = -4
  32.   IUP_CENTER* = cint(0x0000FFFF)
  33.   IUP_LEFT* = cint(0x0000FFFE)
  34.   IUP_RIGHT* = cint(0x0000FFFD)
  35.   IUP_MOUSEPOS* = cint(0x0000FFFC)
  36.   IUP_CURRENT* = cint(0x0000FFFB)
  37.   IUP_CENTERPARENT* = cint(0x0000FFFA)
  38.   IUP_TOP* = IUP_LEFT
  39.   IUP_BOTTOM* = IUP_RIGHT
  40.  
  41.  
  42. type
  43.   Ihandle = object
  44.   PIhandle* = ptr Ihandle
  45.  
  46.   uptr_t = clong
  47.   sptr_t = clong
  48.   Icallback* = proc (a1: PIhandle): cint {.cdecl.}
  49.  
  50. proc Open*(argc: var cint; argv: ptr cstringArray): cint {.cdecl, importc: "IupOpen", dynlib: libiupSONAME, discardable.}
  51. proc Close*() {.cdecl, importc: "IupClose", dynlib: libiupSONAME.}
  52. proc IsOpened*(): cint {.cdecl, importc: "IupIsOpened", dynlib: libiupSONAME, discardable.}
  53. proc ImageLibOpen*() {.cdecl, importc: "IupImageLibOpen", dynlib: libiupimglibSONAME.}
  54. proc MainLoop*(): cint {.cdecl, importc: "IupMainLoop", dynlib: libiupSONAME, discardable.}
  55. proc LoopStep*(): cint {.cdecl, importc: "IupLoopStep", dynlib: libiupSONAME, discardable.}
  56. proc LoopStepWait*(): cint {.cdecl, importc: "IupLoopStepWait", dynlib: libiupSONAME, discardable.}
  57. proc MainLoopLevel*(): cint {.cdecl, importc: "IupMainLoopLevel", dynlib: libiupSONAME, discardable.}
  58. proc Flush*() {.cdecl, importc: "IupFlush", dynlib: libiupSONAME.}
  59. proc ExitLoop*() {.cdecl, importc: "IupExitLoop", dynlib: libiupSONAME.}
  60. proc PostMessage*(ih: PIhandle; s: cstring; i: cint; d: cdouble; p: pointer) {.cdecl, importc: "IupPostMessage", dynlib: libiupSONAME.}
  61. proc RecordInput*(filename: cstring; mode: cint): cint {.cdecl, importc: "IupRecordInput", dynlib: libiupSONAME, discardable.}
  62. proc PlayInput*(filename: cstring): cint {.cdecl, importc: "IupPlayInput", dynlib: libiupSONAME, discardable.}
  63. proc Update*(ih: PIhandle) {.cdecl, importc: "IupUpdate", dynlib: libiupSONAME.}
  64. proc UpdateChildren*(ih: PIhandle) {.cdecl, importc: "IupUpdateChildren", dynlib: libiupSONAME.}
  65. proc Redraw*(ih: PIhandle; children: cint) {.cdecl, importc: "IupRedraw", dynlib: libiupSONAME.}
  66. proc Refresh*(ih: PIhandle) {.cdecl, importc: "IupRefresh", dynlib: libiupSONAME.}
  67. proc RefreshChildren*(ih: PIhandle) {.cdecl, importc: "IupRefreshChildren", dynlib: libiupSONAME.}
  68. proc Execute*(filename: cstring; parameters: cstring): cint {.cdecl, importc: "IupExecute", dynlib: libiupSONAME, discardable.}
  69. proc ExecuteWait*(filename: cstring; parameters: cstring): cint {.cdecl, importc: "IupExecuteWait", dynlib: libiupSONAME, discardable.}
  70. proc Help*(url: cstring): cint {.cdecl, importc: "IupHelp", dynlib: libiupSONAME, discardable.}
  71. proc Log*(`type`: cstring; format: cstring) {.varargs, cdecl, importc: "IupLog", dynlib: libiupSONAME.}
  72. proc Load*(filename: cstring): cstring {.cdecl, importc: "IupLoad", dynlib: libiupSONAME.}
  73. proc LoadBuffer*(buffer: cstring): cstring {.cdecl, importc: "IupLoadBuffer", dynlib: libiupSONAME.}
  74. proc Version*(): cstring {.cdecl, importc: "IupVersion", dynlib: libiupSONAME.}
  75. proc VersionDate*(): cstring {.cdecl, importc: "IupVersionDate", dynlib: libiupSONAME.}
  76. proc VersionNumber*(): cint {.cdecl, importc: "IupVersionNumber", dynlib: libiupSONAME, discardable.}
  77. proc VersionShow*() {.cdecl, importc: "IupVersionShow", dynlib: libiupSONAME.}
  78. proc SetLanguage*(lng: cstring) {.cdecl, importc: "IupSetLanguage", dynlib: libiupSONAME.}
  79. proc GetLanguage*(): cstring {.cdecl, importc: "IupGetLanguage", dynlib: libiupSONAME.}
  80. proc SetLanguageString*(name: cstring; str: cstring) {.cdecl, importc: "IupSetLanguageString", dynlib: libiupSONAME.}
  81. proc StoreLanguageString*(name: cstring; str: cstring) {.cdecl, importc: "IupStoreLanguageString", dynlib: libiupSONAME.}
  82. proc GetLanguageString*(name: cstring): cstring {.cdecl, importc: "IupGetLanguageString", dynlib: libiupSONAME.}
  83. proc SetLanguagePack*(ih: PIhandle) {.cdecl, importc: "IupSetLanguagePack", dynlib: libiupSONAME.}
  84. proc Destroy*(ih: PIhandle) {.cdecl, importc: "IupDestroy", dynlib: libiupSONAME.}
  85. proc Detach*(child: PIhandle) {.cdecl, importc: "IupDetach", dynlib: libiupSONAME.}
  86. proc Append*(ih: PIhandle; child: PIhandle): PIhandle {.cdecl, importc: "IupAppend", dynlib: libiupSONAME.}
  87. proc Insert*(ih: PIhandle; ref_child: PIhandle; child: PIhandle): PIhandle {. cdecl, importc: "IupInsert", dynlib: libiupSONAME.}
  88. proc GetChild*(ih: PIhandle; pos: cint): PIhandle {.cdecl, importc: "IupGetChild", dynlib: libiupSONAME.}
  89. proc GetChildPos*(ih: PIhandle; child: PIhandle): cint {.cdecl, importc: "IupGetChildPos", dynlib: libiupSONAME, discardable.}
  90. proc GetChildCount*(ih: PIhandle): cint {.cdecl, importc: "IupGetChildCount", dynlib: libiupSONAME, discardable.}
  91. proc GetNextChild*(ih: PIhandle; child: PIhandle): PIhandle {.cdecl, importc: "IupGetNextChild", dynlib: libiupSONAME.}
  92. proc GetBrother*(ih: PIhandle): PIhandle {.cdecl, importc: "IupGetBrother", dynlib: libiupSONAME.}
  93. proc GetParent*(ih: PIhandle): PIhandle {.cdecl, importc: "IupGetParent", dynlib: libiupSONAME.}
  94. proc GetDialog*(ih: PIhandle): PIhandle {.cdecl, importc: "IupGetDialog", dynlib: libiupSONAME.}
  95. proc GetDialogChild*(ih: PIhandle; name: cstring): PIhandle {.cdecl, importc: "IupGetDialogChild", dynlib: libiupSONAME.}
  96. proc Reparent*(ih: PIhandle; new_parent: PIhandle; ref_child: PIhandle): cint {. cdecl, importc: "IupReparent", dynlib: libiupSONAME, discardable.}
  97. proc Popup*(ih: PIhandle; x: cint; y: cint): cint {.cdecl, importc: "IupPopup", dynlib: libiupSONAME, discardable.}
  98. proc Show*(ih: PIhandle): cint {.cdecl, importc: "IupShow", dynlib: libiupSONAME, discardable.}
  99. proc ShowXY*(ih: PIhandle; x: cint; y: cint): cint {.cdecl, importc: "IupShowXY", dynlib: libiupSONAME, discardable.}
  100. proc Hide*(ih: PIhandle): cint {.cdecl, importc: "IupHide", dynlib: libiupSONAME, discardable.}
  101. proc Map*(ih: PIhandle): cint {.cdecl, importc: "IupMap", dynlib: libiupSONAME, discardable.}
  102. proc Unmap*(ih: PIhandle) {.cdecl, importc: "IupUnmap", dynlib: libiupSONAME.}
  103. proc ResetAttribute*(ih: PIhandle; name: cstring) {.cdecl, importc: "IupResetAttribute", dynlib: libiupSONAME.}
  104. proc GetAllAttributes*(ih: PIhandle; names: cstringArray; n: cint): cint {.cdecl, importc: "IupGetAllAttributes", dynlib: libiupSONAME, discardable.}
  105. proc CopyAttributes*(src_ih: PIhandle; dst_ih: PIhandle) {.cdecl, importc: "IupCopyAttributes", dynlib: libiupSONAME.}
  106. proc SetAtt*(handle_name: cstring; ih: PIhandle; name: cstring): PIhandle {.varargs, cdecl, importc: "IupSetAtt", dynlib: libiupSONAME.}
  107. proc SetAttributes*(ih: PIhandle; str: cstring): PIhandle {.cdecl, importc: "IupSetAttributes", dynlib: libiupSONAME, discardable.}
  108. proc GetAttributes*(ih: PIhandle): cstring {.cdecl, importc: "IupGetAttributes", dynlib: libiupSONAME.}
  109. proc SetAttribute*(ih: PIhandle; name: cstring; value: cstring) {.cdecl, importc: "IupSetAttribute", dynlib: libiupSONAME.}
  110. proc SetStrAttribute*(ih: PIhandle; name: cstring; value: cstring) {.cdecl, importc: "IupSetStrAttribute", dynlib: libiupSONAME.}
  111. proc SetStrf*(ih: PIhandle; name: cstring; format: cstring) {.varargs, cdecl, importc: "IupSetStrf", dynlib: libiupSONAME.}
  112. proc SetInt*(ih: PIhandle; name: cstring; value: cint) {.cdecl, importc: "IupSetInt", dynlib: libiupSONAME.}
  113. proc SetFloat*(ih: PIhandle; name: cstring; value: cfloat) {.cdecl, importc: "IupSetFloat", dynlib: libiupSONAME.}
  114. proc SetDouble*(ih: PIhandle; name: cstring; value: cdouble) {.cdecl, importc: "IupSetDouble", dynlib: libiupSONAME.}
  115. proc SetRGB*(ih: PIhandle; name: cstring; r: cuchar; g: cuchar; b: cuchar) {.cdecl, importc: "IupSetRGB", dynlib: libiupSONAME.}
  116. proc GetAttribute*(ih: PIhandle; name: cstring): cstring {.cdecl, importc: "IupGetAttribute", dynlib: libiupSONAME.}
  117. proc GetInt*(ih: PIhandle; name: cstring): cint {.cdecl, importc: "IupGetInt", dynlib: libiupSONAME, discardable.}
  118. proc GetInt2*(ih: PIhandle; name: cstring): cint {.cdecl, importc: "IupGetInt2", dynlib: libiupSONAME, discardable.}
  119. proc GetIntInt*(ih: PIhandle; name: cstring; i1: var cint; i2: var cint): cint {.cdecl, importc: "IupGetIntInt", dynlib: libiupSONAME, discardable.}
  120. proc GetFloat*(ih: PIhandle; name: cstring): cfloat {.cdecl, importc: "IupGetFloat", dynlib: libiupSONAME.}
  121. proc GetDouble*(ih: PIhandle; name: cstring): cdouble {.cdecl, importc: "IupGetDouble", dynlib: libiupSONAME.}
  122. proc GetRGB*(ih: PIhandle; name: cstring; r: ptr cuchar; g: ptr cuchar; b: ptr cuchar) {. cdecl, importc: "IupGetRGB", dynlib: libiupSONAME.}
  123. proc SetAttributeId*(ih: PIhandle; name: cstring; id: cint; value: cstring) {.cdecl, importc: "IupSetAttributeId", dynlib: libiupSONAME.}
  124. proc SetStrAttributeId*(ih: PIhandle; name: cstring; id: cint; value: cstring) {.cdecl, importc: "IupSetStrAttributeId", dynlib: libiupSONAME.}
  125. proc SetStrfId*(ih: PIhandle; name: cstring; id: cint; format: cstring) {.varargs, cdecl, importc: "IupSetStrfId", dynlib: libiupSONAME.}
  126. proc SetIntId*(ih: PIhandle; name: cstring; id: cint; value: cint) {.cdecl, importc: "IupSetIntId", dynlib: libiupSONAME.}
  127. proc SetFloatId*(ih: PIhandle; name: cstring; id: cint; value: cfloat) {.cdecl, importc: "IupSetFloatId", dynlib: libiupSONAME.}
  128. proc SetDoubleId*(ih: PIhandle; name: cstring; id: cint; value: cdouble) {.cdecl, importc: "IupSetDoubleId", dynlib: libiupSONAME.}
  129. proc SetRGBId*(ih: PIhandle; name: cstring; id: cint; r: cuchar; g: cuchar; b: cuchar) {. cdecl, importc: "IupSetRGBId", dynlib: libiupSONAME.}
  130. proc GetAttributeId*(ih: PIhandle; name: cstring; id: cint): cstring {.cdecl, importc: "IupGetAttributeId", dynlib: libiupSONAME.}
  131. proc GetIntId*(ih: PIhandle; name: cstring; id: cint): cint {.cdecl, importc: "IupGetIntId", dynlib: libiupSONAME, discardable.}
  132. proc GetFloatId*(ih: PIhandle; name: cstring; id: cint): cfloat {.cdecl, importc: "IupGetFloatId", dynlib: libiupSONAME.}
  133. proc GetDoubleId*(ih: PIhandle; name: cstring; id: cint): cdouble {.cdecl, importc: "IupGetDoubleId", dynlib: libiupSONAME.}
  134. proc GetRGBId*(ih: PIhandle; name: cstring; id: cint; r: ptr cuchar; g: ptr cuchar; b: ptr cuchar) {.cdecl, importc: "IupGetRGBId", dynlib: libiupSONAME.}
  135. proc SetAttributeId2*(ih: PIhandle; name: cstring; lin: cint; col: cint; value: cstring) {. cdecl, importc: "IupSetAttributeId2", dynlib: libiupSONAME.}
  136. proc SetStrAttributeId2*(ih: PIhandle; name: cstring; lin: cint; col: cint; value: cstring) {.cdecl, importc: "IupSetStrAttributeId2", dynlib: libiupSONAME.}
  137. proc SetStrfId2*(ih: PIhandle; name: cstring; lin: cint; col: cint; format: cstring) {. varargs, cdecl, importc: "IupSetStrfId2", dynlib: libiupSONAME.}
  138. proc SetIntId2*(ih: PIhandle; name: cstring; lin: cint; col: cint; value: cint) {.cdecl, importc: "IupSetIntId2", dynlib: libiupSONAME.}
  139. proc SetFloatId2*(ih: PIhandle; name: cstring; lin: cint; col: cint; value: cfloat) {. cdecl, importc: "IupSetFloatId2", dynlib: libiupSONAME.}
  140. proc SetDoubleId2*(ih: PIhandle; name: cstring; lin: cint; col: cint; value: cdouble) {. cdecl, importc: "IupSetDoubleId2", dynlib: libiupSONAME.}
  141. proc SetRGBId2*(ih: PIhandle; name: cstring; lin: cint; col: cint; r: cuchar; g: cuchar; b: cuchar) {.cdecl, importc: "IupSetRGBId2", dynlib: libiupSONAME.}
  142. proc GetAttributeId2*(ih: PIhandle; name: cstring; lin: cint; col: cint): cstring {. cdecl, importc: "IupGetAttributeId2", dynlib: libiupSONAME.}
  143. proc GetIntId2*(ih: PIhandle; name: cstring; lin: cint; col: cint): cint {.cdecl, importc: "IupGetIntId2", dynlib: libiupSONAME, discardable.}
  144. proc GetFloatId2*(ih: PIhandle; name: cstring; lin: cint; col: cint): cfloat {.cdecl, importc: "IupGetFloatId2", dynlib: libiupSONAME.}
  145. proc GetDoubleId2*(ih: PIhandle; name: cstring; lin: cint; col: cint): cdouble {.cdecl, importc: "IupGetDoubleId2", dynlib: libiupSONAME.}
  146. proc GetRGBId2*(ih: PIhandle; name: cstring; lin: cint; col: cint; r: ptr cuchar; g: ptr cuchar; b: ptr cuchar) {.cdecl, importc: "IupGetRGBId2", dynlib: libiupSONAME.}
  147. proc SetGlobal*(name: cstring; value: cstring) {.cdecl, importc: "IupSetGlobal", dynlib: libiupSONAME.}
  148. proc SetStrGlobal*(name: cstring; value: cstring) {.cdecl, importc: "IupSetStrGlobal", dynlib: libiupSONAME.}
  149. proc GetGlobal*(name: cstring): cstring {.cdecl, importc: "IupGetGlobal", dynlib: libiupSONAME.}
  150. proc SetFocus*(ih: PIhandle): PIhandle {.cdecl, importc: "IupSetFocus", dynlib: libiupSONAME, discardable.}
  151. proc GetFocus*(): PIhandle {.cdecl, importc: "IupGetFocus", dynlib: libiupSONAME.}
  152. proc PreviousField*(ih: PIhandle): PIhandle {.cdecl, importc: "IupPreviousField", dynlib: libiupSONAME.}
  153. proc NextField*(ih: PIhandle): PIhandle {.cdecl, importc: "IupNextField", dynlib: libiupSONAME.}
  154. proc GetCallback*(ih: PIhandle; name: cstring): Icallback {.cdecl, importc: "IupGetCallback", dynlib: libiupSONAME.}
  155. proc SetCallback*(ih: PIhandle; name: cstring; `func`: Icallback): Icallback {.cdecl, importc: "IupSetCallback", dynlib: libiupSONAME, discardable.}
  156. proc SetCallbacks*(ih: PIhandle; name: cstring; `func`: Icallback): PIhandle {. varargs, cdecl, importc: "IupSetCallbacks", dynlib: libiupSONAME, discardable.}
  157. proc GetFunction*(name: cstring): Icallback {.cdecl, importc: "IupGetFunction", dynlib: libiupSONAME.}
  158. proc SetFunction*(name: cstring; `func`: Icallback): Icallback {.cdecl, importc: "IupSetFunction", dynlib: libiupSONAME.}
  159. proc GetHandle*(name: cstring): PIhandle {.cdecl, importc: "IupGetHandle", dynlib: libiupSONAME.}
  160. proc SetHandle*(name: cstring; ih: PIhandle): PIhandle {.cdecl, importc: "IupSetHandle", dynlib: libiupSONAME, discardable.}
  161. proc GetAllNames*(names: cstringArray; n: cint): cint {.cdecl, importc: "IupGetAllNames", dynlib: libiupSONAME, discardable.}
  162. proc GetAllDialogs*(names: cstringArray; n: cint): cint {.cdecl, importc: "IupGetAllDialogs", dynlib: libiupSONAME, discardable.}
  163. proc GetName*(ih: PIhandle): cstring {.cdecl, importc: "IupGetName", dynlib: libiupSONAME.}
  164. proc SetAttributeHandle*(ih: PIhandle; name: cstring; ih_named: PIhandle) {.cdecl, importc: "IupSetAttributeHandle", dynlib: libiupSONAME.}
  165. proc GetAttributeHandle*(ih: PIhandle; name: cstring): PIhandle {.cdecl, importc: "IupGetAttributeHandle", dynlib: libiupSONAME.}
  166. proc SetAttributeHandleId*(ih: PIhandle; name: cstring; id: cint; ih_named: PIhandle) {.cdecl, importc: "IupSetAttributeHandleId", dynlib: libiupSONAME.}
  167. proc GetAttributeHandleId*(ih: PIhandle; name: cstring; id: cint): PIhandle {.cdecl, importc: "IupGetAttributeHandleId", dynlib: libiupSONAME.}
  168. proc SetAttributeHandleId2*(ih: PIhandle; name: cstring; lin: cint; col: cint; ih_named: PIhandle) {.cdecl, importc: "IupSetAttributeHandleId2", dynlib: libiupSONAME.}
  169. proc GetAttributeHandleId2*(ih: PIhandle; name: cstring; lin: cint; col: cint): PIhandle {. cdecl, importc: "IupGetAttributeHandleId2", dynlib: libiupSONAME.}
  170. proc GetClassName*(ih: PIhandle): cstring {.cdecl, importc: "IupGetClassName", dynlib: libiupSONAME.}
  171. proc GetClassType*(ih: PIhandle): cstring {.cdecl, importc: "IupGetClassType", dynlib: libiupSONAME.}
  172. proc GetAllClasses*(names: cstringArray; n: cint): cint {.cdecl, importc: "IupGetAllClasses", dynlib: libiupSONAME, discardable.}
  173. proc GetClassAttributes*(classname: cstring; names: cstringArray; n: cint): cint {. cdecl, importc: "IupGetClassAttributes", dynlib: libiupSONAME, discardable.}
  174. proc GetClassCallbacks*(classname: cstring; names: cstringArray; n: cint): cint {.cdecl, importc: "IupGetClassCallbacks", dynlib: libiupSONAME, discardable.}
  175. proc SaveClassAttributes*(ih: PIhandle) {.cdecl, importc: "IupSaveClassAttributes", dynlib: libiupSONAME.}
  176. proc CopyClassAttributes*(src_ih: PIhandle; dst_ih: PIhandle) {.cdecl, importc: "IupCopyClassAttributes", dynlib: libiupSONAME.}
  177. proc SetClassDefaultAttribute*(classname: cstring; name: cstring; value: cstring) {. cdecl, importc: "IupSetClassDefaultAttribute", dynlib: libiupSONAME.}
  178. proc ClassMatch*(ih: PIhandle; classname: cstring): cint {.cdecl, importc: "IupClassMatch", dynlib: libiupSONAME, discardable.}
  179. proc Create*(classname: cstring): PIhandle {.cdecl, importc: "IupCreate", dynlib: libiupSONAME.}
  180. proc Createv*(classname: cstring; params: ptr pointer): PIhandle {.cdecl, importc: "IupCreatev", dynlib: libiupSONAME.}
  181. proc Createp*(classname: cstring; first: pointer): PIhandle {.varargs, cdecl, importc: "IupCreatep", dynlib: libiupSONAME.}
  182. proc Fill*(): PIhandle {.cdecl, importc: "IupFill", dynlib: libiupSONAME.}
  183. proc Space*(): PIhandle {.cdecl, importc: "IupSpace", dynlib: libiupSONAME.}
  184. proc Radio*(child: PIhandle): PIhandle {.cdecl, importc: "IupRadio", dynlib: libiupSONAME.}
  185. proc Vbox*(child: PIhandle): PIhandle {.varargs, cdecl, importc: "IupVbox", dynlib: libiupSONAME.}
  186. proc Vboxv*(children: ptr PIhandle): PIhandle {.cdecl, importc: "IupVboxv", dynlib: libiupSONAME.}
  187. proc Zbox*(child: PIhandle): PIhandle {.varargs, cdecl, importc: "IupZbox", dynlib: libiupSONAME.}
  188. proc Zboxv*(children: ptr PIhandle): PIhandle {.cdecl, importc: "IupZboxv", dynlib: libiupSONAME.}
  189. proc Hbox*(child: PIhandle): PIhandle {.varargs, cdecl, importc: "IupHbox", dynlib: libiupSONAME.}
  190. proc Hboxv*(children: ptr PIhandle): PIhandle {.cdecl, importc: "IupHboxv", dynlib: libiupSONAME.}
  191. proc Normalizer*(ih_first: PIhandle): PIhandle {.varargs, cdecl, importc: "IupNormalizer", dynlib: libiupSONAME.}
  192. proc Normalizerv*(ih_list: ptr PIhandle): PIhandle {.cdecl, importc: "IupNormalizerv", dynlib: libiupSONAME.}
  193. proc Cbox*(child: PIhandle): PIhandle {.varargs, cdecl, importc: "IupCbox", dynlib: libiupSONAME.}
  194. proc Cboxv*(children: ptr PIhandle): PIhandle {.cdecl, importc: "IupCboxv", dynlib: libiupSONAME.}
  195. proc Sbox*(child: PIhandle): PIhandle {.cdecl, importc: "IupSbox", dynlib: libiupSONAME.}
  196. proc Split*(child1: PIhandle; child2: PIhandle): PIhandle {.cdecl, importc: "IupSplit", dynlib: libiupSONAME.}
  197. proc ScrollBox*(child: PIhandle): PIhandle {.cdecl, importc: "IupScrollBox", dynlib: libiupSONAME.}
  198. proc FlatScrollBox*(child: PIhandle): PIhandle {.cdecl, importc: "IupFlatScrollBox", dynlib: libiupSONAME.}
  199. proc GridBox*(child: PIhandle): PIhandle {.varargs, cdecl, importc: "IupGridBox", dynlib: libiupSONAME.}
  200. proc GridBoxv*(children: ptr PIhandle): PIhandle {.cdecl, importc: "IupGridBoxv", dynlib: libiupSONAME.}
  201. proc MultiBox*(child: PIhandle): PIhandle {.varargs, cdecl, importc: "IupMultiBox", dynlib: libiupSONAME.}
  202. proc MultiBoxv*(children: ptr PIhandle): PIhandle {.cdecl, importc: "IupMultiBoxv", dynlib: libiupSONAME.}
  203. proc Expander*(child: PIhandle): PIhandle {.cdecl, importc: "IupExpander", dynlib: libiupSONAME.}
  204. proc DetachBox*(child: PIhandle): PIhandle {.cdecl, importc: "IupDetachBox", dynlib: libiupSONAME.}
  205. proc BackgroundBox*(child: PIhandle): PIhandle {.cdecl, importc: "IupBackgroundBox", dynlib: libiupSONAME.}
  206. proc Frame*(child: PIhandle): PIhandle {.cdecl, importc: "IupFrame", dynlib: libiupSONAME.}
  207. proc FlatFrame*(child: PIhandle): PIhandle {.cdecl, importc: "IupFlatFrame", dynlib: libiupSONAME.}
  208. proc Image*(width: cint; height: cint; pixels: ptr cuchar): PIhandle {.cdecl, importc: "IupImage", dynlib: libiupSONAME.}
  209. proc ImageRGB*(width: cint; height: cint; pixels: ptr cuchar): PIhandle {.cdecl, importc: "IupImageRGB", dynlib: libiupSONAME.}
  210. proc ImageRGBA*(width: cint; height: cint; pixels: ptr cuchar): PIhandle {.cdecl, importc: "IupImageRGBA", dynlib: libiupSONAME.}
  211. proc Item*(title: cstring; action: cstring): PIhandle {.cdecl, importc: "IupItem", dynlib: libiupSONAME.}
  212. proc Submenu*(title: cstring; child: PIhandle): PIhandle {.cdecl, importc: "IupSubmenu", dynlib: libiupSONAME.}
  213. proc Separator*(): PIhandle {.cdecl, importc: "IupSeparator", dynlib: libiupSONAME.}
  214. proc Menu*(child: PIhandle): PIhandle {.varargs, cdecl, importc: "IupMenu", dynlib: libiupSONAME.}
  215. proc Menuv*(children: ptr PIhandle): PIhandle {.cdecl, importc: "IupMenuv", dynlib: libiupSONAME.}
  216. proc Button*(title: cstring; action: cstring): PIhandle {.cdecl, importc: "IupButton", dynlib: libiupSONAME.}
  217. proc FlatButton*(title: cstring): PIhandle {.cdecl, importc: "IupFlatButton", dynlib: libiupSONAME.}
  218. proc FlatToggle*(title: cstring): PIhandle {.cdecl, importc: "IupFlatToggle", dynlib: libiupSONAME.}
  219. proc DropButton*(dropchild: PIhandle): PIhandle {.cdecl, importc: "IupDropButton", dynlib: libiupSONAME.}
  220. proc FlatLabel*(title: cstring): PIhandle {.cdecl, importc: "IupFlatLabel", dynlib: libiupSONAME.}
  221. proc FlatSeparator*(): PIhandle {.cdecl, importc: "IupFlatSeparator", dynlib: libiupSONAME.}
  222. proc Canvas*(action: cstring): PIhandle {.cdecl, importc: "IupCanvas", dynlib: libiupSONAME.}
  223. proc Dialog*(child: PIhandle): PIhandle {.cdecl, importc: "IupDialog", dynlib: libiupSONAME.}
  224. proc User*(): PIhandle {.cdecl, importc: "IupUser", dynlib: libiupSONAME.}
  225. proc Thread*(): PIhandle {.cdecl, importc: "IupThread", dynlib: libiupSONAME.}
  226. proc Label*(title: cstring): PIhandle {.cdecl, importc: "IupLabel", dynlib: libiupSONAME.}
  227. proc List*(action: cstring): PIhandle {.cdecl, importc: "IupList", dynlib: libiupSONAME.}
  228. proc FlatList*(): PIhandle {.cdecl, importc: "IupFlatList", dynlib: libiupSONAME.}
  229. proc Text*(action: cstring): PIhandle {.cdecl, importc: "IupText", dynlib: libiupSONAME.}
  230. proc MultiLine*(action: cstring): PIhandle {.cdecl, importc: "IupMultiLine", dynlib: libiupSONAME.}
  231. proc Toggle*(title: cstring; action: cstring): PIhandle {.cdecl, importc: "IupToggle", dynlib: libiupSONAME.}
  232. proc Timer*(): PIhandle {.cdecl, importc: "IupTimer", dynlib: libiupSONAME.}
  233. proc Clipboard*(): PIhandle {.cdecl, importc: "IupClipboard", dynlib: libiupSONAME.}
  234. proc ProgressBar*(): PIhandle {.cdecl, importc: "IupProgressBar", dynlib: libiupSONAME.}
  235. proc Val*(`type`: cstring): PIhandle {.cdecl, importc: "IupVal", dynlib: libiupSONAME.}
  236. proc FlatVal*(`type`: cstring): PIhandle {.cdecl, importc: "IupFlatVal", dynlib: libiupSONAME.}
  237. proc Tabs*(child: PIhandle): PIhandle {.varargs, cdecl, importc: "IupTabs", dynlib: libiupSONAME.}
  238. proc Tabsv*(children: ptr PIhandle): PIhandle {.cdecl, importc: "IupTabsv", dynlib: libiupSONAME.}
  239. proc FlatTabs*(first: PIhandle): PIhandle {.varargs, cdecl, importc: "IupFlatTabs", dynlib: libiupSONAME.}
  240. proc FlatTabsv*(children: ptr PIhandle): PIhandle {.cdecl, importc: "IupFlatTabsv", dynlib: libiupSONAME.}
  241. proc Tree*(): PIhandle {.cdecl, importc: "IupTree", dynlib: libiupSONAME.}
  242. proc Link*(url: cstring; title: cstring): PIhandle {.cdecl, importc: "IupLink", dynlib: libiupSONAME.}
  243. proc AnimatedLabel*(animation: PIhandle): PIhandle {.cdecl, importc: "IupAnimatedLabel", dynlib: libiupSONAME.}
  244. proc DatePick*(): PIhandle {.cdecl, importc: "IupDatePick", dynlib: libiupSONAME.}
  245. proc Calendar*(): PIhandle {.cdecl, importc: "IupCalendar", dynlib: libiupSONAME.}
  246. proc Colorbar*(): PIhandle {.cdecl, importc: "IupColorbar", dynlib: libiupSONAME.}
  247. proc Gauge*(): PIhandle {.cdecl, importc: "IupGauge", dynlib: libiupSONAME.}
  248. proc Dial*(`type`: cstring): PIhandle {.cdecl, importc: "IupDial", dynlib: libiupSONAME.}
  249. proc ColorBrowser*(): PIhandle {.cdecl, importc: "IupColorBrowser", dynlib: libiupSONAME.}
  250. proc Spin*(): PIhandle {.cdecl, importc: "IupSpin", dynlib: libiupSONAME.}
  251. proc Spinbox*(child: PIhandle): PIhandle {.cdecl, importc: "IupSpinbox", dynlib: libiupSONAME.}
  252. proc StringCompare*(str1: cstring; str2: cstring; casesensitive: cint; lexicographic: cint): cint {.cdecl, importc: "IupStringCompare", dynlib: libiupSONAME, discardable.}
  253. proc SaveImageAsText*(ih: PIhandle; filename: cstring; format: cstring; name: cstring): cint {. cdecl, importc: "IupSaveImageAsText", dynlib: libiupimSONAME, discardable.}
  254. proc ImageGetHandle*(name: cstring): PIhandle {.cdecl, importc: "IupImageGetHandle", dynlib: libiupSONAME.}
  255. proc TextConvertLinColToPos*(ih: PIhandle; lin: cint; col: cint; pos: var cint) {.cdecl, importc: "IupTextConvertLinColToPos", dynlib: libiupSONAME.}
  256. proc TextConvertPosToLinCol*(ih: PIhandle; pos: cint; lin: var cint; col: var cint) {. cdecl, importc: "IupTextConvertPosToLinCol", dynlib: libiupSONAME.}
  257. proc ConvertXYToPos*(ih: PIhandle; x: cint; y: cint): cint {.cdecl, importc: "IupConvertXYToPos", dynlib: libiupSONAME, discardable.}
  258. proc StoreGlobal*(name: cstring; value: cstring) {.cdecl, importc: "IupStoreGlobal", dynlib: libiupSONAME.}
  259. proc StoreAttribute*(ih: PIhandle; name: cstring; value: cstring) {.cdecl, importc: "IupStoreAttribute", dynlib: libiupSONAME.}
  260. proc SetfAttribute*(ih: PIhandle; name: cstring; format: cstring) {.varargs, cdecl, importc: "IupSetfAttribute", dynlib: libiupSONAME.}
  261. proc StoreAttributeId*(ih: PIhandle; name: cstring; id: cint; value: cstring) {.cdecl, importc: "IupStoreAttributeId", dynlib: libiupSONAME.}
  262. proc SetfAttributeId*(ih: PIhandle; name: cstring; id: cint; f: cstring) {.varargs, cdecl, importc: "IupSetfAttributeId", dynlib: libiupSONAME.}
  263. proc StoreAttributeId2*(ih: PIhandle; name: cstring; lin: cint; col: cint; value: cstring) {.cdecl, importc: "IupStoreAttributeId2", dynlib: libiupSONAME.}
  264. proc SetfAttributeId2*(ih: PIhandle; name: cstring; lin: cint; col: cint; format: cstring) {.varargs, cdecl, importc: "IupSetfAttributeId2", dynlib: libiupSONAME.}
  265. proc TreeSetUserId*(ih: PIhandle; id: cint; userid: pointer): cint {.cdecl, importc: "IupTreeSetUserId", dynlib: libiupSONAME, discardable.}
  266. proc TreeGetUserId*(ih: PIhandle; id: cint): pointer {.cdecl, importc: "IupTreeGetUserId", dynlib: libiupSONAME.}
  267. proc TreeGetId*(ih: PIhandle; userid: pointer): cint {.cdecl, importc: "IupTreeGetId", dynlib: libiupSONAME, discardable.}
  268. proc TreeSetAttributeHandle*(ih: PIhandle; name: cstring; id: cint; ih_named: PIhandle) {.cdecl, importc: "IupTreeSetAttributeHandle", dynlib: libiupSONAME.}
  269. proc FileDlg*(): PIhandle {.cdecl, importc: "IupFileDlg", dynlib: libiupSONAME.}
  270. proc MessageDlg*(): PIhandle {.cdecl, importc: "IupMessageDlg", dynlib: libiupSONAME.}
  271. proc ColorDlg*(): PIhandle {.cdecl, importc: "IupColorDlg", dynlib: libiupSONAME.}
  272. proc FontDlg*(): PIhandle {.cdecl, importc: "IupFontDlg", dynlib: libiupSONAME.}
  273. proc ProgressDlg*(): PIhandle {.cdecl, importc: "IupProgressDlg", dynlib: libiupSONAME.}
  274. proc GetFile*(arq: cstring): cint {.cdecl, importc: "IupGetFile", dynlib: libiupSONAME, discardable.}
  275. proc Message*(title: cstring; msg: cstring) {.cdecl, importc: "IupMessage", dynlib: libiupSONAME.}
  276. proc Messagef*(title: cstring; format: cstring) {.varargs, cdecl, importc: "IupMessagef", dynlib: libiupSONAME.}
  277. proc MessageError*(parent: PIhandle; message: cstring) {.cdecl, importc: "IupMessageError", dynlib: libiupSONAME.}
  278. proc MessageAlarm*(parent: PIhandle; title: cstring; message: cstring; buttons: cstring): cint {.cdecl, importc: "IupMessageAlarm", dynlib: libiupSONAME, discardable.}
  279. proc Alarm*(title: cstring; msg: cstring; b1: cstring; b2: cstring; b3: cstring): cint {. cdecl, importc: "IupAlarm", dynlib: libiupSONAME, discardable.}
  280. proc Scanf*(format: cstring): cint {.varargs, cdecl, importc: "IupScanf", dynlib: libiupSONAME, discardable.}
  281. proc ListDialog*(`type`: cint; title: cstring; size: cint; list: cstringArray; op: cint; max_col: cint; max_lin: cint; marks: var cint): cint {.cdecl, importc: "IupListDialog", dynlib: libiupSONAME, discardable.}
  282. proc GetText*(title: cstring; text: cstring; maxsize: cint): cint {.cdecl, importc: "IupGetText", dynlib: libiupSONAME, discardable.}
  283. proc GetColor*(x: cint; y: cint; r: ptr cuchar; g: ptr cuchar; b: ptr cuchar): cint {.cdecl, importc: "IupGetColor", dynlib: libiupSONAME, discardable.}
  284. type
  285.   Iparamcb* = proc (dialog: PIhandle; param_index: cint; user_data: pointer): cint {.
  286.       cdecl.}
  287.  
  288. proc GetParam*(title: cstring; action: Iparamcb; user_data: pointer; format: cstring): cint {. varargs, cdecl, importc: "IupGetParam", dynlib: libiupSONAME, discardable.}
  289. proc GetParamv*(title: cstring; action: Iparamcb; user_data: pointer; format: cstring; param_count: cint; param_extra: cint; param_data: ptr pointer): cint {. cdecl, importc: "IupGetParamv", dynlib: libiupSONAME, discardable.}
  290. proc Param*(format: cstring): PIhandle {.cdecl, importc: "IupParam", dynlib: libiupSONAME.}
  291. proc ParamBox*(param: PIhandle): PIhandle {.varargs, cdecl, importc: "IupParamBox", dynlib: libiupSONAME.}
  292. proc ParamBoxv*(param_array: ptr PIhandle): PIhandle {.cdecl, importc: "IupParamBoxv", dynlib: libiupSONAME.}
  293. proc LayoutDialog*(dialog: PIhandle): PIhandle {.cdecl, importc: "IupLayoutDialog", dynlib: libiupSONAME.}
  294. proc ElementPropertiesDialog*(parent: PIhandle; elem: PIhandle): PIhandle {. cdecl, importc: "IupElementPropertiesDialog", dynlib: libiupSONAME.}
  295. proc GlobalsDialog*(): PIhandle {.cdecl, importc: "IupGlobalsDialog", dynlib: libiupSONAME.}
  296. proc ClassInfoDialog*(parent: PIhandle): PIhandle {.cdecl, importc: "IupClassInfoDialog", dynlib: libiupSONAME.}
  297.  

tinc.nim IUP test script
Code: Text
  1. include iup
  2.  
  3. proc btn_exit_cb(ih:PIhandle):cint {.cdecl.}=
  4.   return IUP_CLOSE
  5.  
  6. var dlg, button, label, vbox: PIhandle
  7. var argc:cint
  8. var argv:ptr cstringArray
  9.  
  10. Open(argc, argv)
  11.  
  12. label =  Label("Hello world from IUP.")
  13. button = Button("OK", nil)
  14.  
  15. vbox = Vbox(label, button, nil)
  16. SetAttribute(vbox, "ALIGNMENT", "ACENTER")
  17. SetAttribute(vbox, "GAP", "10")
  18. SetAttribute(vbox, "MARGIN", "10x10")
  19.  
  20. dlg = Dialog(vbox)
  21. SetAttribute(dlg, "TITLE", "Ubuntu RPi")
  22.  
  23. SetCallback(button, "ACTION", btn_exit_cb)
  24.  
  25. ShowXY(dlg, IUP_CENTER, IUP_CENTER)
  26.  
  27. MainLoop()
  28.  
  29. Close()
  30.  


ubuntu@rpi4b:~/repo/Nim/examples$ nim c -d:release tinc.nim
Hint: used config file '/home/ubuntu/repo/Nim/config/nim.cfg' [Conf]
Hint: used config file '/home/ubuntu/repo/Nim/config/config.nims' [Conf]
Hint: system [Processing]
Hint: widestrs [Processing]
Hint: io [Processing]
Hint: tinc [Processing]
/home/ubuntu/repo/Nim/examples/iup.nim(13, 3) Hint: 'libiupglSONAME' is declared but not used [XDeclaredButNotUsed]
/home/ubuntu/repo/Nim/examples/iup.nim(20, 3) Hint: 'libiupwebSONAME' is declared but not used [XDeclaredButNotUsed]
/home/ubuntu/repo/Nim/examples/iup.nim(19, 3) Hint: 'libiuptuioSONAME' is declared but not used [XDeclaredButNotUsed]
/home/ubuntu/repo/Nim/examples/iup.nim(16, 3) Hint: 'libiup_mglplotSONAME' is declared but not used [XDeclaredButNotUsed]
/home/ubuntu/repo/Nim/examples/iup.nim(17, 3) Hint: 'libiup_plotSONAME' is declared but not used [XDeclaredButNotUsed]
/home/ubuntu/repo/Nim/examples/iup.nim(11, 3) Hint: 'libiupcontrolsSONAME' is declared but not used [XDeclaredButNotUsed]
/home/ubuntu/repo/Nim/examples/iup.nim(12, 3) Hint: 'libiupglcontrolsSONAME' is declared but not used [XDeclaredButNotUsed]
/home/ubuntu/repo/Nim/examples/iup.nim(18, 3) Hint: 'libiup_scintillaSONAME' is declared but not used [XDeclaredButNotUsed]
/home/ubuntu/repo/Nim/examples/iup.nim(10, 3) Hint: 'libcdSONAME' is declared but not used [XDeclaredButNotUsed]
/home/ubuntu/repo/Nim/examples/iup.nim(9, 3) Hint: 'libiupcdSONAME' is declared but not used [XDeclaredButNotUsed]
CC: stdlib_system.nim
CC: tinc.nim
Hint:  [Link]
Hint: operation successful (22171 lines compiled; 6.781 sec total; 19.84MiB peakmem; Release Build) [SuccessX]
ubuntu@rpi4b:~/repo/Nim/examples$

Title: Re: RaspberryBASIC.org Forum
Post by: John on December 24, 2019, 03:27:53 PM
I think I'm going to build an IUP app that allows you to select what resouces you need for you script and generates a custom include.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 24, 2019, 06:28:07 PM
AIR,

Does Nim provide any debugging tools? Finding this niup bug by adding code until it breaks seem brute force.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 24, 2019, 08:52:41 PM
I found the problem with the niup library. I don't know how to fix it but at least everything else works (compiles) I reworked the niup.nim file as part of my debugging effort.

To me this looks like an attempt at a shortcut to dropping the Iup prefix but  doesn't look well thought out. Maybe the 1.1.1 version I'm running says no way.

Code that causes the error
Code: Text
  1. const
  2. #  isshift* = iup_isshift
  3. #  iscontrol* = iup_iscontrol
  4. #  isbutton1* = iup_isbutton1
  5. #  isbutton2* = iup_isbutton2
  6. #  isbutton3* = iup_isbutton3
  7. #  isdouble* = iup_isdouble
  8. #  isalt* = iup_isalt
  9. #  issys* = iup_issys
  10. #  isbutton4* = iup_isbutton4
  11. #  isbutton5* = iup_isbutton5
  12.  

Attached is my iup.nim (niup rework)
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 25, 2019, 05:46:54 AM
AIR,

The first time you built the shared objects for IUP there were multiple .so files. The latest tecmake.mak only builds one .so file. The static library is the same.

I think CD and IM are okay.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 25, 2019, 11:16:29 AM
It builds fine for me.  All static and dynamic libraries.  With the tecmake.mak I posted.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 25, 2019, 11:25:07 AM
Here are my lib build directories.


ubuntu@rpi4b:~/iup-dev/iup/lib/Linux53_arm64$ ls -l
total 3800
-rw-r--r-- 1 ubuntu ubuntu 2627956 Dec 21 22:31 libiup.a
-rwxr-xr-x 1 ubuntu ubuntu 1258520 Dec 21 22:31 libiup.so
ubuntu@rpi4b:~/iup-dev/iup/lib/Linux53_arm64$

ubuntu@rpi4b:~/iup-dev/cd/lib/Linux53_arm64$ ls -l
total 5648
drwxr-xr-x 2 ubuntu ubuntu    4096 Dec 21 22:24 Lua53
-rw-r--r-- 1 ubuntu ubuntu 1284338 Dec 21 22:22 libcd.a
-rwxr-xr-x 1 ubuntu ubuntu  892504 Dec 21 22:22 libcd.so
-rw-r--r-- 1 ubuntu ubuntu    1562 Dec 21 22:23 libcdcontextplus.a
-rwxr-xr-x 1 ubuntu ubuntu    7984 Dec 21 22:23 libcdcontextplus.so
-rw-r--r-- 1 ubuntu ubuntu   40324 Dec 21 22:23 libcdgl.a
-rwxr-xr-x 1 ubuntu ubuntu   40176 Dec 21 22:23 libcdgl.so
-rw-r--r-- 1 ubuntu ubuntu    7084 Dec 21 22:23 libcdim.a
-rwxr-xr-x 1 ubuntu ubuntu   14360 Dec 21 22:23 libcdim.so
-rw-r--r-- 1 ubuntu ubuntu   50350 Dec 21 22:23 libcdpdf.a
-rwxr-xr-x 1 ubuntu ubuntu   44088 Dec 21 22:23 libcdpdf.so
-rw-r--r-- 1 ubuntu ubuntu 1923682 Dec 21 22:23 libpdflib.a
-rwxr-xr-x 1 ubuntu ubuntu 1455088 Dec 21 22:23 libpdflib.so
ubuntu@rpi4b:~/iup-dev/cd/lib/Linux53_arm64$

ubuntu@rpi4b:~/iup-dev/im/lib/Linux53_arm64$ ls -l
total 9184
drwxr-xr-x 2 ubuntu ubuntu    4096 Dec 21 22:43 Lua53
-rw-r--r-- 1 ubuntu ubuntu 2228190 Dec 21 22:38 libim.a
-rwxr-xr-x 1 ubuntu ubuntu 1473784 Dec 21 22:38 libim.so
-rw-r--r-- 1 ubuntu ubuntu  317320 Dec 21 22:43 libim_fftw.a
-rwxr-xr-x 1 ubuntu ubuntu  205872 Dec 21 22:43 libim_fftw.so
-rw-r--r-- 1 ubuntu ubuntu  437912 Dec 21 22:39 libim_jp2.a
-rwxr-xr-x 1 ubuntu ubuntu  322440 Dec 21 22:39 libim_jp2.so
-rw-r--r-- 1 ubuntu ubuntu   12380 Dec 21 22:43 libim_lzo.a
-rwxr-xr-x 1 ubuntu ubuntu   17816 Dec 21 22:43 libim_lzo.so
-rw-r--r-- 1 ubuntu ubuntu  810614 Dec 21 22:40 libim_process.a
-rwxr-xr-x 1 ubuntu ubuntu  619472 Dec 21 22:40 libim_process.so
-rw-r--r-- 1 ubuntu ubuntu 1741958 Dec 21 22:42 libim_process_omp.a
-rwxr-xr-x 1 ubuntu ubuntu 1190616 Dec 21 22:42 libim_process_omp.so
ubuntu@rpi4b:~/iup-dev/im/lib/Linux53_arm64$


Remarking out the code I mentioned above makes the niup extension work as  a module.

Code: Text
  1. import niup
  2. import niupext
  3.  
  4. proc btn_exit_cb(ih:PIhandle):cint {.cdecl.}=
  5.   # Exits the main loop
  6.   return IUP_CLOSE
  7.  
  8. proc mainProc =
  9.   var dlg, button, label, vbox: PIhandle
  10.  
  11.   Open()
  12.  
  13.   label =  Label("Hello world from IUP.")
  14.   button = Button("OK", nil)
  15.  
  16.   vbox = Vbox(label, button, nil)
  17.   SetAttribute(vbox, "ALIGNMENT", "ACENTER")
  18.   SetAttribute(vbox, "GAP", "10")
  19.   SetAttribute(vbox, "MARGIN", "10x10")
  20.  
  21.   dlg = Dialog(vbox)
  22.   SetAttribute(dlg, "TITLE", "Ubuntu 64")
  23.  
  24.   # Registers callbacks
  25.   SetCallback(button, "ACTION", btn_exit_cb)
  26.  
  27.   ShowXY(dlg, IUP_CENTER, IUP_CENTER)
  28.  
  29.   MainLoop()
  30.  
  31.   Close()
  32.  
  33. if isMainModule:
  34.   mainProc()
  35.  




Merry Christmas AIR!
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 25, 2019, 12:23:33 PM
riveraa@ubuntu:~/iup-dev/build$ for x in cd im iup;do printf "\n\n$x\n";ll $x/lib/Linux53_arm64;done


cd
total 5.6M
drwxrwxr-x 2 riveraa riveraa 4.0K Dec 25 13:45 Lua53
-rw-rw-r-- 1 riveraa riveraa 1.3M Dec 25 13:43 libcd.a
-rwxrwxr-x 1 riveraa riveraa 872K Dec 25 13:43 libcd.so
-rw-rw-r-- 1 riveraa riveraa 1.6K Dec 25 13:44 libcdcontextplus.a
-rwxrwxr-x 1 riveraa riveraa 7.8K Dec 25 13:44 libcdcontextplus.so
-rw-rw-r-- 1 riveraa riveraa  40K Dec 25 13:44 libcdgl.a
-rwxrwxr-x 1 riveraa riveraa  40K Dec 25 13:44 libcdgl.so
-rw-rw-r-- 1 riveraa riveraa 7.0K Dec 25 13:44 libcdim.a
-rwxrwxr-x 1 riveraa riveraa  15K Dec 25 13:44 libcdim.so
-rw-rw-r-- 1 riveraa riveraa  50K Dec 25 13:44 libcdpdf.a
-rwxrwxr-x 1 riveraa riveraa  44K Dec 25 13:44 libcdpdf.so
-rw-rw-r-- 1 riveraa riveraa 1.9M Dec 25 13:44 libpdflib.a
-rwxrwxr-x 1 riveraa riveraa 1.4M Dec 25 13:44 libpdflib.so


im
total 9.0M
drwxrwxr-x 2 riveraa riveraa 4.0K Dec 25 13:04 Lua53
-rw-rw-r-- 1 riveraa riveraa 2.2M Dec 25 13:00 libim.a
-rwxrwxr-x 1 riveraa riveraa 1.5M Dec 25 13:00 libim.so
-rw-rw-r-- 1 riveraa riveraa 310K Dec 25 13:04 libim_fftw.a
-rwxrwxr-x 1 riveraa riveraa 202K Dec 25 13:04 libim_fftw.so
-rw-rw-r-- 1 riveraa riveraa 428K Dec 25 13:00 libim_jp2.a
-rwxrwxr-x 1 riveraa riveraa 315K Dec 25 13:00 libim_jp2.so
-rw-rw-r-- 1 riveraa riveraa  13K Dec 25 13:04 libim_lzo.a
-rwxrwxr-x 1 riveraa riveraa  18K Dec 25 13:04 libim_lzo.so
-rw-rw-r-- 1 riveraa riveraa 792K Dec 25 13:01 libim_process.a
-rwxrwxr-x 1 riveraa riveraa 605K Dec 25 13:01 libim_process.so
-rw-rw-r-- 1 riveraa riveraa 1.7M Dec 25 13:03 libim_process_omp.a
-rwxrwxr-x 1 riveraa riveraa 1.2M Dec 25 13:03 libim_process_omp.so


iup
total 22M
drwxrwxr-x 2 riveraa riveraa 4.0K Dec 25 14:04 Lua53
-rw-rw-r-- 1 riveraa riveraa 2.6M Dec 25 13:47 libiup.a
-rwxrwxr-x 1 riveraa riveraa 1.3M Dec 25 13:47 libiup.so
-rw-rw-r-- 1 riveraa riveraa 4.6M Dec 25 13:52 libiup_mglplot.a
-rwxrwxr-x 1 riveraa riveraa 2.9M Dec 25 13:52 libiup_mglplot.so
-rw-rw-r-- 1 riveraa riveraa 480K Dec 25 13:48 libiup_plot.a
-rwxrwxr-x 1 riveraa riveraa 293K Dec 25 13:48 libiup_plot.so
-rw-rw-r-- 1 riveraa riveraa 4.4M Dec 25 13:58 libiup_scintilla.a
-rwxrwxr-x 1 riveraa riveraa 2.9M Dec 25 13:58 libiup_scintilla.so
-rw-rw-r-- 1 riveraa riveraa  29K Dec 25 13:47 libiupcd.a
-rwxrwxr-x 1 riveraa riveraa  30K Dec 25 13:47 libiupcd.so
-rw-rw-r-- 1 riveraa riveraa 614K Dec 25 13:47 libiupcontrols.a
-rwxrwxr-x 1 riveraa riveraa 331K Dec 25 13:47 libiupcontrols.so
-rw-rw-r-- 1 riveraa riveraa  22K Dec 25 13:47 libiupgl.a
-rwxrwxr-x 1 riveraa riveraa  24K Dec 25 13:47 libiupgl.so
-rw-rw-r-- 1 riveraa riveraa 247K Dec 25 13:47 libiupglcontrols.a
-rwxrwxr-x 1 riveraa riveraa 130K Dec 25 13:48 libiupglcontrols.so
-rw-rw-r-- 1 riveraa riveraa  17K Dec 25 13:58 libiupim.a
-rwxrwxr-x 1 riveraa riveraa  24K Dec 25 13:58 libiupim.so
-rw-rw-r-- 1 riveraa riveraa 286K Dec 25 13:58 libiupimglib.a
-rwxrwxr-x 1 riveraa riveraa 266K Dec 25 13:58 libiupimglib.so
-rw-rw-r-- 1 riveraa riveraa 309K Dec 25 13:59 libiuptuio.a
-rwxrwxr-x 1 riveraa riveraa 173K Dec 25 13:59 libiuptuio.so
-rw-rw-r-- 1 riveraa riveraa  20K Dec 25 13:58 libiupweb.a
-rwxrwxr-x 1 riveraa riveraa  26K Dec 25 13:58 libiupweb.so
riveraa@ubuntu:~/iup-dev/build$


Either you've made changes to the .mak file that broke stuff, or your build environment is not complete as far as the required development libraries go.

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 25, 2019, 12:31:17 PM
I used fresh unzips of the IUP/CD/IM/FTGL/LUA53 and used the two make files you posted.

I can try recompiling IUP again.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 25, 2019, 01:42:36 PM
This time I ran make from the root iup directory rather than src. It looks good.



ubuntu@rpi4b:~/iup-dev/iup/lib/Linux53_arm64$ ls -l
total 22172
drwxr-xr-x 2 ubuntu ubuntu    4096 Dec 25 13:37 Lua53
-rw-r--r-- 1 ubuntu ubuntu 2627956 Dec 25 13:23 libiup.a
-rwxr-xr-x 1 ubuntu ubuntu 1258520 Dec 25 13:23 libiup.so
-rw-r--r-- 1 ubuntu ubuntu 4819946 Dec 25 13:28 libiup_mglplot.a
-rwxr-xr-x 1 ubuntu ubuntu 2942288 Dec 25 13:28 libiup_mglplot.so
-rw-r--r-- 1 ubuntu ubuntu  490624 Dec 25 13:24 libiup_plot.a
-rwxr-xr-x 1 ubuntu ubuntu  299800 Dec 25 13:24 libiup_plot.so
-rw-r--r-- 1 ubuntu ubuntu 4603046 Dec 25 13:35 libiup_scintilla.a
-rwxr-xr-x 1 ubuntu ubuntu 3003640 Dec 25 13:35 libiup_scintilla.so
-rw-r--r-- 1 ubuntu ubuntu   29132 Dec 25 13:23 libiupcd.a
-rwxr-xr-x 1 ubuntu ubuntu   29856 Dec 25 13:23 libiupcd.so
-rw-r--r-- 1 ubuntu ubuntu  627932 Dec 25 13:24 libiupcontrols.a
-rwxr-xr-x 1 ubuntu ubuntu  338848 Dec 25 13:24 libiupcontrols.so
-rw-r--r-- 1 ubuntu ubuntu   21882 Dec 25 13:24 libiupgl.a
-rwxr-xr-x 1 ubuntu ubuntu   24056 Dec 25 13:24 libiupgl.so
-rw-r--r-- 1 ubuntu ubuntu  252126 Dec 25 13:24 libiupglcontrols.a
-rwxr-xr-x 1 ubuntu ubuntu  132872 Dec 25 13:24 libiupglcontrols.so
-rw-r--r-- 1 ubuntu ubuntu   16554 Dec 25 13:35 libiupim.a
-rwxr-xr-x 1 ubuntu ubuntu   23992 Dec 25 13:35 libiupim.so
-rw-r--r-- 1 ubuntu ubuntu  292404 Dec 25 13:35 libiupimglib.a
-rwxr-xr-x 1 ubuntu ubuntu  271600 Dec 25 13:35 libiupimglib.so
-rw-r--r-- 1 ubuntu ubuntu  315412 Dec 25 13:36 libiuptuio.a
-rwxr-xr-x 1 ubuntu ubuntu  176664 Dec 25 13:36 libiuptuio.so
-rw-r--r-- 1 ubuntu ubuntu   19950 Dec 25 13:35 libiupweb.a
-rwxr-xr-x 1 ubuntu ubuntu   25688 Dec 25 13:35 libiupweb.so
ubuntu@rpi4b:~/iup-dev/iup/lib/Linux53_arm64$

Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 25, 2019, 01:47:30 PM
That's where you're supposed to run make, otherwise it can't find what it needs.
BTW, your issue with NIUP is the compiler; you're using the bleeding edge version, which has a bunch of changes.
Using the stable version, the NIUP example compiles fine.  No changes required to the import.

Title: Re: RaspberryBASIC.org Forum
Post by: John on December 25, 2019, 02:29:30 PM
I was able to compile all the IUP Examples (https://github.com/dariolah/nim-iup-examples) from the repo.

Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 25, 2019, 02:40:59 PM
I wrote 8th entry for your GUI Login challenge:

Code: [Select]
requires gui

var gui

{ guest: "pa$$w0rd!" } constant passwords

: authenticate
  "edit1" g:child g:text? passwords swap m:@ nip null? if
    "User not found!" . cr
    2drop
  else
    swap
    "edit2" g:child g:text? nip s:= if
      "Authenticated!" . cr
      bye
    else
      "Username and password don't match!" . cr
    then
  then ;

{
  kind: "win",
  buttons: 5,
  title: "Login",
  wide: 360,
  high: 160,
  resizable: false,
  bg:"lightgray",
  center: true,
  init: ( gui ! ),
  children:
  [
    {
      kind: "box",
      name: "frame",
      bounds: "10, 10, parent.width-10, parent.height-10",
      bg: "gray",
      children:
      [
        {
          kind: "label",
          label: "Username:",
          bounds: "parent.left, parent.top+10, 80, top+24 ",
          name: "lbl1"
},
        {
          kind: "edit",
          bounds: "lbl1.right+10, lbl1.top, parent.width-10, top+24",
          name: "edit1",
          max-text: 32
        },
        {
          kind: "label",
          label: "Password:",
          bounds: "lbl1.left, lbl1.bottom+10, 80, top+24 ",
          name: "lbl2"
},
        {
          kind: "edit",
          bounds: "edit1.left, lbl2.top, parent.width-10, top+24",
          name: "edit2",
          max-text: 32,
          password-char: "*"
        },
        {
          kind: "btn",
          label: "Login",
          bg: "darkgray",
          bounds: "lbl2.left, lbl2.bottom+20, edit2.right, top+30",
          name: "button",
          tooltip: "Login to account",
          click: ' authenticate
        }
      ]
    }
  ]
} var, gui-desc

: app:main
  gui-desc @ g:new ;
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 25, 2019, 03:50:02 PM
Quote from: AIR
BTW, your issue with NIUP is the compiler; you're using the bleeding edge version, which has a bunch of changes.

I'm out of Band-Aids so I compiled Nim 1.0.4 from source.

Code: Text
  1. import niup
  2. import niupext
  3.  
  4. proc btn_exit_cb(ih:PIhandle):cint {.cdecl.}=
  5.   # Exits the main loop
  6.   return IUP_CLOSE
  7.  
  8. proc mainProc =
  9.   var dlg, button, label, vbox: PIhandle
  10.  
  11.   Open()
  12.  
  13.   label =  Label("Hello world from IUP.")
  14.   button = Button("OK", nil)
  15.  
  16.   vbox = Vbox(label, button, nil)
  17.   withPIhandle vbox:
  18.     "ALIGNMENT" "ACENTER"
  19.     "GAP"       "10"
  20.     "MARGIN"    "10x10"
  21.  
  22.   dlg = Dialog(vbox)
  23.   SetAttribute(dlg, "TITLE", "Hello World with callback")
  24.  
  25.   # Registers callbacks
  26.   SetCallback(button, "ACTION", btn_exit_cb)
  27.  
  28.   ShowXY(dlg, IUP_CENTER, IUP_CENTER)
  29.  
  30.   MainLoop()
  31.  
  32.   Close()
  33.  
  34. if isMainModule:
  35.   mainProc()
  36.  

The isxxxx const's are working again and so is with.

Title: Re: RaspberryBASIC.org Forum
Post by: John on December 26, 2019, 05:03:58 PM
Here is a preview of what the ScriptBasic login submission will look like. I'm cleaning up the code and will post it on the Raspberry BASIC forum soon.



Title: Re: RaspberryBASIC.org Forum
Post by: John on December 26, 2019, 07:35:50 PM
AIR,

The only issue I have with my submission is IUP isn't toggling the password text box when I change the "PASSWORD" attribute. It's like once it's set as a password text box that is what it remains.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 26, 2019, 07:43:53 PM
Don't know what to tell you, I don't use IUP.

Here's my almost finished version 1.1  using C and GTK3....
AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 26, 2019, 08:34:29 PM
Code: C
  1. /* logon2.c
  2.  *
  3.  * version 1.1
  4.  *
  5.  * GUI Logon Screen Challenge Submission
  6.  * C version, using GTK+-3.0
  7.  *
  8.  * Written by Armando I. Rivera (AIR)
  9.  *
  10.  * Compile:  gcc logon2.c $(pkg-config --libs --cflags gtk+-3.0) -o logon2
  11. */
  12.  
  13.  
  14. #include <gtk/gtk.h>
  15.  
  16. GtkWidget *err_label;
  17.  
  18. void onClick( GtkWidget *widget, gpointer   data ) {
  19.     gchar *stupid_password = "pa$$w0rd!";
  20.     gchar *user_password;
  21.     g_object_get(data,"text",&user_password,NULL);
  22.  
  23.     if (g_strcmp0 (stupid_password,user_password) == 0) {
  24.         g_print("Your are now logged in!\n");
  25.         gtk_main_quit();
  26.     }else{
  27.         gtk_label_set_markup(GTK_LABEL(err_label), "<span color=\"red\" font_desc=\"16.0\">** Invalid Password **</span>");
  28.         g_print("Username or Password is Incorrect!\n");
  29.  
  30.     }
  31. }
  32.  
  33. int main( int argc, char *argv[])
  34. {
  35.     GtkWidget *window, *layout, *image, *btnLogin;
  36.     GtkWidget *lblUser, *lblPass, *txtUser, *txtPass;
  37.  
  38.     gtk_init(&argc, &argv);
  39.    
  40.     layout = gtk_layout_new(NULL, NULL);
  41.  
  42.     window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  43.     g_object_set(window,
  44.                 "title","Login",
  45.                 "default-width",660,
  46.                 "default-height",370,
  47.                 "resizable",FALSE,
  48.                 "window-position",GTK_WIN_POS_CENTER,
  49.                 "child",layout,
  50.                 "decorated",0,
  51.                 NULL);
  52.  
  53.  
  54.     image = gtk_image_new_from_file("logon.png");
  55.     g_object_set(layout,"child",image,"margin",10,NULL);
  56.    
  57.     lblUser = gtk_label_new("");
  58.     lblPass = gtk_label_new("");
  59.     err_label = gtk_label_new("");
  60.     g_object_set(err_label,"width-request",270,NULL);
  61.    
  62.     gtk_label_set_markup(GTK_LABEL(lblUser), "<span font_desc=\"16.0\">Username:</span>");
  63.     gtk_label_set_markup(GTK_LABEL(lblPass), "<span font_desc=\"16.0\">Password:</span>");
  64.    
  65.     txtUser = gtk_entry_new();
  66.     txtPass = gtk_entry_new();
  67.    
  68.    
  69.     g_object_set(txtPass,"visibility", FALSE,NULL);
  70.    
  71.     btnLogin = gtk_button_new_with_label("Login");
  72.     g_object_set(btnLogin,"width-request",170,NULL);
  73.  
  74.  
  75.     gtk_layout_put(GTK_LAYOUT(layout), lblUser, 330, 112);
  76.     gtk_layout_put(GTK_LAYOUT(layout), lblPass, 330, 162);
  77.     gtk_layout_put(GTK_LAYOUT(layout), txtUser, 460, 110);
  78.     gtk_layout_put(GTK_LAYOUT(layout), txtPass, 460, 160);
  79.     gtk_layout_put(GTK_LAYOUT(layout), btnLogin, 460, 210);
  80.     gtk_layout_put(GTK_LAYOUT(layout), err_label, 300, 16);
  81.  
  82.     g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
  83.     g_signal_connect (btnLogin, "clicked", G_CALLBACK (onClick), txtPass);
  84.  
  85.     gtk_widget_show_all(window);
  86.  
  87.     gtk_main();
  88.  
  89.     return 0;
  90. }
  91.  
  92.  

Source and graphic attached in archive below....

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 26, 2019, 08:58:13 PM
AIR,

The only issue I have with my submission is IUP isn't toggling the password text box when I change the "PASSWORD" attribute. It's like once it's set as a password text box that is what it remains.

Going back to my Hotbasic and BCX Linux days, when I was neck deep in the GTK implementation for both, I recall that whenever you changed attributes like this you needed to tell the library to redraw the objects/form in order to show the up-to-date representation.

I don't know how you would do that with IUP, but since it's using the GTK backend, there should be a function call that does this.

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 26, 2019, 09:33:50 PM
Nice thought but didn't work.

Code: Script BASIC
  1. SUB show_password
  2.   showcb = Iup::GetAttribute(showpwd, "VALUE")
  3.   IF showcb = "ON" THEN
  4.     Iup::SetAttribute(pwdtxt, "PASSWORD", "NO")
  5.     Iup::Refresh(pwdtxt)
  6.   ELSE
  7.     Iup::SetAttribute(pwdtxt, "PASSWORD", "YES")
  8.     Iup::Refresh(pwdtxt)
  9.   END IF
  10. END SUB
  11.  
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 26, 2019, 09:52:39 PM
You may want to try this in C to see if there's a problem with the library or your implemented interface...
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 27, 2019, 05:42:41 AM
I think I this is a bug. I'll ask Antonio to look into it.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 27, 2019, 07:23:08 AM
I posted an issue on the niup repo and the maintainer responded.

Quote from: Dario Lah@niup repo
I'm not following devel branch, only stable releases of Nim.

First issue looks like it could be fixed with new c2nim, problem code is result of c2nim.

Second is possibly because of changes in macros API, I need changelog for Nim.

Once there is new stable Nim release, I'll update NIUP.

Thank you for notice
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 27, 2019, 08:16:28 AM
Response from Antonio.

Quote
  Hi,


PASSWORD (creation only) [Windows and GTK Only] (non inheritable): Hide the typed character using an "*". Default: "NO".


  creation only means it can not be changed after the native element is created.


  My suggestion is for you to use a zbox with two IupText, then switch between them when the password is necessary.


Best,

Scuri
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 27, 2019, 01:56:27 PM
Here is my login gui updated to match recent entries:

Code: [Select]
requires gui

var gui

{ guest: "pa$$w0rd!" } constant passwords

: authenticate
  "edit1" g:child g:text? passwords swap m:@ nip null? if
    drop
    "lbl0" g:child
    "User not found!" g:text drop
  else
    swap
    "edit2" g:child g:text? rot s:= if
     "Authenticated!" . cr
     bye
    else
      "lbl0" g:child
      "Username and password don't match!" g:text drop
    then
  then ;

{
  kind: "win",
  buttons: 0,
  native-title-bar: false,
  title: "Login",
  wide: 520,
  high: 200,
  resizable: false,
  center: true,
  init: ( gui ! ),
  children:
  [
    {
      kind: "box",
      name: "frame",
      bounds: "0, 0, parent.width, parent.height",
      bg: "gray",
      children:
      [
        {
          kind: "image",
          bounds: "parent.left+10, parent.top+10, left+128, top+128",
          img: "8thlogo.png",
          name: "logo"     
        },
        {
          kind: "label",
          fg: "blue",
          font: 20,
          label: "",
          bounds: "logo.right+20, parent.top+10, parent.width-10, top+24 ",
          justify: ["hcenter"],
          name: "lbl0"
},
        {
          kind: "label",
          label: "Username:",
          bounds: "logo.right+20, lbl0.bottom+20, left+80, top+24 ",
          name: "lbl1"
},
        {
          kind: "edit",
          bounds: "lbl1.right+10, lbl1.top, parent.width-20, top+24",
          name: "edit1",
          max-text: 32
        },
        {
          kind: "label",
          label: "Password:",
          bounds: "lbl1.left, lbl1.bottom+10, left+80, top+24",
          name: "lbl2"
},
        {
          kind: "edit",
          bounds: "edit1.left, lbl2.top, parent.width-20, top+24",
          name: "edit2",
          max-text: 32,
          password-char: "*"
        },
        {
          kind: "btn",
          label: "Login",
          bg: "darkgray",
          bounds: "lbl2.left, lbl2.bottom+20, edit2.right, top+30",
          name: "button",
          tooltip: "Login to account",
          click: ' authenticate
        }
      ]
    }
  ]
} var, gui-desc

: app:main
  gui-desc @ g:new ;
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 27, 2019, 03:56:01 PM
Response from Antonio.

Quote
  Hi,


PASSWORD (creation only) [Windows and GTK Only] (non inheritable): Hide the typed character using an "*". Default: "NO".


  creation only means it can not be changed after the native element is created.


  My suggestion is for you to use a zbox with two IupText, then switch between them when the password is necessary.


Best,

Scuri

That's an implementation choice, at least as far as GTK is concerned.

Consider:

Code: C
  1. #include <gtk/gtk.h>
  2.  
  3. GtkWidget *mainwin, *txtEntry, *chkBox, *layout;
  4.  
  5. void toggled_cb (GtkToggleButton *toggle_button, gpointer  user_data) {
  6.       if (gtk_toggle_button_get_active (toggle_button)) {
  7.           g_object_set(user_data,"visibility",TRUE,NULL);
  8.       }else{
  9.           g_object_set(user_data,"visibility",FALSE,NULL);
  10.       }
  11.    
  12. }
  13.  
  14. int main(int argc, char **argv) {
  15.    
  16.     gtk_init(&argc, &argv);
  17.    
  18.     mainwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  19.     layout = gtk_layout_new(NULL, NULL);
  20.     g_object_set(mainwin,
  21.                 "title","Visible Password Toggle",
  22.                 "default-width",660,
  23.                 "default-height",370,
  24.                 "resizable",FALSE,
  25.                 "window-position",GTK_WIN_POS_CENTER,
  26.                 "child",layout,
  27.                 NULL);
  28.  
  29.     txtEntry = gtk_entry_new();
  30.     g_object_set(txtEntry,"text","mypassword","visibility",FALSE,NULL);
  31.    
  32.     chkBox = gtk_check_button_new_with_label("Show Password");
  33.     g_object_set(layout,"child",txtEntry,"margin",10,NULL);
  34.  
  35.     gtk_layout_put(GTK_LAYOUT(layout), chkBox, 0, 40);
  36.    
  37.     gtk_widget_show_all(mainwin);
  38.  
  39.     g_signal_connect (mainwin, "destroy", G_CALLBACK (gtk_main_quit), NULL);
  40.     g_signal_connect (chkBox, "toggled", G_CALLBACK (toggled_cb), txtEntry);
  41.    
  42.     gtk_main();
  43.  
  44.     return 0;
  45. }
  46.  
  47.  

In your interface, you should be able to grab the native GTK widget and toggle it's visibility flag...IUP remains as Antonio et al coded it, and you "extend" it in your interface in order to achieve the desired functionality...

Of course, if he's running his own event loop and hooking it into GTK's event loop, this may not work depending on how he hooks into GTK's event loop...


AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 27, 2019, 06:43:26 PM
The zbox.c example demonstrates what I'm trying to accomplish.

Let's see if I can make Antonio's concept work.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 27, 2019, 08:09:22 PM
Did this one on my Mac, using BlitzMax (there's no arm64 version available yet)

Code: Text
  1. Strict
  2.  
  3. Import MaxGUI.Drivers
  4.  
  5. Local window:    TGadget    =     CreateWindow("Logon",40,40,440,150,Null,WINDOW_TITLEBAR | WINDOW_CENTER)
  6. Local logo:        TGadget    =    CreatePanel(6,6,119,100, window)
  7. Local image:    TPixmap    =    LoadPixmap("login.png")
  8. Local lblUser:    TGadget    =     CreateLabel("Username:",110,16,90,22,window)
  9. Local txtUser:    TGadget    =    CreateTextField(190,16,240,22,window)
  10. Local lblPass:    TGadget    =     CreateLabel("Password:",110,48,90,22,window)
  11. Local txtPass:    TGadget    =    CreateTextField(190,48,240,22,window,TEXTFIELD_PASSWORD)
  12. Local btnLogin:    TGadget    =     CreateButton("Login",190,80,240,22,window)
  13. Local lblErr:    TGadget    =     CreateLabel("",126,100,260,60,window)
  14.  
  15. SetPanelPixmap logo,image
  16. SetGadgetFont(lblErr,LookupGuiFont(GUIFONT_SYSTEM,18,FONT_BOLD))
  17. SetGadgetColor(lblErr,255,0,0,False)
  18.  
  19. While True
  20.    WaitEvent
  21.    Select EventID()
  22.        Case EVENT_WINDOWCLOSE,EVENT_APPTERMINATE
  23.            End
  24.        Case EVENT_GADGETACTION
  25.            Select EventSource()
  26.             Case btnLogin
  27.                 Local user_password:String = GadgetText(txtPass)
  28.                 Local stupid_password:String = "pa$$w0rd!"
  29.                
  30.                 If user_password = stupid_password
  31.                     End
  32.                 Else
  33.                     SetGadgetText(lblErr,"** Invalid Password **")
  34.                 EndIf
  35.                
  36.             Case txtPass
  37.                 SetGadgetText(lblErr,"")                
  38.  
  39.            EndSelect
  40.    End Select
  41. Wend


If you enter the wrong password, when you go to re-enter it, the warning message goes away.... 8)

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 27, 2019, 08:36:50 PM
I was able to get the show/hide password working correctly.

If you want to  give this a try, I attached everything you need to do so.

Code: Script BASIC
  1. ' ScriptBasic / IUP - Login - JRS
  2.  
  3. IMPORT iup.bas
  4.  
  5. SUB login_clicked
  6.   uid = Iup::GetAttribute(uidtxt,"VALUE")
  7.   IF Iup::GetAttribute(showpwd, "VALUE") = "OFF" THEN
  8.     pwd = Iup::GetAttribute(pwdtxt1,"VALUE")
  9.   ELSE
  10.     pwd = Iup::GetAttribute(pwdtxt2,"VALUE")
  11.   END IF
  12.   IF uid = "John" AND pwd = "Spikowski" THEN
  13.     Iup::Hide(errlbl)
  14.     Iup::Message("Login",  "Login Successful")
  15.     Iup::ExitLoop = TRUE
  16.   ELSE
  17.     Iup::Show(errlbl)
  18.     Iup::SetFocus(uidtxt)
  19.   END IF
  20. END SUB
  21.  
  22. SUB show_password
  23.   showcb = Iup::GetAttribute(showpwd, "VALUE")
  24.   IF showcb = "OFF" THEN
  25.     pwd2 = Iup::GetAttribute(pwdtxt2,"VALUE")
  26.     Iup::SetAttribute(pwdtxt1, "VALUE", pwd2)
  27.     Iup::SetAttribute(zbtxt, "VALUE", "pwdtxt1")
  28.   ELSE
  29.     pwd1 = Iup::GetAttribute(pwdtxt1,"VALUE")
  30.     Iup::SetAttribute(pwdtxt2, "VALUE", pwd1)
  31.     Iup::SetAttribute(zbtxt, "VALUE", "pwdtxt2")
  32.   END IF
  33. END SUB
  34.  
  35. SUB Win_exit
  36.   Iup::ExitLoop = TRUE
  37. END SUB
  38.  
  39. Iup::Open()
  40. dlg = Iup::Create("dialog")
  41. Iup::SetAttributes(dlg, "TITLE=\"Login\", SIZE=200x200")
  42.  
  43. vb = Iup::Create("vbox")
  44. hb1 = Iup::Create("hbox")
  45. piclbl = Iup::Create("label")
  46. Iup::SetAttribute(piclbl, "IMAGE", "./login.png")
  47. Iup::SetAttribute(piclbl, "EXPAND", "HORIZONTAL")
  48. Iup::SetAttribute(piclbl, "ALIGNMENT", "ACENTER:ATOP")
  49. Iup::Append(hb1, piclbl)
  50. Iup::Append(vb, hb1)
  51.  
  52. hb2 = Iup::Create("hbox")
  53. errlbl = Iup::Create("label")
  54. Iup::SetAttribute(errlbl, "TITLE", "User ID / Password Incorrect")
  55. Iup::SetAttribute(errlbl, "FGCOLOR", "#ff0000")
  56. Iup::SetAttribute(errlbl, "EXPAND", "HORIZONTAL")
  57. Iup::SetAttribute(errlbl, "ALIGNMENT", "ACENTER")
  58. Iup::Hide(errlbl)
  59. Iup::Append(hb2, errlbl)
  60. Iup::Append(vb, hb2)
  61.  
  62. hb3 = Iup::Create("hbox")
  63. Iup::SetAttribute(hb3, "MARGIN", "20x10")
  64. Iup::SetAttribute(hb3, "GAP", "5")
  65. vb1 = Iup::Create("vbox")
  66. Iup::SetAttribute(vb1, "GAP", "15")
  67. uidlbl = Iup::Create("label")
  68. Iup::SetAttribute(uidlbl, "TITLE", "User ID")
  69. Iup::Append(vb1, uidlbl)
  70. pwdlbl = Iup::Create("label")
  71. Iup::SetAttribute(pwdlbl, "TITLE", "Password")
  72. Iup::Append(vb1, pwdlbl)
  73. Iup::Append(hb3, vb1)
  74. vb2 = Iup::Create("vbox")
  75. uidtxt = Iup::Create("text")
  76. Iup::SetAttribute(uidtxt, "SIZE", "85x")
  77. Iup::Append(vb2, uidtxt)
  78. pwdtxt1 = Iup::Create("text")
  79. Iup::SetAttribute(pwdtxt1, "PASSWORD", "YES")
  80. Iup::SetAttribute(pwdtxt1, "SIZE", "85x")
  81. pwdtxt2 = Iup::Create("text")
  82. Iup::SetAttribute(pwdtxt2, "SIZE", "85x")
  83. Iup::SetHandle ("pwdtxt1", pwdtxt1)
  84. Iup::SetHandle ("pwdtxt2", pwdtxt2)
  85. zbtxt = Iup::Zbox(pwdtxt1, pwdtxt2)
  86. Iup::SetHandle("zbtxt", zbtxt)
  87. Iup::Append(vb2, zbtxt)
  88. Iup::Append(hb3, vb2)
  89. Iup::Append(vb, hb3)
  90.  
  91. hb4 = Iup::Create("hbox")
  92. Iup::SetAttribute(hb4, "MARGIN", "35x")
  93. showpwd = Iup::Create("toggle")
  94. Iup::SetAttribute(showpwd, "TITLE", "Show Password?")
  95. Iup::SetAttribute(showpwd, "CANFOCUS", "NO")
  96. Iup::Append(hb4, showpwd)
  97. Iup::Append(vb, hb4)
  98.  
  99. hb5 = Iup::Create("hbox")
  100. Iup::SetAttribute(hb5, "MARGIN", "40x10")
  101. loginbut = Iup::Create("button")
  102. Iup::SetAttribute(loginbut, "TITLE", "Login")
  103. Iup::SetAttribute(loginbut, "EXPAND", "HORIZONTAL")
  104. iup::Append(hb5, loginbut)
  105. iup::Append(vb, hb5)
  106.  
  107. iup::Append(dlg, vb)
  108.  
  109. Iup::SetCallback(dlg,"CLOSE_CB",ADDRESS(Win_exit()))
  110. Iup::SetCallback(loginbut, "ACTION", ADDRESS(login_clicked()))
  111. Iup::SetCallback(showpwd, "ACTION", ADDRESS(show_password()))
  112.  
  113. Iup::Show(dlg)
  114. Iup::MainLoop()
  115. Iup::Close()
  116.  

Title: Re: RaspberryBASIC.org Forum
Post by: John on December 27, 2019, 09:50:39 PM
It would be great to make the password hide/show as part of the challenge requirements. It's an interesting twist.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 28, 2019, 06:36:46 PM
AIR,

Do you know how to  make Nim variables global?

It says it can find uidtxt in the callback.

Code: Text
  1. import niup
  2. import niupext
  3.  
  4. proc login_clicked(ih:PIhandle):cint {.cdecl.}=
  5.   let uid = GetAttribute(uidtxt,"VALUE")
  6.   if GetAttribute(showpwd, "VALUE") == "OFF":
  7.     let pwd = GetAttribute(pwdtxt1,"VALUE")
  8.   else:
  9.     let pwd = GetAttribute(pwdtxt2,"VALUE")
  10.  
  11.   if uid == "John" and pwd == "Spikowski":
  12.     Hide(errlbl)
  13.     Message("Login",  "Login Successful")
  14.     return IUP_CLOSE
  15.   else:
  16.     Show(errlbl)
  17.     SetFocus(uidtxt)
  18.  
  19. Open()
  20.  
  21. # *** DIALOG ***
  22. let dlg = Create("dialog")
  23. SetAttributes(dlg,
  24.   "TITLE=\"Login\", " &
  25.   "SIZE=200x200, " &
  26.   "MAXBOX=NO, " &
  27.   "MINBOX=NO, " &
  28.   "RESIZE=NO")
  29.  
  30. # *** CONTAINER ***
  31. let vb = Create("vbox")
  32.  
  33. # *** IMAGE ***
  34. let hb1 = Create("hbox")
  35. let piclbl = Create("label")
  36. SetAttributes(piclbl,  
  37.   "IMAGE=\"login.png\", " &
  38.   "EXPAND=HORIZONTAL, " &
  39.   "ALIGNMENT=ACENTER:ATOP")
  40. discard Append(hb1, piclbl)
  41. discard Append(vb, hb1)
  42.  
  43. # *** ERROR ***
  44. let hb2 = Create("hbox")
  45. let errlbl = Create("label")
  46. SetAttributes(errlbl,
  47.   "TITLE=\"User ID / Password Incorrect\", " &
  48.   "FGCOLOR=\"#ff0000\", " &
  49.   "EXPAND=HORIZONTAL, " &
  50.   "ALIGNMENT=ACENTER")
  51. # Hide(errlbl)
  52. discard Append(hb2, errlbl)
  53. discard Append(vb, hb2)
  54.  
  55. # *** ENTRY ***
  56. let hb3 = Create("hbox")
  57. SetAttributes(hb3,
  58.   "MARGIN=20x10, " &
  59.   "GAP=5")
  60. let vb1 = Create("vbox")
  61. SetAttribute(vb1, "GAP", "15")
  62. let uidlbl = Create("label")
  63. SetAttribute(uidlbl, "TITLE", "User ID")
  64. discard Append(vb1, uidlbl)
  65. let pwdlbl = Create("label")
  66. SetAttribute(pwdlbl, "TITLE", "Password")
  67. discard Append(vb1, pwdlbl)
  68. discard Append(hb3, vb1)
  69. let vb2 = Create("vbox")
  70. let uidtxt = Create("text")
  71. SetAttribute(uidtxt, "SIZE", "85x")
  72. discard Append(vb2, uidtxt)
  73. let pwdtxt1 = Create("text")
  74. SetAttributes(pwdtxt1,
  75.   "PASSWORD=YES, " &
  76.   "SIZE=85x")
  77. let pwdtxt2 = Create("text")
  78. SetAttribute(pwdtxt2, "SIZE", "85x")
  79. SetHandle("pwdtxt1", pwdtxt1)
  80. SetHandle("pwdtxt2", pwdtxt2)
  81. let zbtxt = Zbox(pwdtxt1, pwdtxt2, nil)
  82. SetHandle("zbtxt", zbtxt)
  83. discard Append(vb2, zbtxt)
  84. discard Append(hb3, vb2)
  85. discard Append(vb, hb3)
  86.  
  87. # *** SHOW/HIDE ***
  88. let hb4 = Create("hbox")
  89. SetAttribute(hb4, "MARGIN", "35x")
  90. let showpwd = Create("toggle")
  91. SetAttributes(showpwd,
  92.   "TITLE=\"Show Password?\", " &
  93.   "CANFOCUS=NO")
  94. discard Append(hb4, showpwd)
  95. discard Append(vb, hb4)
  96.  
  97. # *** LOGIN ***
  98. let hb5 = Create("hbox")
  99. SetAttribute(hb5, "MARGIN", "40x10")
  100. let loginbut = Create("button")
  101. SetAttributes(loginbut,
  102.   "TITLE=\"Login\", " &
  103.   "EXPAND=HORIZONTAL")
  104. discard Append(hb5, loginbut)
  105. discard Append(vb, hb5)
  106.  
  107. # *** ATTACH CONTAINER ***
  108. discard Append(dlg, vb)
  109.  
  110. ' *** CALLBACKS ***
  111. SetCallback(loginbut, "ACTION", login_clicked)
  112. SetCallback(showpwd, "ACTION", show_password)
  113.  
  114. # *** PROCESS ***
  115. Show(dlg)
  116. MainLoop()
  117. Close()
  118.  
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 28, 2019, 06:37:54 PM
If we're going to add toggling the visibility of the password as a 'requirement', we should also add the password box reacting to the "Enter/Return" key.

Code: C
  1. /* logon2.c
  2.  *
  3.  * version 1.2
  4.  *
  5.  * GUI Logon Screen Challenge Submission
  6.  * C version, using GTK+-3.0
  7.  *
  8.  * Written by Armando I. Rivera (AIR)
  9.  *
  10.  * Compile:  gcc logon2.c $(pkg-config --libs --cflags gtk+-3.0) -o logon2
  11. */
  12.  
  13. #include <gtk/gtk.h>
  14.  
  15. GtkWidget *err_label;
  16.  
  17. void chkBox_cb (GtkToggleButton *toggle_button, gpointer data) {
  18.       if (gtk_toggle_button_get_active (toggle_button)) {
  19.           g_object_set(data,"visibility",TRUE,NULL);
  20.       }else{
  21.           g_object_set(data,"visibility",FALSE,NULL);
  22.       }
  23. }
  24.  
  25. void txtPass_cb( GtkWidget *widget, gpointer data ) {
  26.     g_object_set(data,"label","",NULL);
  27. }
  28.  
  29. void onClick( GtkWidget *widget, gpointer data ) {
  30.     gchar *stupid_password = "pa$$w0rd!";
  31.     gchar *user_password;
  32.     g_object_get(data,"text",&user_password,NULL);
  33.  
  34.     if (g_strcmp0 (stupid_password,user_password) == 0) {
  35.         g_print("Your are now logged in!\n");
  36.         gtk_main_quit();
  37.     }else{
  38.         gtk_label_set_markup(GTK_LABEL(err_label), "<span color=\"red\" font_desc=\"16.0\">** Invalid Password **</span>");
  39.         g_print("Username or Password is Incorrect!\n");
  40.  
  41.     }
  42. }
  43.  
  44. int main( int argc, char *argv[])
  45. {
  46.     GtkWidget *window, *layout, *image, *btnLogin, *chkBox;
  47.     GtkWidget *lblUser, *lblPass, *txtUser, *txtPass;
  48.  
  49.     gtk_init(&argc, &argv);
  50.    
  51.     layout = gtk_layout_new(NULL, NULL);
  52.  
  53.     window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  54.     g_object_set(window,
  55.                 "title","Login",
  56.                 "default-width",660,
  57.                 "default-height",370,
  58.                 "resizable",FALSE,
  59.                 "window-position",GTK_WIN_POS_CENTER,
  60.                 "child",layout,
  61.                 "decorated",0,
  62.                 NULL);
  63.  
  64.  
  65.     image = gtk_image_new_from_file("logon.png");
  66.     g_object_set(layout,"child",image,"margin",10,NULL);
  67.    
  68.     lblUser = gtk_label_new("");
  69.     lblPass = gtk_label_new("");
  70.     err_label = gtk_label_new("");
  71.     g_object_set(err_label,"width-request",270,NULL);
  72.    
  73.     gtk_label_set_markup(GTK_LABEL(lblUser), "<span font_desc=\"16.0\">Username:</span>");
  74.     gtk_label_set_markup(GTK_LABEL(lblPass), "<span font_desc=\"16.0\">Password:</span>");
  75.    
  76.     txtUser = gtk_entry_new();
  77.     txtPass = gtk_entry_new();    
  78.     g_object_set(txtPass,"visibility", FALSE,NULL);
  79.    
  80.     chkBox = gtk_check_button_new_with_label("Show Password");
  81.  
  82.     btnLogin = gtk_button_new_with_label("Login");
  83.     g_object_set(btnLogin,"width-request",170,NULL);
  84.  
  85.  
  86.     gtk_layout_put(GTK_LAYOUT(layout), lblUser, 330, 112-30);
  87.     gtk_layout_put(GTK_LAYOUT(layout), lblPass, 330, 162-30);
  88.     gtk_layout_put(GTK_LAYOUT(layout), txtUser, 460, 110-30);
  89.     gtk_layout_put(GTK_LAYOUT(layout), txtPass, 460, 160-30);
  90.     gtk_layout_put(GTK_LAYOUT(layout), chkBox, 460, 210-30);
  91.     gtk_layout_put(GTK_LAYOUT(layout), btnLogin, 460, 250-30);
  92.     gtk_layout_put(GTK_LAYOUT(layout), err_label, 300, 16);
  93.  
  94.     g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
  95.     g_signal_connect (btnLogin, "clicked", G_CALLBACK (onClick), txtPass);
  96.     g_signal_connect (chkBox, "toggled", G_CALLBACK (chkBox_cb), txtPass);
  97.     g_signal_connect (txtPass, "changed", G_CALLBACK (txtPass_cb), err_label);
  98.     g_signal_connect (txtPass, "activate", G_CALLBACK (onClick), txtPass);
  99.    
  100.     gtk_widget_show_all(window);
  101.  
  102.     gtk_main();
  103.  
  104.     return 0;
  105. }
  106.  
  107.  
  108.  

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 28, 2019, 07:44:51 PM
AIR,

Do you know how to  make Nim variables global?

It says it can find uidtxt in the callback.

You have to declare them before the call to Open(), removing the 'let' from the declared variables.  You can either declare them before the callback, or forward declare the callback and move it to the end of the code.

Something like:

Code: Text
  1. import niup
  2. import niupext
  3.  
  4. var uidtxt,showpwd,pwdtxt1,pwdtxt2,errlbl:PIhandle
  5. proc login_clicked(ih:PIhandle):cint {.cdecl.}
  6.  
  7. Open()
  8.  
  9. # *** DIALOG ***
  10. let dlg = Create("dialog")
  11. SetAttributes(dlg,
  12.   "TITLE=\"Login\", " &
  13.   "SIZE=200x200, " &
  14.   "MAXBOX=NO, " &
  15.   "MINBOX=NO, " &
  16.   "RESIZE=NO")
  17.  
  18. # *** CONTAINER ***
  19. let vb = Create("vbox")
  20.  
  21. # *** IMAGE ***
  22. let hb1 = Create("hbox")
  23. let piclbl = Create("label")
  24. SetAttributes(piclbl,  
  25.   "IMAGE=\"login.png\", " &
  26.   "EXPAND=HORIZONTAL, " &
  27.   "ALIGNMENT=ACENTER:ATOP")
  28. discard Append(hb1, piclbl)
  29. discard Append(vb, hb1)
  30.  
  31. # *** ERROR ***
  32. let hb2 = Create("hbox")
  33. errlbl = Create("label")
  34. SetAttributes(errlbl,
  35.   "TITLE=\"User ID / Password Incorrect\", " &
  36.   "FGCOLOR=\"#ff0000\", " &
  37.   "EXPAND=HORIZONTAL, " &
  38.   "ALIGNMENT=ACENTER")
  39. # Hide(errlbl)
  40. discard Append(hb2, errlbl)
  41. discard Append(vb, hb2)
  42.  
  43. # *** ENTRY ***
  44. let hb3 = Create("hbox")
  45. SetAttributes(hb3,
  46.   "MARGIN=20x10, " &
  47.   "GAP=5")
  48. let vb1 = Create("vbox")
  49. SetAttribute(vb1, "GAP", "15")
  50. let uidlbl = Create("label")
  51. SetAttribute(uidlbl, "TITLE", "User ID")
  52. discard Append(vb1, uidlbl)
  53. let pwdlbl = Create("label")
  54. SetAttribute(pwdlbl, "TITLE", "Password")
  55. discard Append(vb1, pwdlbl)
  56. discard Append(hb3, vb1)
  57. let vb2 = Create("vbox")
  58. uidtxt = Create("text")
  59. SetAttribute(uidtxt, "SIZE", "85x")
  60. discard Append(vb2, uidtxt)
  61. pwdtxt1 = Create("text")
  62. SetAttributes(pwdtxt1,
  63.   "PASSWORD=YES, " &
  64.   "SIZE=85x")
  65. pwdtxt2 = Create("text")
  66. SetAttribute(pwdtxt2, "SIZE", "85x")
  67. SetHandle("pwdtxt1", pwdtxt1)
  68. SetHandle("pwdtxt2", pwdtxt2)
  69. let zbtxt = Zbox(pwdtxt1, pwdtxt2, nil)
  70. SetHandle("zbtxt", zbtxt)
  71. discard Append(vb2, zbtxt)
  72. discard Append(hb3, vb2)
  73. discard Append(vb, hb3)
  74.  
  75. # *** SHOW/HIDE ***
  76. let hb4 = Create("hbox")
  77. SetAttribute(hb4, "MARGIN", "35x")
  78. showpwd = Create("toggle")
  79. SetAttributes(showpwd,
  80.   "TITLE=\"Show Password?\", " &
  81.   "CANFOCUS=NO")
  82. discard Append(hb4, showpwd)
  83. discard Append(vb, hb4)
  84.  
  85. # *** LOGIN ***
  86. let hb5 = Create("hbox")
  87. SetAttribute(hb5, "MARGIN", "40x10")
  88. let loginbut = Create("button")
  89. SetAttributes(loginbut,
  90.   "TITLE=\"Login\", " &
  91.   "EXPAND=HORIZONTAL")
  92. discard Append(hb5, loginbut)
  93. discard Append(vb, hb5)
  94.  
  95. # *** ATTACH CONTAINER ***
  96. discard Append(dlg, vb)
  97.  
  98. # *** CALLBACKS ***
  99. SetCallback(loginbut, "ACTION", login_clicked)
  100. #~ SetCallback(showpwd, "ACTION", show_password)
  101.  
  102. # *** PROCESS ***
  103. Show(dlg)
  104. MainLoop()
  105. Close()
  106.  
  107. proc login_clicked(ih:PIhandle):cint {.cdecl.} =
  108.   var pwd:cstring
  109.   let uid = GetAttribute(uidtxt,"VALUE")
  110.   if GetAttribute(showpwd, "VALUE") == "OFF":
  111.     pwd = GetAttribute(pwdtxt1,"VALUE")
  112.   else:
  113.     pwd = GetAttribute(pwdtxt2,"VALUE")
  114.  
  115.   if uid == "John" and pwd == "Spikowski":
  116.     Hide(errlbl)
  117.     Message("Login",  "Login Successful")
  118.     return IUP_CLOSE
  119.   else:
  120.     Show(errlbl)
  121.     SetFocus(uidtxt)
  122.  
  123.  

Nim has a '{.global.}' pragma, but it essentially functions like the 'static' keyword does in C.  Won't work in this case, because it looks like the call to 'Open' sets up a proc so the variables are local to that but 'static' as in C.


Title: Re: RaspberryBASIC.org Forum
Post by: John on December 28, 2019, 08:18:56 PM
That worked.

Thanks.

I'm spoiled by SB not having to declare anything.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 29, 2019, 05:03:15 AM
I agree that one should be able to hit the return key to tab from User ID to Password and to the login button.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 29, 2019, 02:45:32 PM
Nim Changes

I'm using the state argument returned from the toggle callback rather than using GetAttribute to obtain it. The ENTER key now defaults to clicking the Login button if pressed.

ScriptBasic Changes

The ENTER key now defaults to clicking the Login button if pressed.

I think I'm going to give Nim a try on Windows 10. My hope is to get IUP and COM / OLE working on that platform.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 29, 2019, 04:52:52 PM
C CHANGES
Switched from using gtk_*_new for each object type, to g_object_new, which eliminates the need for g_object_set() for setting the widget properties.

Pressing "Enter" in the "Username" text box will move the focus to the "Password" text box, which in turn will execute the "onClick" callback when enter is pressed in the "Password" text box.

Code: C
  1. /* logon2.c
  2.  *
  3.  * version 1.3
  4.  *
  5.  * GUI Logon Screen Challenge Submission
  6.  * C version, using GTK+-3.0
  7.  *
  8.  * Written by Armando I. Rivera (AIR)
  9.  *
  10.  * Compile:  gcc logon2.c $(pkg-config --libs --cflags gtk+-3.0) -o logon2
  11. */
  12.  
  13. #include <gtk/gtk.h>
  14.  
  15.  
  16. GtkWidget *err_label;
  17.  
  18. void chkBox_cb (GtkToggleButton *toggle_button, gpointer data) {
  19.       if (gtk_toggle_button_get_active (toggle_button)) {
  20.           g_object_set(data,"visibility",TRUE,NULL);
  21.       }else{
  22.           g_object_set(data,"visibility",FALSE,NULL);
  23.       }
  24. }
  25.  
  26. void txtPass_cb( GtkWidget *widget, gpointer data ) {
  27.     g_object_set(data,"label","",NULL);
  28. }
  29.  
  30. void txtUser_cb( GtkWidget *widget, gpointer data ) {
  31.     gtk_widget_grab_focus(data);
  32. }
  33.  
  34. void onClick( GtkWidget *widget, gpointer data ) {
  35.     gchar *stupid_password = "pa$$w0rd!";
  36.     gchar *user_password;
  37.     g_object_get(data,"text",&user_password,NULL);
  38.  
  39.     if (g_strcmp0 (stupid_password,user_password) == 0) {
  40.         g_print("You are now logged in!\n");
  41.         gtk_main_quit();
  42.     }else{
  43.         gtk_label_set_markup(GTK_LABEL(err_label), "<span color=\"red\" font_desc=\"16.0\">** Invalid Password **</span>");
  44.         g_print("Username or Password is Incorrect!\n");
  45.  
  46.     }
  47. }
  48.  
  49. int main( int argc, char *argv[])
  50. {
  51.     GtkWidget *window, *layout, *image, *btnLogin, *chkBox;
  52.     GtkWidget *lblUser, *lblPass, *txtUser, *txtPass;
  53.  
  54.     gtk_init(&argc, &argv);
  55.    
  56.     layout = gtk_layout_new(NULL, NULL);
  57.  
  58.     window = g_object_new(GTK_TYPE_WINDOW,
  59.                         "type",GTK_WINDOW_TOPLEVEL,
  60.                         "title","Login",
  61.                         "default-width",660,
  62.                         "default-height",370,
  63.                         "resizable",FALSE,
  64.                         "window-position",GTK_WIN_POS_CENTER,
  65.                         "child",layout,
  66.                         "decorated",0,
  67.                         NULL);
  68.  
  69.     image = g_object_new(GTK_TYPE_IMAGE,"file","logon.png",NULL);
  70.     g_object_set(layout,"child",image,"margin",10,NULL);
  71.    
  72.     lblUser = g_object_new(GTK_TYPE_LABEL,"use-markup",TRUE,"label","<span font_desc=\"16.0\">Username:</span>",NULL);
  73.     lblPass = g_object_new(GTK_TYPE_LABEL,"use-markup",TRUE,"label","<span font_desc=\"16.0\">Password:</span>",NULL);
  74.     err_label = g_object_new(GTK_TYPE_LABEL, "width-request", 270,NULL);
  75.  
  76.     txtUser = g_object_new(GTK_TYPE_ENTRY,NULL);
  77.     txtPass = g_object_new(GTK_TYPE_ENTRY,"visibility",FALSE,NULL);    
  78.    
  79.     chkBox = g_object_new(GTK_TYPE_CHECK_BUTTON,"label","Show Password",NULL);
  80.  
  81.     btnLogin = g_object_new(GTK_TYPE_BUTTON,"label","Login","width-request",170,NULL);
  82.  
  83.     gtk_layout_put(GTK_LAYOUT(layout), lblUser, 330, 112-30);
  84.     gtk_layout_put(GTK_LAYOUT(layout), lblPass, 330, 162-30);
  85.     gtk_layout_put(GTK_LAYOUT(layout), txtUser, 460, 110-30);
  86.     gtk_layout_put(GTK_LAYOUT(layout), txtPass, 460, 160-30);
  87.     gtk_layout_put(GTK_LAYOUT(layout), chkBox, 460, 210-30);
  88.     gtk_layout_put(GTK_LAYOUT(layout), btnLogin, 460, 250-30);
  89.     gtk_layout_put(GTK_LAYOUT(layout), err_label, 300, 16);
  90.  
  91.     g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
  92.     g_signal_connect (btnLogin, "clicked", G_CALLBACK (onClick), txtPass);
  93.     g_signal_connect (chkBox, "toggled", G_CALLBACK (chkBox_cb), txtPass);
  94.     g_signal_connect (txtPass, "changed", G_CALLBACK (txtPass_cb), err_label);
  95.     g_signal_connect (txtPass, "activate", G_CALLBACK (onClick), txtPass);
  96.     g_signal_connect (txtUser, "activate", G_CALLBACK (txtUser_cb), txtPass);
  97.    
  98.     gtk_widget_show_all(window);
  99.  
  100.     gtk_main();
  101.  
  102.     return 0;
  103. }
  104.  
  105.  
  106.  

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 29, 2019, 06:31:36 PM
I'm going to be happy with return clicking the login button. In the day, the accounting software I worked on allowed enter as well as tab with the added ability to move around the form with the arrow keys.

Title: Re: RaspberryBASIC.org Forum
Post by: John on December 29, 2019, 08:15:50 PM
I gave your latest example a try and noticed that enter didn't move to the password field and there doesn't seem to  be a way out.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 29, 2019, 10:16:54 PM
Works on my Pi and Linux Laptop.


The password is:  pa$$w0rd!, like in the original.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 29, 2019, 11:48:12 PM
The enter key works on the password field (clicks the login button) but does nothing on User ID.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 29, 2019, 11:56:05 PM
Are you SURE you're compiling and running the latest source?

I copied what I posted into a new file, compiled it, and it works as it should.

Attached is the source, arm64 binary, and graphic.

Title: Re: RaspberryBASIC.org Forum
Post by: John on December 30, 2019, 10:55:32 AM
You're compiled version worked fine. I didn't recompile the source.

I highly recommend a way of exiting the login dialog if someone were to forget their password.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 30, 2019, 10:59:37 AM
It's modeled after a system logon dialog, where you would not have that option or window decorations....if you run it from a terminal, ctrl-c will kill it.  If not, pkill/kill/killall will do it.

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 30, 2019, 11:05:06 AM
Then it's not a dialog but a logon splash  screen.

I recompiled your source and it worked fine like the compiled version you posted.

Title: Re: RaspberryBASIC.org Forum
Post by: John on December 30, 2019, 11:26:41 AM
Let's call the ScriptBasic / Nim version the challenge baseline and any other permutations are welcome.

I'm assuming you will post your submission on the Raspberry BASIC  forum when you are ready to release it.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 30, 2019, 12:22:54 PM
Here is an updated 8th login dialog. Added toggle control for show password option. Tab and enter keys now work as expected. It also now uses encrypted password instead of storing it as a plain text.

I didn't find a way to change edit controls "password-char" property after it's created, so I am removing and adding child controls on the fly... I also wrote alternator word called next-state that gives a different state on every call. It works very nicely with toggle controls click event...

Code: [Select]
requires gui

{ guest: ` "2aab261fa05fbb817f5a2cba6511789632472561c04c82db1c4f7b0d7068f893" b:>hex ` } constant password

defer: auth

{
  kind: "edit",
  bounds: "edit1.left, lbl2.top, parent.width-20, top+24",
  name: "edit2",
  max-text: 32,
  password-char: "*",
  return-pressed: ' auth ,
  text-changed: ( "lbl0" g:child "" g:text drop )
} g:new constant edit2-hide-passwd

{
  kind: "edit",
  bounds: "edit1.left, lbl2.top, parent.width-20, top+24",
  name: "edit2",
  max-text: 32,
  password-char: "",
  return-pressed: ' auth ,
  text-changed: ( "lbl0" g:child "" g:text drop )
} g:new constant edit2-show-passwd

: alternator \ a -- a[0]
  a:shift dup >r
  a:push drop r> ;

[ ` edit2-show-passwd ` , ` edit2-hide-passwd ` ] ' alternator curry: next-state

: authenticate
  "edit1" g:child g:text? password swap m:@ nip null? if
    drop
    "lbl0" g:child
    "User not found!" g:text drop
  else
    swap
    "edit2" g:child g:text? s:len 0 n:= if
       drop false
     else
       "salty8thtears" 10000 cr:genkey rot b:=
     then if
       "Authenticated!" . cr
       bye
     else
       "lbl0" g:child
       "User and password don't match!" g:text drop
     then
  then ;

' authenticate w:is auth

{
  kind: "win",
  buttons: 5,
  native-title-bar: false,
  title: "Login",
  wide: 520,
  high: 220,
  resizable: false,
  center: true,
  children:
  [
    {
      kind: "box",
      name: "frame",
      bounds: "0, 0, parent.width, parent.height",
      bg: "gray",
      children:
      [
        {
          kind: "image",
          bounds: "parent.left+10, parent.top+10, left+128, top+128",
          img: "8thlogo.png",
          name: "logo"
        },
        {
          kind: "label",
          fg: "red",
          font: 20,
          label: "",
          bounds: "logo.right+20, parent.top+10, parent.width-10, top+24 ",
          justify: ["hcenter"],
          name: "lbl0"
        },
        {
          kind: "label",
          label: "Username:",
          bounds: "logo.right+20, lbl0.bottom+20, left+80, top+24 ",
          name: "lbl1"
        },
        {
          kind: "edit",
          bounds: "lbl1.right+10, lbl1.top, parent.width-20, top+24",
          name: "edit1",
          max-text: 32,
          return-pressed: ( "edit2" g:child g:focus drop ),
          text-changed: ( "lbl0" g:child "" g:text drop )
        },
        {
          kind: "label",
          label: "Password:",
          bounds: "lbl1.left, lbl1.bottom+10, left+80, top+24",
          name: "lbl2"
        },
        {
          kind: "edit",
          bounds: "edit1.left, lbl2.top, parent.width-20, top+24",
          name: "edit2",
          max-text: 32,
          password-char: "*",
          return-pressed: ' authenticate ,
          text-changed: ( "lbl0" g:child "" g:text drop )
        },
        {
          kind: "toggle",
          label: "Show password",
          adjustwidth: true,
          bounds: "edit1.left, lbl2.bottom+20, left+100, top+24",
          name: "toggle",
          click: ( "edit2" g:child g:text? >r "frame" g:child "edit2" g:-child next-state g:+child "edit2" g:child r> g:text drop )
        },
        {
          kind: "btn",
          label: "Login",
          bg: "darkgray",
          bounds: "lbl2.left, lbl2.bottom+60, edit1.right, top+30",
          name: "button",
          tooltip: "Login to account",
          click: ' authenticate
        }
      ]
    }
  ]
} g:new var, gui

: app:main ;
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 30, 2019, 12:35:49 PM
Jalih,

It would be great if you could join the Raspberry BASIC forum and participate there. I would like to migrate this AllBASIC thread to that forum and give other topics here a chance to flurious.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 30, 2019, 12:42:03 PM
Jalih,

It would be great if you could join the Raspberry BASIC forum and participate there. I would like to migrate this AllBASIC thread to that forum and give other topics here a chance to flurious.

Okay, I will join...  ;D

One additional improvement for this login dialog challenge would be to use database for storing username, encrypted password and salt.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 30, 2019, 04:20:50 PM
How would we implement the salt, as a static-applies-to-all variable, or a unique salt for each encrypted password that is generated?

If we do this, we need to agree that simply stuffing the password in plain text into the DB is not acceptable; it has to be the encrypted version of the password, and the comparison/check has to be against the encrypted version, not the plain text, and finally that hard-coding the passwords within the code, encrypted or not, is not allowed.


For the DB portion, a full RDBS is overkill, I would use sqlite3 for this.

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 30, 2019, 07:39:09 PM
That would mean you would also need to create a new account dialog as well.

The easy way is to add a New Account checkbox and what's entered would be added to the SQLite database with an encrypted password.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 30, 2019, 09:35:48 PM
You can do that, or do as I did and model your logon app after a system logon screen, which doesn't allow the creation of a new account at that screen.
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on December 30, 2019, 11:15:42 PM
You can do that, or do as I did and model your logon app after a system logon screen, which doesn't allow the creation of a new account at that screen.
I think that is fine! Lets keep the account creation dialog out of this challenge. You can use whatever method available to create the user account database. It just needs to store username, randomly generated hash and encrypted password for user.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 31, 2019, 02:27:55 PM
I posted an updated ScriptBasic version on Raspbery BASIC that supports a database with encrypted (MD5) passwords.
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 31, 2019, 05:35:39 PM
Quote from: JaliH
It just needs to store username, randomly generated hash and encrypted password for user.

The encrypted password is supposed to be created using the randomly generated hash to 'salt' the password generation AND the resulting check, with the hash being retrieved along with the encrypted password from the DB in order to perform the verification.

The Scriptbasic version is missing this....

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 31, 2019, 06:50:54 PM
I've already gone after extra points with the DB addition.

Isn't MD5 encryption enough for a login GUI example?
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on December 31, 2019, 07:27:37 PM
You're not salting the md5 with a hash, and you're not generating and storing the hash or retrieving the hash to perform the verification.

The hash has to be unique for each account too.

AIR.
Title: Re: RaspberryBASIC.org Forum
Post by: John on December 31, 2019, 09:01:20 PM
I'm not storing the Password. I'm storing a 16 byte MD5 hash of it. Login will be successful if the user entered MD5 hashed password matches the MD5 version of it in the database. A 1/2 mil solar power converter I wrote BACnet interface for used MD5 as it's API encryption method to control it externally.

I added duplicate UserID checking / error reporting and fixed the MD5 HEX string to be a fixed 32 byte length.

Happy New Year!
Title: Re: RaspberryBASIC.org Forum
Post by: jalih on January 01, 2020, 03:46:31 AM
You're not salting the md5 with a hash, and you're not generating and storing the hash or retrieving the hash to perform the verification.

The hash has to be unique for each account too.

I currently generate 32 byte random buffer from the cryptographically strong random source and convert it to hex string for the salt. Key for user chosen password is generated with PBKDF2 algorithm using previously randomly generated salt and 10000 iterations as parameters. Username, key and salt is then stored into database.

Title: Re: RaspberryBASIC.org Forum
Post by: John on January 01, 2020, 09:34:06 AM
The method I'm using is how this forum software encrypts passwords. I don't use salt but known to use sugar from time to time.  :)
Title: Re: RaspberryBASIC.org Forum
Post by: John on January 01, 2020, 12:58:54 PM
It seems I have everything I need to enhance the Nim IUP version to match what I did in ScriptBasic.

Hope to have something soon,

I was hoping someone would  take a shot at upgrading the Python initial example to bring it to current challenge specs.

Title: Re: RaspberryBASIC.org Forum
Post by: John on January 01, 2020, 02:24:52 PM
I really miss UltraEdit on the RPi.

Here is the Nim login.nim example on my Laptop Ubuntu 64. My guess is Unity is a slightly different desktop than what is installed with a standard Ubuntu desktop install.

Title: Re: RaspberryBASIC.org Forum
Post by: John on January 02, 2020, 07:25:38 PM
I updated the Nim submission to match the ScriptBasic latest version.

I surely learned a few things about Nim along the way.  :o

Q. How do you convert a cstring for a function that requires a Nim string?

That one took some digging.  :-[
Title: Re: RaspberryBASIC.org Forum
Post by: AIR on January 04, 2020, 12:16:15 PM
Updated C submission.

The libc 'crypt' function is configured to use a SHA-512 hashed password, which was generated using the default 5000 hash iterations.

Full source with arm64 binary, required png grahpic, sqlite3 database, and sql dump attached.

EDIT:  the password for both the 'guest' and 'admin' accounts is...'password'.

Code: C
  1. /* logon2.c
  2.  *
  3.  * version 1.4
  4.  *
  5.  * GUI Logon Screen Challenge Submission
  6.  * C version, using GTK3
  7.  *
  8.  * Written by Armando I. Rivera (AIR)
  9.  *
  10.  * Compile:  gcc logon2.c $(pkg-config --libs --cflags gtk+-3.0 sqlite3) -lcrypt -o logon2
  11. */
  12.  
  13. #define _GNU_SOURCE
  14. #include <gtk/gtk.h>
  15. #include <stdio.h>
  16. #include <crypt.h>
  17. #include <sqlite3.h>
  18.  
  19. GtkWidget *window, *layout, *image, *btnLogin, *chkBox;
  20. GtkWidget *lblUser, *lblPass, *txtUser, *txtPass,*err_label;
  21.  
  22. void chkBox_cb (GtkToggleButton *toggle_button, gpointer data) {
  23.       if (gtk_toggle_button_get_active (toggle_button)) {
  24.           g_object_set(data,"visibility",TRUE,NULL);
  25.       }else{
  26.           g_object_set(data,"visibility",FALSE,NULL);
  27.       }
  28. }
  29.  
  30. void txtPass_cb( GtkWidget *widget, gpointer data ) {
  31.     g_object_set(data,"label","",NULL);
  32. }
  33.  
  34. void txtUser_cb( GtkWidget *widget, gpointer data ) {
  35.     gtk_widget_grab_focus(data);
  36. }
  37.  
  38. int checkPassword(gchar *user, gchar *passwd) {
  39.     sqlite3_stmt *stmt = NULL;
  40.     sqlite3 *db;
  41.     gchar *zErrMsg = 0;
  42.     int rc;
  43.     gchar *sql,*stored_password=0,*stored_salt;
  44.     gchar *hashed_password;
  45.  
  46.     if (g_file_test("auth.db",G_FILE_TEST_EXISTS) == FALSE){
  47.       return(1);
  48.     }    
  49.  
  50.     if (rc = sqlite3_open("auth.db", &db)) {
  51.        return(2);
  52.     }
  53.     asprintf(&sql,"select username,password,salt from Users where username is '%s'",user);
  54.    
  55.     if (rc = sqlite3_prepare_v2(db, sql,-1,&stmt,0) != SQLITE_OK ) {
  56.         return(-1);
  57.     }
  58.  
  59.     free(sql);
  60.    
  61.     if (sqlite3_step(stmt) == SQLITE_ROW) {
  62.         stored_password = (gchar*)sqlite3_column_text(stmt,1);
  63.         stored_salt = (gchar*)sqlite3_column_text(stmt,2);
  64.         hashed_password= crypt(passwd,stored_salt);
  65.         return g_strcmp0 (hashed_password, stored_password);
  66.     }else{
  67.         return(3);
  68.     }
  69. }
  70.  
  71. void onClick( GtkWidget *widget, gpointer data ) {
  72.     gchar *user_name, *user_password;
  73.     int result;
  74.     g_object_get(txtUser,"text",&user_name,NULL);
  75.     g_object_get(txtPass,"text",&user_password,NULL);
  76.    
  77.     result = checkPassword(user_name, user_password);
  78.  
  79.     switch (result) {
  80.         case 0:
  81.             g_print("User '%s' now logged in!\n",user_name);
  82.             gtk_main_quit();
  83.             break;
  84.         case 1:
  85.             gtk_label_set_markup(GTK_LABEL(err_label), "<span color=\"red\" font_desc=\"16.0\">** Database Not Found **</span>");
  86.             g_print("'auth.db' database not found\n");
  87.             break;
  88.         case 2:
  89.             gtk_label_set_markup(GTK_LABEL(err_label), "<span color=\"red\" font_desc=\"16.0\">** Database Not Accessible**</span>");
  90.             g_print("Unable to read 'auth.db' database\n");
  91.             break;
  92.         case 3:
  93.             gtk_label_set_markup(GTK_LABEL(err_label), "<span color=\"red\" font_desc=\"16.0\">** Unknown User **</span>");
  94.             g_print("Unknown User Account for '%s'\n",user_name);