r10614: 2005-07-05 Kevin Rosenberg (kevin@rosenberg.net)
[uffi.git] / src / corman / getenv-ccl.lisp
1 ;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*-
2 ;;;; *************************************************************************
3 ;;;; FILE IDENTIFICATION
4 ;;;;
5 ;;;; Name:          getenv-ccl.cl
6 ;;;; Purpose:       cormanlisp version
7 ;;;; Programmer:    "Joe Marshall" <prunesquallor@attbi.com>
8 ;;;; Date Started:  Feb 2002
9 ;;;;
10 ;;;; $Id$
11 ;;;;
12 ;;;; *************************************************************************
13
14 (in-package :cl-user)
15
16 (ct:defun-dll c-getenv ((lpname LPSTR)
17                         (lpbuffer LPSTR)
18                         (nsize LPDWORD))
19   :library-name "kernel32.dll"
20   :return-type DWORD
21   :entry-name "GetEnvironmentVariableA"
22   :linkage-type :pascal)
23
24 (defun getenv (name)
25   (let ((nsizebuf (ct:malloc (sizeof :long)))
26         (buffer (ct:malloc 1))
27         (cname (ct:lisp-string-to-c-string name)))
28     (setf (ct:cref lpdword nsizebuf 0) 0)
29     (let* ((needed-size (c-getenv cname buffer nsizebuf))
30            (buffer1 (ct:malloc (1+ needed-size))))
31       (setf (ct:cref lpdword nsizebuf 0) needed-size)
32       (prog1 (if (zerop (c-getenv cname buffer1 nsizebuf)) 
33                  nil
34                (ct:c-string-to-lisp-string buffer1))
35         (ct:free buffer1)
36         (ct:free nsizebuf)))))
37
38 (defun cl:user-homedir-pathname (&optional host)
39   (cond ((or (stringp host)
40              (and (consp host)
41                   (every #'stringp host))) nil)
42         ((or (eq host :unspecific)
43              (null host))
44          (let ((homedrive (getenv "HOMEDRIVE"))
45                (homepath  (getenv "HOMEPATH")))
46            (parse-namestring
47              (if (and (stringp homedrive)
48                       (stringp homepath)
49                       (= (length homedrive) 2)
50                       (> (length homepath) 0))
51                  (concatenate 'string homedrive homepath "\\")
52                  "C:\\"))))
53         (t (error "HOST must be a string, list of strings, NIL or :unspecific"))))
54
55 ;|
56 (uffi:def-function ("getenv" c-getenv) 
57     ((name :cstring))
58   :returning :cstring)
59
60 (defun my-getenv (key)
61   "Returns an environment variable, or NIL if it does not exist"
62   (check-type key string)
63   (uffi:with-cstring (key-native key)
64     (uffi:convert-from-cstring (c-getenv key-native))))
65     
66 #examples-uffi
67 (progn
68   (flet ((print-results (str)
69            (format t "~&(getenv ~S) => ~S" str (my-getenv str))))
70     (print-results "USER")
71     (print-results "_FOO_")))
72
73
74 #test-uffi
75 (progn
76   (util.test:test (my-getenv "_FOO_") nil :fail-info "Error retrieving non-existent getenv")
77   (util.test:test (and (stringp (my-getenv "USER"))
78                        (< 0 (length (my-getenv "USER"))))
79                   t :fail-info "Error retrieving getenv")
80 )
81