#include "PikaObj.h" #include "dataArgs.h" #include "dataMemory.h" #include "dataString.h" #include "dataStrs.h" #include 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; }