I'm trying to write to a file in Common Lisp, but I keep getting a "file is not a stream" error:
[1]> (open "file.txt" :direction :output :if-does-not-exist :create :if-exists :supersede)
#<output buffered file-stream character #P"file.txt">
[2]> (princ 'Hello "file.txt")
*** - princ: argument "file.txt" is not a stream
Even attempting to close the file returns an error:
[4]> (close "file.txt")
*** - no-applicable-method: When calling #<standard-generic-function close>
with arguments ("file.txt"), no method is applicable.
The file was properly created, so I thought it might be a permissions issue, but that doesn't seem to be it.
I've Googled this error without any luck so far. Does anyone know what I am doing wrong? Thank you.
PS: I'm running Linux Mint 17.3 Rosa with CLISP 2.49 (2010-07-07)
To use open files, you must save the return value of open and uses it as the second argument to princ. You must also use that same return value as an argument to close.
This is usually done with the convenience macro with-open-file.
The files chapter of Practical Common Lisp shows how to use these and other functions and macros.
Related
I get a "Undefined function FILE-EXISTS-P called with arguments ..." error when calling (file-exists-p "somepath") in Clozure Common Lisp but everywhere I look it appears that this function should be available. I even see it when using M-x apropos.
I'm using LispBox for Windows.
Does anyone have an idea of what might be wrong or maybe suggest a process by which I can try to figure it out?
FILE-EXISTS-P is not a standard Common Lisp function or a Clozure Common Lisp specific function.
Instead, you can use the standard PROBE-FILE function (see the manual) to check if a file exists:
CL-USER> (probe-file "not-existant-file.lisp")
NIL
CL-USER> (probe-file "/Users/myname/temp.lisp")
#P"/Users/myname/temp.lisp"
Note that the in the standard is undefined the result of applying the function to a directory, while the CCL implementation (at least on some systems) checks correctly also if a directory exists:
CL-USER> (probe-file "/Users/myname/")
#P"/Users/myname/"
I am spawning a process from Common Lisp program (gnuplot). I am able to establish input and output streams for the process. However, I have a problem reading from the output. The problem is that I want to try to read from the output, and if there is nothing there, well... do nothing for example.
(Basic problem: I want to read the result of the command show term but I want to skip any other output that gnuplot might have produced before sending this command)
If I just use (read-line gnuplot-output nil :eof) and there is nothing in output stream, it will not indicate :eof (since the stream is still alive and something might appear there) and will just block until it has something to read (i.e. forever).
Is there are way to detect that there is nothing to read? At least, somehow safely time-out the attempt to read (i.e. it shouldn't pop a new line out of the stream once the time-out is reached)?
PS. I am using SBCL
Listen should tell you if there is a character available. I think you'll have to read the stream character by character rather than whole lines at a time, unless you're sure that the program never outputs an incomplete line.
Edit: A quick test (using sb-ext for running the program):
(defun test ()
(do* ((program (run-program "output-test.sh" nil
:search t
:output :stream
:wait nil))
(output-stream (process-output program)))
((not (process-alive-p program)))
(if (listen output-stream)
(loop
for char = (read-char-no-hang output-stream nil nil)
while char
do (write-char char))
(format t "No output available.~%"))
(sleep 1)))
Where output-test.sh is:
#!/bin/sh
for item in *
do
echo $item
sleep 3
done
I use this valgrind.el to run valgrind inside emacs. But the newest version of emacs has deprecated compile-internal. I don't know nearly enough about elisp to figure out how to convert the compile-internal call to a compilation-start call. This is what the original function call in question looks like:
(compile-internal command "No more errors" "valgrind")
I found this bit online that indicates possible usage of compilation-start:
(compilation-start command mode
#'(lambda (mode-name) (concat "*" buf-name "*")))
Any help would be appreciated!
I am not sure about what you tried and what the results were.
As per the documentation, I would replace the compile internal line by:
(compilation-start command nil (lambda (mode-name) "*valgrind*"))
Flycheck is an emacs library that does background compilation of source files. You can add your own "checkers" (ways of compiling certain files) with help from the manual.
I'm trying to add a compiler that needs to find a few files in a relative directory to the current file. I have a function that does that for me, called (process filename). When building the terminal command to execute for a file, you can use an (eval FORM) compute parameters on the fly. Here's the relevant part of my checker's definition:
(flycheck-declare-checker unity-csharp-flychecker
"given a c-sharp file, looks for the unity file and then tries to build it using mdtool."
:command '("mdtool" "build"
(eval '(process source-original)))
...)
source-original is a special symbol that is substituted for buffer-file-name at execution time.
Unfortunately when I try to use the checker, I get this error:
Invalid result from evaluation of (quote (process source-original)): (process source-original)
Am I using (eval) incorrectly here? How can I get access to source-original from within so I can pass it to (process)? Any help much appreciated.
This is the correct form:
(flycheck-declare-checker unity-csharp-flychecker
"given a c-sharp file, looks for the unity file and then tries to build it using mdtool."
:command '("mdtool" "build"
(eval (process buffer-file-name)))
...)
Thanks for Bruce Conner for getting me to remove the quote before (process ...). That gave me a new error:
Error: (void-variable source-original)
So I dug into the source and saw there is no symbol substitution before evaluation. I assumed because we were given symbols that just using buffer-file-name wouldn't work, but I tried it and it does. I don't know if there are ramifications for that approach down the road.
I have installed LispBox on Windows and it's running great. I do however have some trouble with debugging code : when I try and compile code and it contains an error such as a syntax error, the error message output (printed below) is not very useful.
Serious errors encountered during compilation of
"d:/Jervis/Documents/Programming/LISP/hw1.lisp"
[Condition of type SIMPLE-ERROR]
0: (CCL::%COMPILE-FILE "d:/Jervis/Documents/Programming/LISP/hw1.lisp" "d:/Jervis/Documents/Programming/LISP/hw1.wx64fsl" T NIL T T NIL T :DEFER NIL #<BACKEND WIN64 #x21001C6FCD> :DEFAULT NIL 0)
1: (COMPILE-FILE #P"d:/Jervis/Documents/Programming/LISP/hw1.lisp" :OUTPUT-FILE #P"d:/Jervis/Documents/Programming/LISP/hw1.wx64fsl" :VERBOSE T :PRINT NIL :LOAD NIL :FEATURES NIL :TARGET :WIN64 :SAVE-LOC..
2: (SWANK-BACKEND:CALL-WITH-COMPILATION-HOOKS #<CCL:COMPILED-LEXICAL-CLOSURE (:INTERNAL SWANK-BACKEND:SWANK-COMPILE-FILE) #x2100C2730F>)
3: ((:INTERNAL SWANK:COMPILE-FILE-FOR-EMACS))
Does anyone know how to get the line number of the code that is causing the compilation errors?
I have tried to follow the advice here of opening the Compiler Input buffer but that did not work. (The buffer was unavailable, and thus couldn't be opened).
Any Ideas?
A clarification first: the *Compiler Input* buffer you mention has nothing to do with Common Lisp and Slime, it is about errors that Emacs encountered when compiling Emacs Lisp (its internal lisp, quite different from CL).
As for your problem (determining a file name/line number to narrow down the problem): when I enter a broken piece of code in a file (say test.lisp):
(defun fact (n)
(if (= 0 n)
1
!(* n (facto (1- n)))))
, then try to send it to CCL via Slime by pressing C-c C-k in the test.lisp buffer, I get an error and a list of restarts (below the list of restarts there's also a backtrace similar to what you got). Select restart 0 by pressing 0, then 'n' to not load the broken compiled file into CCL. The buffer with the error should be replaced with a buffer named *slime-compilation*, which in my case contains:
cd d:/tmp/lispbox-0.7/
2 compiler notes:
test.lisp:2:5:
warning: Extra arguments in (IF (= 0 N) 1 ! (* N (FACTO (1- N)))) don't match lambda list (CCL::TEST CCL:TRUE &OPTIONAL CCL:FALSE).
style-warning: Unused lexical variable N
Compilation failed.
, which looks like it's what you wanted.
My hand-installed Linux CL setup doesn't need selecting the 0 restart and there's also a slime setting to avoid the 'load fasl file anyway (y/n)' prompt, so the experience can get better with some customization.