DllExport int call_conv change_char(CTXTdecl) { char *str_in; int pos; char *c, *str_out; str_in = (char *) extern_ptoc_string(1); str_out = (char *) calloc(strlen(str_in)+1, sizeof(char)); strcpy(str_out, str_in); pos = extern_ptoc_int(2); c = (char *) extern_ptoc_string(3); str_out[pos-1] = c[0]; /* Now that we have constructed a new symbol, we must ensure that it appears in the symbol table. This can be done using function string_find() that searches the symbol table for the symbol, and if the symbol does not appear there, it inserts it. If we are sure that the symbol already appeared in the symbol table there is no need to use string_find(). */ extern_ctop_string(CTXTc 4, str_out); free(str_out); // extern_ctop_string(4, (char *) string_find(str_out,4)); return TRUE; }
DllExport int call_conv pl_encode_url() { char *url; char *dir, *file_base, *suffix; check_thread_context url = (char *) extern_ptoc_string(1); encode(url, &dir, &file_base, &suffix); c2p_string(CTXTc dir, p2p_car(reg_term(CTXTc 2))); c2p_string(CTXTc file_base, p2p_car(p2p_cdr(reg_term(CTXTc 2)))); c2p_string(CTXTc suffix, p2p_car(p2p_cdr(p2p_cdr(reg_term(CTXTc 2))))); return TRUE; }
DllExport int call_conv expand_file() { char *file_name; char *expanded_file_name; int tlen, lose; struct passwd *pw; register char *new_dir, *p, *user_name; #ifdef MULTI_THREAD if( NULL == th) th = xsb_get_main_thread(); #endif file_name = extern_ptoc_string(1); /* If file_name is absolute, flush ...// and detect /./ and /../. If no /./ or /../ we can return right away. */ if (file_name[0] == '/') { p = file_name; lose = 0; while (*p) { if (p[0] == '/' && p[1] == '/') file_name = p + 1; if (p[0] == '/' && p[1] == '~') file_name = p + 1, lose = 1; if (p[0] == '/' && p[1] == '.' && (p[2] == '/' || p[2] == 0 || (p[2] == '.' && (p[3] == '/' || p[3] == 0)))) lose = 1; p++; } if (!lose) { ctop_string(CTXTc 2, file_name); return TRUE; } } /* Now determine directory to start with and put it in new_dir */ new_dir = 0; if (file_name[0] == '~' && file_name[1] == '/') /* prefix ~/ */ { if (!(new_dir = (char *) getenv("HOME"))) new_dir = ""; file_name++; } else /* prefix ~username/ */ { for (p = file_name; *p && (*p != '/'); p++); user_name = alloca(p - file_name + 1); bcopy (file_name, user_name, p - file_name); user_name[p - file_name] = 0; pw = (struct passwd *) getpwnam(user_name + 1); if (!pw) { fprintf(stderr, "++Error: \"%s\" is not a registered user\n", user_name + 1); ctop_string(CTXTc 2, file_name); /* return the input file name unchanged */ return TRUE; } file_name = p; new_dir = pw -> pw_dir; } /* Now concatenate the directory and name to new space in the stack frame */ tlen = (new_dir ? strlen(new_dir) + 1 : 0) + strlen(file_name) + 1; expanded_file_name = alloca(tlen); if (new_dir) strcpy(expanded_file_name, new_dir); strcat(expanded_file_name, file_name); /* Make sure you insert the newly created symbol into the symbol table. */ ctop_string(CTXTc 2, string_find(expanded_file_name, 1)); return TRUE; }