/* Do not remove the headers from this file! see /USAGE for more info. */
#include <menu.h>
#include <security.h>
inherit MENUS;
inherit M_ACCESS;
/****** Begin private data and functions */
private:
MENU toplevel;
MENU_ITEM quit1, quit2, blank;
string fname;
mapping data;
string menu_title() {
return "\nSave file editor: \"" + fname + "\"\nVariables: " + implode(keys(data), ", ") + "\n";
}
void update() {
set_menu_title(toplevel, menu_title());
}
mapping load_data_file(string fn) {
string text = read_file(fn);
mapping result;
string name, value;
if (!text) return 0;
result = ([]);
foreach (string line in explode(text, "\n")) {
if (line[0] == '#') continue;
if (sscanf(line, "%s %s", name, value) != 2)
error("Syntax error in data file.\n");
result[name] = restore_variable(value);
}
return result;
}
int save_data_file(string fname) {
string result = "";
foreach (string var, mixed value in data)
result += var + " " + save_variable(value) + "\n";
return write_file(fname, result, 1);
}
mixed expression(string str) {
array parts = reg_assoc(str, ({ "\\$\\$", "\\$[a-zA-Z0-9_]+" }), ({ 1, 2 }));
string expr = "mixed expression(mapping internal_data) {\nreturn ";
mixed value;
object ob;
for (int i = 0; i < sizeof(parts[0]); i++) {
switch (parts[1][i]) {
case 0:
expr += parts[0][i];
break;
case 1:
expr += "$";
break;
case 2:
expr += "(internal_data[\"" + parts[0][i][1..] + "\"])";
break;
}
}
expr += ";\n}\n";
write_file("/tmp/dataedit.c", expr, 1);
if (ob = find_object("/tmp/dataedit"))
destruct(ob);
ob = load_object("/tmp/dataedit");
value = ob->expression(data);
destruct(ob);
rm("/tmp/dataedit.c");
return value;
}
void quit_and_discard() {
quit_menu_application();
}
void quit_and_save() {
if (save_data_file(fname))
quit_menu_application();
else
write("Failed.\n");
}
void remove_variable(string var) {
if (undefinedp(data[var]))
write("No such variable.\n");
else {
map_delete(data, var);
write("Done.\n");
}
update();
}
void remove_var() {
get_input_then_call( (: remove_variable :), "Variable: ");
}
void rename_variable(string oldv, string newv) {
if (!undefinedp(data[newv]))
write("A variable by that name already exists.\n");
else {
data[newv] = data[oldv];
map_delete(data, oldv);
write("Done.\n");
}
update();
}
void get_new_name(string old) {
if (undefinedp(data[old]))
write("No such variable.\n");
else {
get_input_then_call( (: rename_variable, old :), "New name: ");
}
}
void rename_var() {
get_input_then_call( (: get_new_name :), "Old name: ");
}
void set_variable(string vname, string valstr) {
mixed value = expression(valstr);
data[vname] = value;
write("Done.\n");
}
void get_value(string vname) {
get_input_then_call( (: set_variable, vname :), "Value: ");
}
void set_var() {
get_input_then_call( (: get_value :), "Variable: ");
}
void print_variable(string expr) {
printf("Value is: %O\n", expression(expr));
}
void print() {
get_input_then_call( (: print_variable :), "Expression: ");
}
void merge_file(string fname) {
mapping data2;
if (!(data2 = load_data_file(fname))) {
write("No such file.\n");
return;
}
foreach (mixed key, mixed value in data2) {
if (!data[key])
data[key] = value;
else {
if (typeof(data[key]) != typeof(value))
write("Type mismatch in merging variable '" + key + "': " +
typeof(data[key]) + " vs " + typeof(value) + "\n");
switch (typeof(value)) {
case "mapping":
case "array":
data[key] += value;
break;
default:
if (value == data[key])
continue;
write("While merging variable '" + key + "': Cannot merge objects of type " + typeof(value) + "\n");
}
}
}
update();
}
void merge() {
get_input_then_call( (: merge_file :), "File to merge with: ");
}
void save_to_file(string file) {
if (save_data_file(file)) {
fname = file;
update();
} else write("Failed.\n");
}
void save_to() {
get_input_then_call( (: save_to_file :), "New filename: ");
}
/****** End of private functions */
public:
void start_menu(string file) {
if (!data = load_data_file(fname = file)) {
write(file + ": No such file.\n");
destruct(this_object());
return;
}
toplevel = new_menu(menu_title());
blank = new_seperator("");
#define NME(X) add_menu_item(toplevel, new_menu_item X)
add_menu_item(toplevel, blank);
NME(("Delete Variable", (: remove_var :), "d"));
NME(("Rename Variable", (: rename_var :), "r"));
NME(("Set Variable", (: set_var :), "="));
NME(("Print Expression", (: print :), "p"));
NME(("Merge Datafile", (: merge :), "m"));
NME(("Save as ...", (: save_to :), "s"));
NME(("Quit and Save", (: quit_and_save :), "q"));
NME(("Quit w/o Saving", (: quit_and_discard :), "Q"));
add_menu_item(toplevel, blank);
set_menu_prompt(toplevel, "[dr=pmsqQ] ");
allow_empty_selection(toplevel);
init_menu_application(toplevel);
}
void create() {
set_privilege(1);
}