static char *pid2appid(pid_t pid, char *buf, size_t size) { char binary[PATH_MAX]; char path[PATH_MAX], *dir, *p, *base; unsigned int len; if (!pid || !get_binary(pid, binary, sizeof(binary))) return NULL; strncpy(path, binary, sizeof(path) - 1); path[sizeof(path) - 1] = '\0'; /* fetch basename */ if ((p = strrchr(path, '/')) == NULL || p == path) { strncpy(buf, binary, size - 1); buf[size - 1] = '\0'; return buf; } base = p-- + 1; /* fetch ../bin/<basename> */ if ((p = strprev(p, '/', path)) == NULL || p == path) goto return_base; if (strncmp(p + 1, "bin/", 4) != 0) goto return_base; else p--; /* fetch dir name above bin */ if ((dir = strprev(p, '/', path)) == NULL || dir == path) goto return_base; len = (size_t)(p - dir); /* fetch 'apps' dir */ p = dir - 1; if ((p = strprev(p, '/', path)) == NULL) goto return_base; if (strncmp(p + 1, "apps/", 5) != 0) goto return_base; if (len + 1 <= size) { strncpy(buf, dir + 1, len); buf[len] = '\0'; return buf; } return_base: strncpy(buf, base, size - 1); buf[size - 1] = '\0'; return buf; }
STATIC mp_obj_t call_method(jobject obj, const char *name, jarray methods, bool is_constr, mp_uint_t n_args, const mp_obj_t *args) { jvalue jargs[n_args]; // printf("methods=%p\n", methods); jsize num_methods = JJ(GetArrayLength, methods); for (int i = 0; i < num_methods; i++) { jobject meth = JJ(GetObjectArrayElement, methods, i); jobject name_o = JJ(CallObjectMethod, meth, Object_toString_mid); const char *decl = JJ(GetStringUTFChars, name_o, NULL); const char *arg_types = strchr(decl, '(') + 1; //const char *arg_types_end = strchr(arg_types, ')'); // printf("method[%d]=%p %s\n", i, meth, decl); const char *meth_name = NULL; const char *ret_type = NULL; if (!is_constr) { meth_name = strprev(arg_types, '.') + 1; ret_type = strprev(meth_name, ' ') - 1; ret_type = strprev(ret_type, ' ') + 1; int name_len = strlen(name); if (strncmp(name, meth_name, name_len/*arg_types - meth_name - 1*/) || meth_name[name_len] != '('/*(*/) { goto next_method; } } // printf("method[%d]=%p %s\n", i, meth, decl); // printf("!!!%s\n", arg_types); // printf("name=%p meth_name=%s\n", name, meth_name); bool found = true; for (int i = 0; i < n_args && *arg_types != ')'; i++) { if (!py2jvalue(&arg_types, args[i], &jargs[i])) { goto next_method; } if (*arg_types == ',') { arg_types++; } } if (*arg_types != ')') { goto next_method; } if (found) { // printf("found!\n"); jmethodID method_id = JJ(FromReflectedMethod, meth); jobject res; mp_obj_t ret; if (is_constr) { JJ(ReleaseStringUTFChars, name_o, decl); res = JJ(NewObjectA, obj, method_id, jargs); return new_jobject(res); } else { if (MATCH(ret_type, "void")) { JJ(CallVoidMethodA, obj, method_id, jargs); check_exception(); ret = mp_const_none; } else if (MATCH(ret_type, "int")) { jint res = JJ(CallIntMethodA, obj, method_id, jargs); check_exception(); ret = mp_obj_new_int(res); } else if (MATCH(ret_type, "boolean")) { jboolean res = JJ(CallBooleanMethodA, obj, method_id, jargs); check_exception(); ret = mp_obj_new_bool(res); } else if (is_object_type(ret_type)) { res = JJ(CallObjectMethodA, obj, method_id, jargs); check_exception(); ret = new_jobject(res); } else { JJ(ReleaseStringUTFChars, name_o, decl); nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "cannot handle return type")); } JJ(ReleaseStringUTFChars, name_o, decl); JJ(DeleteLocalRef, name_o); JJ(DeleteLocalRef, meth); return ret; } } next_method: JJ(ReleaseStringUTFChars, name_o, decl); JJ(DeleteLocalRef, name_o); JJ(DeleteLocalRef, meth); } nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "method not found")); }