Browse Source

The shebang for the ACTION was implemented. Issue #15.

git-svn-id: https://klish.googlecode.com/svn/trunk@274 0eaa4687-2ee9-07dd-09d9-bcdd2d2dd5fb
Serj Kalichev 13 years ago
parent
commit
496654bf7b

+ 6 - 2
clish.xsd

@@ -324,14 +324,18 @@
 * (e.g. $|<>`) are escaped before evaluation.
 *
 * [builtin] - specify the name of an internally registered
-*             function. The content of the ACTION tag is
-*             taken as the arguments to this builtin function.
+*           function. The content of the ACTION tag is
+*           taken as the arguments to this builtin function.
+*
+* [shebang] - specify the programm to execute the action
+*           script.
 ********************************************************
 -->
     <xs:complexType name="action_t">
         <xs:simpleContent>
             <xs:extension base="xs:string">
                 <xs:attribute name="builtin" type="xs:string" use="optional"/>
+                <xs:attribute name="shebang" type="xs:string" use="optional"/>
             </xs:extension>
         </xs:simpleContent>
     </xs:complexType>

+ 25 - 4
clish/clish_script_callback.c

@@ -6,21 +6,42 @@
  */
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <assert.h>
 
 #include "private.h"
 
 /*--------------------------------------------------------- */
-bool_t clish_script_callback(const clish_shell_t * shell, const char *script)
+bool_t clish_script_callback(const clish_shell_t * this,
+	const clish_command_t * cmd, const char *script)
 {
+	FILE *wpipe;
+	const char * shebang = NULL;
+
+	assert(this);
+	assert(cmd);
+	if (!script) /* Nothing to do */
+		return BOOL_TRUE;
+
+	shebang = clish_command__get_shebang(cmd);
 #ifdef DEBUG
+	if (shebang)
+		fprintf(stderr, "SHEBANG: #!%s\n", shebang);
 	fprintf(stderr, "SYSTEM: %s\n", script);
 #endif /* DEBUG */
-
-	return (0 == system(script)) ? BOOL_TRUE : BOOL_FALSE;
+	if (!shebang)
+		return (0 == system(script)) ? BOOL_TRUE : BOOL_FALSE;
+	/* The shebang is specified */
+	wpipe = popen(shebang, "w");
+	if (!wpipe)
+		return BOOL_FALSE;
+	fwrite(script, strlen(script) + 1, 1, wpipe);
+	return (0 == pclose(wpipe)) ? BOOL_TRUE : BOOL_FALSE;
 }
 
 /*--------------------------------------------------------- */
-bool_t clish_dryrun_callback(const clish_shell_t * shell, const char *script)
+bool_t clish_dryrun_callback(const clish_shell_t * this,
+	const clish_command_t * cmd, const char *script)
 {
 #ifdef DEBUG
 	fprintf(stderr, "DRY-RUN: %s\n", script);

+ 2 - 0
clish/command.h

@@ -108,5 +108,7 @@ unsigned clish_command__get_cfg_depth(const clish_command_t * instance,
 	const char *viewid, clish_pargv_t * pargv);
 bool_t clish_command__get_lock(const clish_command_t * instance);
 void clish_command__set_lock(clish_command_t * instance, bool_t lock);
+const char * clish_command__get_shebang(const clish_command_t * instance);
+void clish_command__set_shebang(clish_command_t * instance, const char * shebang);
 
 #endif				/* _clish_command_h */

+ 26 - 1
clish/command/command.c

@@ -33,12 +33,15 @@ clish_command_init(clish_command_t * this, const char *name, const char *text)
 	this->view = NULL;
 	this->action = NULL;
 	this->detail = NULL;
-	this->builtin = NULL;
 	this->escape_chars = NULL;
 	this->args = NULL;
 	this->pview = NULL;
 	this->lock = BOOL_TRUE;
 
+	/* ACTION params */
+	this->builtin = NULL;
+	this->shebang = NULL;
+
 	/* CONFIG params */
 	this->cfg_op = CLISH_CONFIG_NONE;
 	this->priority = 0; /* medium priority by default */
@@ -75,6 +78,8 @@ static void clish_command_fini(clish_command_t * this)
 	this->detail = NULL;
 	lub_string_free(this->builtin);
 	this->builtin = NULL;
+	lub_string_free(this->shebang);
+	this->shebang = NULL;
 	lub_string_free(this->escape_chars);
 	this->escape_chars = NULL;
 
@@ -614,3 +619,23 @@ void clish_command__set_lock(clish_command_t * this, bool_t lock)
 {
 	this->lock = lock;
 }
+
+/*--------------------------------------------------------- */
+const char * clish_command__get_shebang(const clish_command_t * this)
+{
+	return this->shebang;
+}
+
+/*--------------------------------------------------------- */
+void clish_command__set_shebang(clish_command_t * this, const char * shebang)
+{
+	const char *prog = shebang;
+	const char *prefix = "#!";
+
+	assert(NULL == this->shebang);
+	if (lub_string_nocasestr(shebang, prefix) == shebang)
+		prog += strlen(prefix);
+	if (lub_string_nocasecmp(prog, "/bin/sh") == 0) /* the default */
+		return;
+	this->shebang = lub_string_dup(prog);
+}

+ 4 - 1
clish/command/private.h

@@ -15,13 +15,16 @@ struct clish_command_s {
 	clish_view_t *view;
 	char *viewid;
 	char *detail;
-	char *builtin;
 	char *escape_chars;
 	clish_param_t *args;
 	const struct clish_command_s * link;
 	clish_view_t *pview;
 	bool_t lock;
 
+	/* ACTION params: */
+	char *builtin;
+	char *shebang;
+
 	/* CONFIG params:
 	 * TODO: create special structure for CONFIG params.
 	 */

+ 4 - 0
clish/shell.h

@@ -138,6 +138,10 @@ typedef bool_t clish_shell_script_fn_t(
          * The shell instance which invoked this call
          */
 					      const clish_shell_t * instance,
+	/** 
+         * The command which invoked this call
+         */
+					      const clish_command_t * cmd,
 	/** 
          * The script to be evaluated
          */

+ 1 - 1
clish/shell/shell_execute.c

@@ -279,7 +279,7 @@ clish_shell_execute(clish_shell_t * this,
 		}
 	} else if (NULL != script) {
 		/* now get the client to interpret the resulting script */
-		result = this->client_hooks->script_fn(this, script);
+		result = this->client_hooks->script_fn(this, cmd, script);
 
 	}
 	pthread_cleanup_pop(1);

+ 3 - 0
clish/shell/shell_tinyxml_read.cpp

@@ -434,6 +434,7 @@ process_action(clish_shell_t * shell, TiXmlElement * element, void *parent)
 		// read the following text element
 		TiXmlNode *text = element->FirstChild();
 		const char *builtin = element->Attribute("builtin");
+		const char *shebang = element->Attribute("shebang");
 
 		if (NULL != text) {
 			assert(TiXmlNode::TEXT == text->Type());
@@ -444,6 +445,8 @@ process_action(clish_shell_t * shell, TiXmlElement * element, void *parent)
 			// store the action
 			clish_command__set_builtin(cmd, builtin);
 		}
+		if (NULL != shebang)
+			clish_command__set_shebang(cmd, shebang);
 	}
 }