save to string instead of file

For the Compleat Fan
Locked
HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

save to string instead of file

Post by HPW »

I don't know if this is possible now in an other way.

I want a function like 'save', but I do not want to write to a temp-file and then read it back. The counter-part is ready with 'eval-string'.

It could be an option to 'save' or a new command like:

(stream varname [symbol])

I have in mind an other sort of storage and would like to send the resulting stream to a DLL, from where it could get back.
Hans-Peter

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

could you give a small example what this function would do?

Lutz

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

When you open the newLISP-TK browser you write a file editbox.lsp in c:\temp. I want the complete content of this file in a symbol as a long string including all CRLF. So simple replace the file-target by a string-buffer in the command 'save'. This string contain the lisp-source which I can send to my DLL.
Hans-Peter

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

If you don't care for formatting or pretty printing the following function will work:

(define (save-string sym)
(append "(set '" (string sym " ") (string (eval sym))))

for example:

(define (double x) (+ x x))

(save-string 'double) => "(set 'double (lambda (x) (+ x x))"

The returned string could be sent to the newlisp.dll for evaluation, where it would define the same function.

Lutz
ps: parenthesis missing! see 2 posts down for correction by HPW
Last edited by Lutz on Mon Feb 16, 2004 5:48 pm, edited 1 time in total.

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

>I don't know if this is possible now in an other way.

Yes, that is the kind of other way I search.
For this time I don't care for formatting.
So I will go this way.
Thanks for the code.
Hans-Peter

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

Oops, missing paranthesis:

Code: Select all

(define (save-string sym)
	(append "(set '" (string sym " ") (string (eval sym))")"))
Hans-Peter

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

And it still does not do the same as 'save'.

with save:

Code: Select all

(set 'CADT_WOINT_VARARTTAB '(
  ("KorpFa" 1 1 "Korpusfarbe") 
  ("Progr" 1000 1 "Programm")))
with save-string:

Code: Select all

(set 'atest [text](set 'CADT_WOINT_VARARTTAB (("KorpFa" 1 1 "Korpusfarbe")("Progr" 1000 1"Programm")))[/text])
When eval-string there is a quote missing.
Hans-Peter

eddier
Posts: 289
Joined: Mon Oct 07, 2002 2:48 pm
Location: Blue Mountain College, MS US

Post by eddier »

You need a single quote before (("KorpFa" as '(("KorpFa"

Eddie

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

yes, I guess the 'save-string' function would have to be more complex and distinghish the type stored in a symbol:

- For lambda expressions and numbers leave like it is
- for lists which are not lambda put a single quote
- for strings put quotes around it

Code: Select all

(define (save-string sym)
  (set 'contents (eval sym))
  (if (or (lambda? contents) (integer? contents) (float? contents))
      (append "(set '" (string sym " ") (string (eval sym)) ")")
      (list? contents)
      (append "(set '" (string sym " ") (string "'" (eval sym)) ")")
      (string? contents)
      (append "(set '" (string sym " ") (string "\"" (eval sym)) ")")))
You may still run into problems with nested [text] [/text] tags. Perhaps you should save to a temp-file like the tk-frontend is doing it and then let the dll 'load' it.

Lutz

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

>Perhaps you should save to a temp-file like the tk-frontend is doing it and then let the dll 'load' it.

That option is possible of cource, but I wanted to avoid the step and stream it directly to the DLL. Would it be possible to make the 'save' command to optional work with an text-buffer instead of a file?

Anyway, thanks again for the improved code.
Hans-Peter

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

Yes, I looked into it. But it would be something after version 8.0. I will try then to make something like a 'string device' which also could be used in other circumstances, wherever a file is used. Internally a string stream device already exists but is not used/available to all functions dealing with files.

For upcoming version 8.0 in early summer I am concentrating on fixing bugs, more speed improvements, cutting old deprecated features and only doing small improvements, which have only a local affect on one function.

I want to introduce newLISP to a broader audience, have it rock solid and well documented. With the help of many of you in this forum newLISP has evolved to a more richly featured scripting language and LISP and it is time to do something to promote it to a wider audience.

Lutz

nigelbrown
Posts: 429
Joined: Tue Nov 11, 2003 2:11 am
Location: Brisbane, Australia

Post by nigelbrown »

Seeing the discussion is around eval of strings I have a suggestion and seek feedback -
With the aim of creating dedicated utilities using newLISP could a compile option be created in which a string, probably not too big for a simple but helpful utility, could be compiled into a newLisp.exe such that running the exe began execution with eval'ing that string (rather than looking for an init.lsp). This would have a few advantages over the external init file approach viz
- the exe could be moved around without having to remember the init file
- multiple of these exe could reside in the same directory without init files interfering with each other
- the extra step/bother of having a batch/bash file to run newLISP with the desired startup lisp file is removed
- it is more secure (the internal string could even be largely encrypted although an external one could also) than running the risk of someone fiddling with an external lsip file

For me moving the exe around without having to remember the init file is the main advantage.
I see the overhead of multiple exe sizes as not an issue in the day of 200G drives and the small footprint of newLISP.

This option would be very much in the spirit of newLISP as having as one of its many strengths the nature of being great 'little' language to do utilities in. I say little compared to Common Lisp systems!

An thoughts on an exe the inits from an internal string?

Nigel

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

Such a thing already exists! look for the file "link.lsp" in the newLISP source distribution. This file lets you link (and encrypt) lisp source with the newLISP executable, which then gets automatically executed when the executable is started. It works for both, Win32 and Linux.

Lutz

nigelbrown
Posts: 429
Joined: Tue Nov 11, 2003 2:11 am
Location: Brisbane, Australia

Post by nigelbrown »

Well done Lutz! I'll take it for a spin.

It's such an important example it must be mentioned in the manual! and not just languish in the examples directory - but I'm sure that was on the to-do list.

Thanks
Nigel

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

Lutz,

>But it would be something after version 8.0. I will try then to make something like a 'string device' which also could be used in other circumstances, wherever a file is used.

Sounds very good. Until that time I will use the other options.


Nigel,

Besides the option with link.lsp for smaller solutions, you can also use freewrap, starpacks/TclDevKit to make larger self contained apps. There you can pack large number of files in virtual files systems inside the app. You can find discussion about this (freewrap) here on the forum.
Hans-Peter

nigelbrown
Posts: 429
Joined: Tue Nov 11, 2003 2:11 am
Location: Brisbane, Australia

Post by nigelbrown »

link.lsp worked great!

As a first test I added this code :
...

;; main for linker.exe usage: linker out.exe in.lsp
(begin
(if (not (file-info "newlisp.exe")) (begin
(print "err: Newlisp.exe not found - must be in same directory as linker") (exit 1)))
(if (not (file-info (nth 2 (main-args)))) (begin
(print "err: " (nth 2 (main-args)) " not found - cannot produce linked exe file") (exit 1)))
(print "Linking in " (nth 2 (main-args)) " to create " (nth 1 (main-args)) "\n")
(link "newlisp.exe" (nth 1 (main-args)) (nth 2 (main-args)))
(exit 0))

to the bottom of link.lsp and saved it as linker.lsp, then in newLISP-tk did
> (link "newlisp.exe" "linker.exe" "linker.lsp")
true

and linker.exe worked fine so...
then used linker to link in txttopdf.lsp viz
C:\newlisp>linker txttopdf.exe txttopdf.lsp
Linking in txttopdf.lsp to create txttopdf.exe

Now txttopdf.lsp is txt2pdf.lsp with Sammo's wrapper function and a modification of the linker.lsp command line arg handling added at the end viz:
...
(context 'MAIN)

;; copy-text-to-pdf
;; simple wrapper for Nigel's 'txt2pdf' code
;;
(define (copy-text-to-pdf text-filename pdf-filename)
(let
( (infile (open text-filename "read")) )
(TXT2PDF:txt2pdf (lambda () (read-line infile)) pdf-filename)
(close infile) ))
(begin
(if (not (file-info (nth 1 (main-args)))) (begin
(print "err: " (nth 1 (main-args)) " not found - cannot produce pdf file") (exit 1)))
(print "Pdfing " (nth 1 (main-args)) " to create " (nth 2 (main-args)) "\n")
(copy-text-to-pdf (nth 1 (main-args)) (nth 2 (main-args)))
(exit 0))

So that now txttopdf is a command line utility for making pdf's viz

C:\newlisp>txttopdf README.txt readme.pdf
Pdfing README.txt to create readme.pdf

C:\newlisp>txttopdf READYOU.txt readme.pdf
err: READYOU.txt not found - cannot produce pdf file
C:\newlisp>

Which is just what I want! (I tried Easy Txt2pdf at www.easyhr.com.au but it doesn't/didn't handle brackets properly - not good for pdfing lisp code!)

Thanks Lutz for the exe building mod.

PS I've noticed that txt2pdf.lsp isn't quite right at handling long lines
try
C:\newlisp>txttopdf linker.lsp linker.pdf
Pdfing linker.lsp to create linker.pdf

and look at line that should be
(print "err: " (nth 2 (main-args)) " not found - cannot produce linked exe file") (exit 1)))

the 1))) is chopped off - I'll see what I can do.

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

Many, many thanks for the new 'source' command in 7.5.4.
Comes a lot faster than I hope!
Hans-Peter

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

I could leverage pretty much on what was there already and it also simplified the newlisp-tk frontend tremendously. It is now rather simple to create frontends to newLISP from other environments / languages.

Lutz

Locked