#include #include "PikaObj.h" #include "dataArgs.h" #include "dataMemory.h" #include "dataString.h" #include "dataStrs.h" static int32_t loadArgByType(PikaObj* self, char* definedName, char* definedType, char* sourceArgPath, Args* args) { if (strEqu(definedType, "any")) { if (0 == obj_getAnyArg(self, definedName, sourceArgPath, args)) { return 0; } /* solve arg faild */ return 3; } if (strEqu(definedType, "str")) { /* solve the string type */ char* directStr = strsGetDirectStr(args, sourceArgPath); if (NULL != directStr) { /* direct value */ args_setStr(args, definedName, directStr); /* ok */ return 0; } /* reference value */ char* refStr = obj_getStr(self, sourceArgPath); if (NULL == refStr) { /* faild */ return 1; } args_setStr(args, definedName, refStr); /* succeed */ return 0; } if (strEqu(definedType, "int")) { /* solve the int32_t type */ args_setInt(args, definedName, 0); if ((sourceArgPath[0] >= '0') && (sourceArgPath[0] <= '9')) { /* direct value */ args_set(args, definedName, sourceArgPath); /* succeed */ return 0; } /* reference value */ if (!obj_isArgExist(self, sourceArgPath)) { /* can not get reference */ return 3; } int32_t referenceVal = obj_getInt(self, sourceArgPath); args_setInt(args, definedName, referenceVal); /* succeed */ return 0; } if (strEqu(definedType, "float")) { /* solve the float type */ args_setFloat(args, definedName, 0); if ((sourceArgPath[0] >= '0') && (sourceArgPath[0] <= '9')) { /* direct value */ args_set(args, definedName, sourceArgPath); /* succeed */ return 0; } /* reference value */ if (!obj_isArgExist(self, sourceArgPath)) { /* can not get reference */ return 3; } float referenceVal = obj_getFloat(self, sourceArgPath); args_setFloat(args, definedName, referenceVal); /* succeed */ return 0; } if (strEqu(definedType, "pointer")) { /* only support reference value */ if (!obj_isArgExist(self, sourceArgPath)) { /* can not get reference */ return 3; } void* ptr = obj_getPtr(self, sourceArgPath); args_setPtr(args, definedName, ptr); return 0; } /* type match faild */ return 2; } char* getTypeVal(Args* buffs, char* typeToken) { if (!strIsContain(typeToken, ':')) { return strsCopy(buffs, ""); } return strsGetLastToken(buffs, typeToken, ':'); } static Args* getArgsByNameMatch(PikaObj* self, char* typeList, char* argList) { Args* buffs = New_strBuff(); char* typeListBuff = strsCopy(buffs, typeList); Args* args = New_args(NULL); while (1) { char* typeToken = strsPopToken(buffs, typeListBuff, ','); /* poped all type from typeList */ if (0 == typeToken[0]) { break; } char* typeName = strsGetFirstToken(buffs, typeToken, ':'); char* typeVal = getTypeVal(buffs, typeToken); char* argListBuff = strsCopy(buffs, argList); while (1) { char* argToken = strsPopToken(buffs, argListBuff, ','); char* argName = strsGetFirstToken(buffs, argToken, '='); char* argVal = strsGetLastToken(buffs, argToken, '='); if (0 == argToken[0]) { /* arg poped finised */ break; } if (!strEqu(typeName, argName)) { /* name not match */ continue; } if (0 != loadArgByType(self, typeName, typeVal, argVal, args)) { args_deinit(args); args_deinit(buffs); return NULL; } } } args_deinit(buffs); return args; } static Args* getArgsBySort(PikaObj* self, char* typeList, char* argList) { Args* buffs = New_strBuff(); char* typeListBuff = strsCopy(buffs, typeList); char* argListBuff = strsCopy(buffs, argList); Args* args = New_args(NULL); while (1) { char* typeToken = strsPopToken(buffs, typeListBuff, ','); char* argToken = strsPopToken(buffs, argListBuff, ','); if ((0 == argToken[0]) || (0 == typeToken[0])) { /* arg or type poped finised */ break; } char* typeName = strsGetFirstToken(buffs, typeToken, ':'); char* typeVal = getTypeVal(buffs, typeToken); char* argPath = argToken; if (0 != loadArgByType(self, typeName, typeVal, argPath, args)) { args_deinit(args); args_deinit(buffs); return NULL; } } args_deinit(buffs); return args; } static Args* getArgsBySentence(PikaObj* self, char* typeList, char* argList) { if (strIsContain(argList, '=')) { return getArgsByNameMatch(self, typeList, argList); } return getArgsBySort(self, typeList, argList); } static char* getMethodDeclearation(PikaObj* obj, char* methodName) { Args* buffs = New_strBuff(); char* methodDeclearationPath = strsAppend(buffs, "[md]", methodName); char* res = obj_getStr(obj, methodDeclearationPath); args_deinit(buffs); return res; } static void* getMethodPtr(PikaObj* methodHost, char* methodName) { Args* buffs = New_strBuff(); char* methodPtrPath = strsAppend(buffs, "[mp]", methodName); void* res = obj_getPtr(methodHost, methodPtrPath); args_deinit(buffs); return res; } Args* obj_invoke(PikaObj* self, char* cmd) { /* the Args returned need to be deinit */ Args* res = New_args(NULL); args_setErrorCode(res, 0); Args* buffs = New_strBuff(); char* methodToken = strsGetFirstToken(buffs, cmd, '('); char* methodPath = methodToken; Args* args = NULL; PikaObj* methodHostObj = obj_getObj(self, methodPath, 1); PikaObj* methodHostClass = NULL; if (NULL == methodHostObj) { /* error, not found object */ args_setErrorCode(res, 1); args_setSysOut(res, "[error] runner: object no found."); goto exit; } char* methodName = strsGetLastToken(buffs, methodPath, '.'); void* classPtr = obj_getPtr(methodHostObj, "_clsptr"); char* methodHostClassName = strsAppend(buffs, "classObj-", obj_getName(methodHostObj)); methodHostClass = obj_getClassObjByNewFun(methodHostObj, methodHostClassName, classPtr); /* get method Ptr */ void (*methodPtr)(PikaObj * self, Args * args) = getMethodPtr(methodHostClass, methodName); char* methodDecInClass = getMethodDeclearation(methodHostClass, methodName); /* assert method*/ if ((NULL == methodDecInClass) || (NULL == methodPtr)) { /* error, method no found */ args_setErrorCode(res, 2); args_setSysOut(res, "[error] runner: method no found."); goto exit; } char* methodDec = strsCopy(buffs, methodDecInClass); /* free method host class to save memory */ obj_deinit(methodHostClass); methodHostClass = NULL; /* get type list */ char* typeList = strsCut(buffs, methodDec, '(', ')'); if (typeList == NULL) { /* typeList no found */ args_setErrorCode(res, 3); args_setSysOut(res, "[error] runner: type list no found."); goto exit; } /* get arg list */ char* argList = strsCut(buffs, cmd, '(', ')'); { if (argList == NULL) { /* argL List no found */ args_setErrorCode(res, 4); args_setSysOut(res, "[error] runner: arg list no found."); goto exit; } } /* get return type */ char* returnType = strsGetLastToken(buffs, methodDec, ')'); /* get args */ args = getArgsBySentence(self, typeList, argList); if (NULL == args) { /* get args faild */ args_setErrorCode(res, 5); args_setSysOut(res, "[error] runner: solve arg faild."); goto exit; } obj_setErrorCode(methodHostObj, 0); obj_setSysOut(methodHostObj, ""); /* run method */ methodPtr(methodHostObj, args); /* transfer return type */ args_setStr(res, "returnType", returnType); /* transfer return */ args_copyArgByName(args, "return", res); /* transfer sysOut */ char* sysOut = obj_getSysOut(methodHostObj); if (NULL != sysOut) { args_setSysOut(res, sysOut); } /* transfer errCode */ if (0 != obj_getErrorCode(methodHostObj)) { /* method error */ args_setErrorCode(res, 6); } goto exit; exit: if (NULL != buffs) { args_deinit(buffs); } if (NULL != methodHostClass) { obj_deinit(methodHostClass); } if (NULL != args) { args_deinit(args); } return res; }