1 /*
2   Purpose : A hello Bash builtin command
3   Ideas   : evilrat
4   Author  : Ky-Anh Huynh
5   Date    : 2017-Oct-21st
6   License : MIT
7 */
8 
9 module dusybox.bash_builtin_hello;
10 
11 // bash source, builtins.sh
12 enum BUILTIN_ENABLED = 0x01;
13 
14 // bash source, shell.h
15 enum EXECUTION_FAILURE = 1;
16 enum EXECUTION_SUCCESS = 0;
17 
18 // bash source, command.h
19 struct word_desc
20 {
21   char *word; /* Zero terminated string. */
22   int flags;  /* Flags associated with this word. */
23 }
24 
25 // bash source, command.h
26 /* A linked list of words. */
27 struct word_list
28 {
29   WORD_LIST *next;
30   WORD_DESC *word;
31 }
32 
33 alias WORD_LIST = word_list;
34 alias WORD_DESC = word_desc;
35 
36 // bash source, general.h
37 alias sh_builtin_func_t = extern(C) int function (WORD_LIST *);
38 
39 // (from http://git.savannah.gnu.org/cgit/bash.git/tree/builtins.h)
40 struct builtin
41 {
42   char* name;              /* The name that the user types. */
43   sh_builtin_func_t func;  /* The address of the invoked function. */
44   int flags;               /* One of the #defines above. */
45   const char * *long_doc;  /* NULL terminated array of strings. */
46   const char *short_doc;   /* Short version of documentation. */
47   char *handle;            /* for future use */
48 }
49 
50 extern(C) int dz_hello_builtin (WORD_LIST *list)
51 {
52   import core.runtime;
53   Runtime.initialize();
54 
55   import std.stdio;
56   if (list is null) {
57     writeln("Hello, world. It's Hello builtin command written in Dlang.");
58     return (EXECUTION_SUCCESS);
59   }
60 
61   import std.string : fromStringz;
62   import std.conv;
63 
64   string[] result = null;
65   while (list) {
66     result ~= to!string(fromStringz(list.word.word));
67     list = list.next;
68   }
69 
70   import std.format;
71   writefln("Hello, %-(%s %)", result);
72 
73   /*
74     If we invoke `Runtime.terminate();`, another call will cause
75     Segmentation Fault. Not sure when we should invoke this. FIXME.
76   */
77 
78   return (EXECUTION_SUCCESS);
79 }
80 
81 unittest {
82   import std.exception;
83   assertNotThrown(dz_hello_builtin(null));
84 }
85 
86 extern(C) static builtin dz_hello_struct =
87 {
88   name: cast (char*) "dz_hello",
89   func: &dz_hello_builtin,
90   flags: BUILTIN_ENABLED,
91   short_doc: cast (char*) "dz_hello",
92   handle: null,
93   long_doc: [
94     "Hello, it's from Dlang.",
95     "",
96     "A Hello builtin command written in Dlang.",
97     null
98   ],
99 };