1 /**
2  Wraps calls to xlXXX "functions" via the Excel4/Excel12 functions
3  */
4 module xlld.xl;
5 
6 import xlld.xlcall: XLOPER12, LPXLOPER12;
7 
8 version(unittest) {
9 
10     // this version(unittest) block effectively "implements" the Excel12v function
11     // so that the code can be unit tested without needing to link with the Excel SDK
12     import xlld.xlcallcpp: EXCEL12PROC, SetExcel12EntryPt;
13 
14     static this() {
15         SetExcel12EntryPt(&excel12UnitTest);
16     }
17 
18     static ~this() {
19         import xlld.wrap: gNumXlFree, gNumXlCoerce, gCoerced, gFreed;
20         import unit_threaded;
21         gCoerced[0 .. gNumXlCoerce].shouldBeSameSetAs(gFreed[0 .. gNumXlFree]);
22     }
23 
24 
25     extern(Windows) int excel12UnitTest (int xlfn, int numOpers, LPXLOPER12 *opers, LPXLOPER12 result) nothrow @nogc {
26 
27         import xlld.xlcall: XlType, xlretFailed, xlretSuccess, xlFree, xlCoerce;
28         import xlld.wrap: gReferencedType, gNumXlFree, gNumXlCoerce, gCoerced, gFreed, toXlOper;
29 
30         switch(xlfn) {
31 
32         default:
33             return xlretFailed;
34 
35         case xlFree:
36             assert(numOpers == 1);
37             auto oper = opers[0];
38 
39             gFreed[gNumXlFree++] = oper.val.str;
40 
41             if(oper.xltype == XlType.xltypeStr)
42                 *oper = "".toXlOper;
43 
44             return xlretSuccess;
45 
46         case xlCoerce:
47             assert(numOpers == 1);
48 
49             auto oper = opers[0];
50             gCoerced[gNumXlCoerce++] = oper.val.str;
51             *result = *oper;
52 
53             switch(oper.xltype) with(XlType) {
54 
55             case xltypeSRef:
56                 result.xltype = gReferencedType;
57                 break;
58 
59             case xltypeNum:
60             case xltypeStr:
61                 result.xltype = oper.xltype;
62                 break;
63 
64             case xltypeMissing:
65                 result.xltype = xltypeNil;
66                 break;
67 
68             default:
69             }
70 
71             return xlretSuccess;
72         }
73     }
74 }
75 
76 XLOPER12 coerce(LPXLOPER12 oper) nothrow @nogc {
77     import xlld.framework: Excel12f;
78     import xlld.xlcall: xlCoerce;
79 
80     XLOPER12 coerced;
81     LPXLOPER12[1] arg = [oper];
82     Excel12f(xlCoerce, &coerced, arg);
83     return coerced;
84 }
85 
86 void free(ref XLOPER12 oper) nothrow @nogc {
87     free(&oper);
88 }
89 
90 void free(LPXLOPER12 oper) nothrow @nogc {
91     import xlld.framework: Excel12f;
92     import xlld.xlcall: xlFree;
93 
94     LPXLOPER12[1] arg = [oper];
95     Excel12f(xlFree, null, arg);
96 }