00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "uitree.hh"
00025
00026
00027
00028 Tree makeSubFolderChain(Tree path, Tree elem);
00029 Tree putFolder(Tree folder, Tree item);
00030 Tree getFolder (Tree folder, Tree ilabel);
00031
00032
00033 static void error(const char * s, Tree t)
00034 {
00035 fprintf(stderr, "ERROR : %s (%p)\n", s, t);
00036 }
00037
00038 #define ERROR(s,t) error(s,t); exit(1)
00039
00040
00041
00042
00043
00044
00045 #if 0
00046
00047 static bool findKey (Tree pl, Tree key, Tree& val)
00048 {
00049 if (isNil(pl)) return false;
00050 if (left(hd(pl)) == key) { val= right(hd(pl)); return true; }
00051 return findKey (tl(pl), key, val);
00052 }
00053
00054 static Tree updateKey (Tree pl, Tree key, Tree val)
00055 {
00056 if (isNil(pl)) return cons ( cons(key,val), nil );
00057 if (left(hd(pl)) == key) return cons ( cons(key,val), tl(pl) );
00058 return cons ( hd(pl), updateKey( tl(pl), key, val ));
00059 }
00060
00061 static Tree removeKey (Tree pl, Tree key)
00062 {
00063 if (isNil(pl)) return nil;
00064 if (left(hd(pl)) == key) return tl(pl);
00065 return cons (hd(pl), removeKey(tl(pl), key));
00066 }
00067
00068 #else
00069
00070
00071
00072 static bool isBefore(Tree k1, Tree k2)
00073 {
00074
00075 if (isList(k1)) { k1 = tl(k1); }
00076 if (isList(k2)) { k2 = tl(k2); }
00077
00078
00079 Sym s1, s2;
00080 if (!isSym(k1->node(), &s1)) {
00081 ERROR("the node of the tree is not a symbol", k1);
00082 }
00083 if (!isSym(k2->node(), &s2)) {
00084 ERROR("the node of the tree is not a symbol", k2);
00085 }
00086
00087
00088 return strcmp(name(s1), name(s2)) < 0;
00089 }
00090
00091
00092 static bool findKey (Tree pl, Tree key, Tree& val)
00093 {
00094 if (isNil(pl)) return false;
00095 if (left(hd(pl)) == key) { val = right(hd(pl)); return true; }
00096 if (isBefore(left(hd(pl)),key)) return findKey (tl(pl), key, val);
00097 return false;
00098 }
00099
00100 static Tree updateKey (Tree pl, Tree key, Tree val)
00101 {
00102 if (isNil(pl)) return cons ( cons(key,val), nil );
00103 if (left(hd(pl)) == key) return cons ( cons(key,val), tl(pl) );
00104 if (isBefore(left(hd(pl)),key)) return cons ( hd(pl), updateKey( tl(pl), key, val ));
00105 return cons(cons(key,val), pl);
00106 }
00107
00108 static Tree removeKey (Tree pl, Tree key)
00109 {
00110 if (isNil(pl)) return nil;
00111 if (left(hd(pl)) == key) return tl(pl);
00112 if (isBefore(left(hd(pl)),key)) return cons (hd(pl), removeKey(tl(pl), key));
00113 return pl;
00114 }
00115 #endif
00116
00117
00118
00119
00120
00121 Sym UIFOLDER = symbol ("uiFolder");
00122 Tree uiFolder(Tree label, Tree elements) { return tree(UIFOLDER, label, elements); }
00123 bool isUiFolder(Tree t) { return isTree(t, UIFOLDER); }
00124 bool isUiFolder(Tree t, Tree& label, Tree& elements) { return isTree(t, UIFOLDER, label, elements); }
00125
00126 Sym UIWIDGET = symbol ("uiWidget");
00127 Tree uiWidget(Tree label, Tree varname, Tree sig) { return tree(UIWIDGET, label, varname, sig); }
00128 bool isUiWidget(Tree t, Tree& label, Tree& varname, Tree& sig) { return isTree(t, UIWIDGET, label, varname, sig); }
00129
00130
00131
00132
00133 Tree putFolder(Tree folder, Tree item)
00134 {
00135 Tree label, content;
00136
00137 if ( ! isUiFolder(folder, label, content)) { fprintf(stderr, "ERROR in addFolder : not a folder\n"); }
00138 return uiFolder(label, updateKey(content, uiLabel(item), item));
00139 }
00140
00141
00142 Tree getFolder (Tree folder, Tree ilabel)
00143 {
00144 Tree flabel, content, item;
00145 if (!isUiFolder(folder, flabel, content)) { fprintf(stderr, "ERROR in getFolder : not a folder\n"); }
00146 if (findKey(content, ilabel, item)) {
00147 return item;
00148 } else {
00149 return nil;
00150 }
00151 }
00152
00153
00154 Tree makeSubFolderChain(Tree path, Tree elem)
00155 {
00156 if (isNil(path)) {
00157 return elem;
00158 } else {
00159 return putFolder(uiFolder(hd(path)), makeSubFolderChain(tl(path),elem));
00160 }
00161 }
00162
00163
00164 Tree putSubFolder(Tree folder, Tree path, Tree item)
00165 {
00166 if (isNil(path)) {
00167 return putFolder(folder, item);
00168 } else {
00169 Tree subfolder = getFolder(folder, hd(path));
00170 if (isUiFolder(subfolder)) {
00171 return putFolder(folder, putSubFolder(subfolder, tl(path), item));
00172 } else {
00173 return putFolder(folder, makeSubFolderChain(path, item));
00174 }
00175 }
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192