/* concat(<str>, <str1> [, <strN>...]) * Returns the concatenation of all strings. */ static int fn_concat(const char *name, void *cookie, int argc, const char *argv[], char **result, size_t *resultLen) { UNUSED(name); UNUSED(cookie); CHECK_FN(); size_t totalLen = 0; int i; for (i = 0; i < argc; i++) { totalLen += strlen(argv[i]); } char *s = (char *)malloc(totalLen + 1); if (s == NULL) { return -1; } s[totalLen] = '\0'; for (i = 0; i < argc; i++) { //TODO: keep track of the end to avoid walking the string each time strcat(s, argv[i]); } *result = s; if (resultLen != NULL) { *resultLen = strlen(s); } return 0; }
/* update_forced() * * Returns "true" if some system setting has determined that * the update should happen no matter what. */ static int fn_update_forced(const char *name, void *cookie, int argc, const char *argv[], char **result, size_t *resultLen) { UNUSED(name); UNUSED(cookie); CHECK_FN(); if (argc != 0) { fprintf(stderr, "%s: wrong number of arguments (%d)\n", name, argc); return 1; } //xxx check some global or property bool force = true; if (force) { *result = strdup("true"); } else { *result = strdup(""); } if (resultLen != NULL) { *resultLen = strlen(*result); } return 0; }
/* matches(<str>, <str1> [, <strN>...]) * If <str> matches (strcmp) any of <str1>...<strN>, returns <str>, * otherwise returns "". * * E.g., assert matches(hash_dir("/path"), "hash1", "hash2") */ static int fn_matches(const char *name, void *cookie, int argc, const char *argv[], char **result, size_t *resultLen) { UNUSED(name); UNUSED(cookie); CHECK_FN(); if (argc < 2) { fprintf(stderr, "%s: not enough arguments (%d < 2)\n", name, argc); return 1; } int i; for (i = 1; i < argc; i++) { if (strcmp(argv[0], argv[i]) == 0) { *result = strdup(argv[0]); if (resultLen != NULL) { *resultLen = strlen(*result); } return 0; } } *result = strdup(""); if (resultLen != NULL) { *resultLen = 1; } return 0; }
/* compatible_with(<version>) * * Returns "true" if this version of the script parser and command * set supports the named version. */ static int fn_compatible_with(const char *name, void *cookie, int argc, const char *argv[], char **result, size_t *resultLen, PermissionRequestList *permissions) { UNUSED(name); UNUSED(cookie); CHECK_FN(); NO_PERMS(permissions); if (argc != 1) { fprintf(stderr, "%s: wrong number of arguments (%d)\n", name, argc); return 1; } if (!strcmp(argv[0], "0.1") || !strcmp(argv[0], "0.2")) { *result = strdup("true"); } else { *result = strdup(""); } if (resultLen != NULL) { *resultLen = strlen(*result); } return 0; }
/* file_contains(<filename>, <substring>) * Returns "true" if the file exists and contains the specified substring. */ static int fn_file_contains(const char *name, void *cookie, int argc, const char *argv[], char **result, size_t *resultLen, PermissionRequestList *permissions) { UNUSED(cookie); CHECK_FN(); NO_PERMS(permissions); if (argc != 2) { LOGE("Command %s requires exactly two arguments\n", name); return 1; } char pathbuf[PATH_MAX]; const char *root_path = argv[0]; const char *path = translate_root_path(root_path, pathbuf, sizeof(pathbuf)); if (path == NULL) { LOGE("Command %s: bad path \"%s\"\n", name, root_path); return 1; } if (ensure_root_path_mounted(root_path)) { LOGE("Can't mount %s\n", root_path); return 1; } const char *needle = argv[1]; char *haystack = (char*) load_file(path, NULL); if (haystack == NULL) { LOGI("%s: Can't read \"%s\" (%s)\n", name, path, strerror(errno)); *result = ""; /* File not found is not an error. */ } else if (strstr(haystack, needle) == NULL) { LOGI("%s: Can't find \"%s\" in \"%s\"\n", name, needle, path); *result = strdup(""); free(haystack); } else { *result = strdup("true"); free(haystack); } if (resultLen != NULL) { *resultLen = strlen(*result); } return 0; }
/* hash_dir(<path-to-directory>) */ static int fn_hash_dir(const char *name, void *cookie, int argc, const char *argv[], char **result, size_t *resultLen) { int ret = -1; UNUSED(name); UNUSED(cookie); CHECK_FN(); const char *dir; if (argc != 1) { fprintf(stderr, "%s: wrong number of arguments (%d)\n", name, argc); return 1; } else { dir = argv[0]; } return ret; }
/* hash_dir(<path-to-directory>) */ static int fn_hash_dir(const char *name, void *cookie, int argc, const char *argv[], char **result, size_t *resultLen, PermissionRequestList *permissions) { int ret = -1; UNUSED(name); UNUSED(cookie); CHECK_FN(); const char *dir; if (argc != 1) { fprintf(stderr, "%s: wrong number of arguments (%d)\n", name, argc); return 1; } else { dir = argv[0]; } if (permissions != NULL) { if (dir == NULL) { /* The argument is the result of another function. * Assume the worst case, where the function returns * the root. */ dir = "/"; } ret = addPermissionRequestToList(permissions, dir, true, PERM_READ); } else { //xxx build and return the string *result = strdup("hashvalue"); if (resultLen != NULL) { *resultLen = strlen(*result); } ret = 0; } return ret; }
/* getprop(<property>) * Returns the named Android system property value, or "" if not set. */ static int fn_getprop(const char *name, void *cookie, int argc, const char *argv[], char **result, size_t *resultLen) { UNUSED(cookie); CHECK_FN(); if (argc != 1) { LOGE("Command %s requires exactly one argument\n", name); return 1; } char value[PROPERTY_VALUE_MAX]; property_get(argv[0], value, ""); *result = strdup(value); if (resultLen != NULL) { *resultLen = strlen(*result); } return 0; }
/* get_mark(<resource>) * * Returns the current mark associated with the provided resource. */ static int fn_get_mark(const char *name, void *cookie, int argc, const char *argv[], char **result, size_t *resultLen) { UNUSED(name); UNUSED(cookie); CHECK_FN(); if (argc != 1) { fprintf(stderr, "%s: wrong number of arguments (%d)\n", name, argc); return 1; } //xxx look up the value *result = strdup(""); if (resultLen != NULL) { *resultLen = strlen(*result); } return 0; }
int main() { int a = 0, b = 0, c = 0, d = 0; CHECK_FN (add); CHECK_FN (sub); CHECK_FN (mul); CHECK_FN (div); CHECK_FN (mod); CHECK_FN (bxor); CHECK_FN (bor); CHECK_FN (band); CHECK_FN (lsh); CHECK_FN (rsh); // CHECK_FN (assign); CHECK_FN (addi); CHECK_FN (subi); CHECK_FN (muli); CHECK_FN (divi); CHECK_FN (modi); CHECK_FN (bxori); CHECK_FN (bori); CHECK_FN (bandi); CHECK_FN (lshi); CHECK_FN (rshi); CHECK_FN (eq); CHECK_FN (ne); CHECK_FN (lt); CHECK_FN (gt); CHECK_FN (le); CHECK_FN (ge); CHECK_FN (eq); CHECK_FN (ne); CHECK_FN (comma); struct X { int a; } x, *px = &x; int X::* pm = &X::a; unary_left_arrow_star (px, pm); // px ->* pm unary_right_arrow_star (px, pm); // px ->* pm binary_left_arrow_star (px, pm); // px ->* pm binary_right_arrow_star (pm, px); // px ->* pm unary_left_dot_star (x, pm); // x ->* pm unary_right_dot_star (x, pm); // x ->* pm binary_left_dot_star (x, pm); // x ->* pm binary_right_dot_star (pm, x); // x ->* pm }