comparison shell/shdc/shdc.c @ 0:0cfcc391201f

initial from svn dyncall-1745
author Daniel Adler
date Thu, 19 Mar 2015 22:26:28 +0100
parents
children 5e159be89d73
comparison
equal deleted inserted replaced
-1:000000000000 0:0cfcc391201f
1 /*
2 Package: dyncall
3 File: bindings/shell.c
4 Description: printf(1) style function call mechanism
5 License:
6 Copyright (c) 2007-2014 Daniel Adler <dadler@uni-goettingen.de>,
7 Tassilo Philipp <tphilipp@potion-studios.com>
8
9 Permission to use, copy, modify, and distribute this software for any
10 purpose with or without fee is hereby granted, provided that the above
11 copyright notice and this permission notice appear in all copies.
12
13 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20
21 */
22
23 #include "../../dyncall/dyncall/dyncall.h"
24 #include "../../dyncall/dynload/dynload.h"
25 #include "../../dyncall/dyncall/dyncall_signature.h"
26 #include <stdio.h>
27 #include <stdlib.h> /* needed on some platforms to make atof work _at_runtime_ */
28
29 #define SHDC_VERSION "0.8"
30
31
32 void usage(const char* s)
33 {
34 printf(
35 "Usage: %s -l SO\n"
36 " %s -c SO SYM SIG [ARGS]\n"
37 " %s -v\n"
38 " where SO is the name of the shared object.\n"
39 "\n"
40 " -l lists all symbol names in the shared object\n"
41 " -c calls function in the shared object, where SYM is the symbol name,\n"
42 " SIG the symbol's type signature, and ARGS the arguments.\n"
43 " -v displays the binding's version\n",
44 s, s, s
45 );
46 }
47
48
49 int main(int argc, char* argv[])
50 {
51 const char* libPath;
52 const char* symName;
53 const DCsigchar* sig;
54 const DCsigchar* i;
55 void* sym;
56 DCCallVM* vm;
57 DLLib* dlLib;
58 DLSyms* dlSyms;
59 int c, l;
60
61 if(argc == 2 && strcmp(argv[1], "-v") == 0) {
62 printf(SHDC_VERSION"\n");
63 return 0;
64 }
65
66 /* Parse arguments and check validity. */
67 /* Need at least shared object name and action, and symbol name and signature string for call. */
68 if(argc < 2) {
69 usage(argv[0]);
70 return 1;
71 }
72
73 c = strcmp(argv[1], "-c");
74 l = strcmp(argv[1], "-l");
75 if((c != 0 && l != 0) || (c == 0 && argc < 4)) {
76 usage(argv[0]);
77 return 1;
78 }
79
80
81 libPath = argv[2];
82
83 /* List symbols, if 'ls', else it must be 'call', so proceed to call. */
84 if(l == 0) {
85 dlSyms = dlSymsInit(libPath);
86 if(!dlSyms) {
87 printf("Can't load \"%s\".\n", libPath);
88 usage(argv[0]);
89 return 1;
90 }
91
92 /* hacky: reuse c and l */
93 for(c=dlSymsCount(dlSyms), l=0; l<c; ++l)
94 printf("%s\n", dlSymsName(dlSyms, l));
95
96 dlSymsCleanup(dlSyms);
97 }
98 else {
99 /* Check if number of arguments matches sigstring spec. */
100 /*if(n != argc-4)@@@*/ /* 0 is prog, 1 is flag, 2 is lib, 3 is symbol name, 4 is sig */
101
102 /* Load library and get a pointer to the symbol to call. */
103 dlLib = dlLoadLibrary(libPath);
104 if(!dlLib) {
105 printf("Can't load \"%s\".\n", libPath);
106 usage(argv[0]);
107 return 1;
108 }
109
110 symName = argv[3];
111 sig = i = argv[4];
112
113 sym = dlFindSymbol(dlLib, symName);
114 if(!sym) {
115 printf("Can't find symbol \"%s\".\n", symName);
116 dlFreeLibrary(dlLib);
117 usage(argv[0]);
118 return 1;
119 }
120
121
122 vm = dcNewCallVM(4096/*@@@*/);/*@@@ error checking */
123 dcReset(vm);
124
125 while(*i != '\0' && *i != DC_SIGCHAR_ENDARG) {
126 switch(*i) {
127 case DC_SIGCHAR_CC_PREFIX:
128 switch(*++i) {
129 case DC_SIGCHAR_CC_ELLIPSIS: dcMode(vm, DC_CALL_C_ELLIPSIS); break;
130 case DC_SIGCHAR_CC_STDCALL: dcMode(vm, DC_CALL_C_X86_WIN32_STD); break;
131 case DC_SIGCHAR_CC_FASTCALL_GNU: dcMode(vm, DC_CALL_C_X86_WIN32_FAST_GNU); break;
132 case DC_SIGCHAR_CC_FASTCALL_MS: dcMode(vm, DC_CALL_C_X86_WIN32_FAST_MS); break;
133 case DC_SIGCHAR_CC_THISCALL_MS: dcMode(vm, DC_CALL_C_X86_WIN32_THIS_MS); break;
134 /* @@@ extend with other modes when they become available */
135 }
136 sig += 2;
137 break;
138
139 case DC_SIGCHAR_BOOL: dcArgBool (vm, (DCbool) atoi (argv[5+i-sig] )); break;
140 case DC_SIGCHAR_CHAR: dcArgChar (vm, (DCchar) atoi (argv[5+i-sig] )); break;
141 case DC_SIGCHAR_UCHAR: dcArgChar (vm, (DCchar)(DCuchar) atoi (argv[5+i-sig] )); break;
142 case DC_SIGCHAR_SHORT: dcArgShort (vm, (DCshort) atoi (argv[5+i-sig] )); break;
143 case DC_SIGCHAR_USHORT: dcArgShort (vm, (DCshort)(DCushort)atoi (argv[5+i-sig] )); break;
144 case DC_SIGCHAR_INT: dcArgInt (vm, (DCint) strtol (argv[5+i-sig],NULL,10)); break;
145 case DC_SIGCHAR_UINT: dcArgInt (vm, (DCint)(DCuint) strtoul (argv[5+i-sig],NULL,10)); break;
146 case DC_SIGCHAR_LONG: dcArgLong (vm, (DClong) strtol (argv[5+i-sig],NULL,10)); break;
147 case DC_SIGCHAR_ULONG: dcArgLong (vm, (DCulong) strtoul (argv[5+i-sig],NULL,10)); break;
148 case DC_SIGCHAR_LONGLONG: dcArgLongLong(vm, (DClonglong) strtoll (argv[5+i-sig],NULL,10)); break;
149 case DC_SIGCHAR_ULONGLONG: dcArgLongLong(vm, (DCulonglong) strtoull(argv[5+i-sig],NULL,10)); break;
150 case DC_SIGCHAR_FLOAT: dcArgFloat (vm, (DCfloat) atof (argv[5+i-sig] )); break;
151 case DC_SIGCHAR_DOUBLE: dcArgDouble (vm, (DCdouble) atof (argv[5+i-sig] )); break;
152 case DC_SIGCHAR_POINTER: dcArgPointer (vm, (DCpointer) argv[5+i-sig] ); break;
153 case DC_SIGCHAR_STRING: dcArgPointer (vm, (DCpointer) argv[5+i-sig] ); break;
154 }
155 ++i;
156 }
157
158 if(*i == DC_SIGCHAR_ENDARG)
159 ++i;
160
161 switch(*i) {
162 case '\0':
163 case DC_SIGCHAR_VOID: dcCallVoid (vm,sym) ; break;
164 case DC_SIGCHAR_BOOL: printf("%d\n", dcCallBool (vm,sym)); break;
165 case DC_SIGCHAR_CHAR: printf("%d\n", dcCallChar (vm,sym)); break;
166 case DC_SIGCHAR_UCHAR: printf("%d\n", dcCallChar (vm,sym)); break;
167 case DC_SIGCHAR_SHORT: printf("%d\n", dcCallShort (vm,sym)); break;
168 case DC_SIGCHAR_USHORT: printf("%d\n", dcCallShort (vm,sym)); break;
169 case DC_SIGCHAR_INT: printf("%d\n", dcCallInt (vm,sym)); break;
170 case DC_SIGCHAR_UINT: printf("%d\n", dcCallInt (vm,sym)); break;
171 case DC_SIGCHAR_LONG: printf("%d\n", dcCallLong (vm,sym)); break;
172 case DC_SIGCHAR_ULONG: printf("%d\n", dcCallLong (vm,sym)); break;
173 case DC_SIGCHAR_LONGLONG: printf("%lld\n", dcCallLongLong(vm,sym)); break;
174 case DC_SIGCHAR_ULONGLONG: printf("%lld\n", dcCallLongLong(vm,sym)); break;
175 case DC_SIGCHAR_FLOAT: printf("%g\n", dcCallFloat (vm,sym)); break;
176 case DC_SIGCHAR_DOUBLE: printf("%g\n", dcCallDouble (vm,sym)); break;
177 case DC_SIGCHAR_POINTER: printf("%x\n", dcCallPointer (vm,sym)); break;
178 case DC_SIGCHAR_STRING: printf( dcCallPointer (vm,sym)); break;
179 }
180
181 dlFreeLibrary(dlLib);
182 dcFree(vm);
183 }
184
185 return 0;
186 }
187