Passing a file name's path to CLIPS from a C application.

58 views
Skip to first unread message

JCL

unread,
May 6, 2012, 1:07:41 PM5/6/12
to CLIPSESG
Hello:

I'm a newbie with both CLIPS and C and I apologize if this is a dumb
question.

Question:
How do I pass a file name's full path (filename + path) to CLIPS from
an external application?
Or, more generically: how to pass a value to CLIPS that I can then use
inside CLIPS.


Background:

a.) I have embedded CLIPS inside a C app.

b.) I call "Load(..);" to load a *.clp file.

c.) Inside the *.clp file I have this:
(deffunction save-fact-to-file (?in_string)
(open "LV.sql" LVout "a")
(printout t "Value to insert: " ?in_string crlf)
(printout LVout ?in_string crlf)
(close LVout)
)
{The purpose of this function is to write to a text file the results
of each rule that fired. Those results are later processed by the
calling C app.}

d.) "save-fact-to-file" does work and the function does write the line
out to the indicated file, in this case "LV.sql" The _problem_ is that
the file "LV.sql" is written to the root of the computer's file
system, not to the directory where the app is running from.

What I'd like to know is how can I pass the file's full pathname
(pathname + filename) to CLIPS so that the "save-fact-to-file" will
create the output file where I need the file to be saved at.


I have read the "Advanced Programming Guide" and I was thinking of
several approaches:

a.) Use CLIPS' "system" function [(system "dir " ?directory));] to
query the underlying OS for the full path of the directory where the
app containing CLIPS is running at.

b.) Create a user-defined function to pass the file pathname to CLIPS,
and use the user-defined function to populate the
(deffunction save-fact-to-file (?in_string)
above with the full filename + path for
(open "LV.sql" LVout "a")


Is there an easier way? Thank you all. Regards.

Lode Hoste

unread,
May 9, 2012, 8:35:53 AM5/9/12
to clip...@googlegroups.com
Hi JCL,

a)
I'm afraid there is no build-in '(get-current-path)' function that
would make it easier.
Such a function is hard to support on multiple platforms.
However, I quickly implemented this function for you, supporting
Windows, POSIX (Linux/OSX):


#if IO_FUNCTIONS
static void *GetCurrentPathFunction(void *theEnv) {
#if UNIX_V || UNIX_7 || LINUX || DARWIN || MAC_XCD || MAC_MCW || GENERIC
char buffer[PATH_MAX];
buffer[0] = '\0';
getcwd(buffer, PATH_MAX);
#elif WIN_MVC || WIN_BTC || WIN_GCC
char buffer[MAX_PATH];
char *curr, *end;
buffer[0] = '\0';
GetModuleFileNameA(NULL,buffer,sizeof(buffer));
curr = buffer;
end = NULL;
while (curr[0] != '\0') {
if (curr[0] == '\\') {
/* Skip folder */
end = ++curr;
} else if (curr[0] == ':') {
/* Skip drive letter */
curr++;
if (curr[0] == '\\') {
end = ++curr;
}
} else {
curr++;
}
}
if (end != NULL) {
end[0] = '\0';
}
#else
char buffer[1];
buffer[0] = '\0';
#endif
return (SYMBOL_HN *) EnvAddSymbol(theEnv,buffer);
}
#endif


#if IO_FUNCTIONS
/*==================================================*/
/* Get the fully qualified path for the executable. */
/* Format: (get-current-path) */
/*==================================================*/
EnvDefineFunction2(theEnv,"get-current-path",'s',PTIEF
GetCurrentPathFunction, "get-current-path", "00");
#endif



b) I wondering what you don't like about this method?
c) Alternatively: use a global variable and set it before calling your
function. However, I would prefer method b in this case.


2012/5/6 JCL <afgha...@mypacks.net>:
> --
> You received this message because you are subscribed to the Google Groups "CLIPSESG" group.
> To post to this group, send email to CLIP...@googlegroups.com
> For more options, visit this group at http://groups.google.com/group/CLIPSESG?hl=en
>
> --> IF YOU NO LONGER WANT TO RECEIVE EMAIL <--
> Visit this group at http://groups.google.com/group/CLIPSESG?hl=en
> Click on "Edit my membership" link.
> Select the "No Email" radio button.
> Click the "Save these settings" button.
>
> --> IF YOU WANT TO UNSUBSCRIBE <--
> Visit this group at http://groups.google.com/group/CLIPSESG?hl=en
> Sign in
> Click on "Edit my membership" link.
> Click the "Unsubscribe" button.
> Note: This appears to be the most reliable way to unsubscribe
>
> Alternately, send email to CLIPSESG-u...@googlegroups.com. You will receive an email which you must respond to as well to unsubscribe. Clicking the link mentioned in the unsubscribe reply does not appear to work reliably.
Reply all
Reply to author
Forward
0 new messages