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 }