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 static Tree makeSubFolderChain(Tree path, Tree elem);
00029 static Tree putFolder(Tree folder, Tree item);
00030 static 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
00111 static Tree addKey (Tree pl, Tree key, Tree val)
00112 {
00113 if (isNil(pl)) return cons ( cons(key,val), nil );
00114 if (isBefore(key, left(hd(pl)))) return cons(cons(key,val), pl);
00115 return cons ( hd(pl), addKey( tl(pl), key, val ));
00116 }
00117
00118
00119 #if 0
00120 static Tree removeKey (Tree pl, Tree key)
00121 {
00122 if (isNil(pl)) return nil;
00123 if (left(hd(pl)) == key) return tl(pl);
00124 if (isBefore(left(hd(pl)),key)) return cons (hd(pl), removeKey(tl(pl), key));
00125 return pl;
00126 }
00127 #endif
00128 #endif
00129
00130
00131
00132
00133
00134 Sym UIFOLDER = symbol ("uiFolder");
00135 Tree uiFolder(Tree label, Tree elements) { return tree(UIFOLDER, label, elements); }
00136 bool isUiFolder(Tree t) { return isTree(t, UIFOLDER); }
00137 bool isUiFolder(Tree t, Tree& label, Tree& elements) { return isTree(t, UIFOLDER, label, elements); }
00138
00139 Sym UIWIDGET = symbol ("uiWidget");
00140 Tree uiWidget(Tree label, Tree varname, Tree sig) { return tree(UIWIDGET, label, varname, sig); }
00141 bool isUiWidget(Tree t, Tree& label, Tree& varname, Tree& sig) { return isTree(t, UIWIDGET, label, varname, sig); }
00142
00143
00144
00145
00146 Tree putFolder(Tree folder, Tree item)
00147 {
00148 Tree label, content;
00149
00150 if ( ! isUiFolder(folder, label, content)) { fprintf(stderr, "ERROR in addFolder : not a folder\n"); }
00151 return uiFolder(label, updateKey(content, uiLabel(item), item));
00152 }
00153
00154
00155 Tree addToFolder(Tree folder, Tree item)
00156 {
00157 Tree label, content;
00158
00159 if ( ! isUiFolder(folder, label, content)) { fprintf(stderr, "ERROR in addFolder : not a folder\n"); }
00160 return uiFolder(label, addKey(content, uiLabel(item), item));
00161 }
00162
00163
00164 Tree getFolder (Tree folder, Tree ilabel)
00165 {
00166 Tree flabel, content, item;
00167 if (!isUiFolder(folder, flabel, content)) { fprintf(stderr, "ERROR in getFolder : not a folder\n"); }
00168 if (findKey(content, ilabel, item)) {
00169 return item;
00170 } else {
00171 return nil;
00172 }
00173 }
00174
00175
00176 Tree makeSubFolderChain(Tree path, Tree elem)
00177 {
00178 if (isNil(path)) {
00179 return elem;
00180 } else {
00181 return putFolder(uiFolder(hd(path)), makeSubFolderChain(tl(path),elem));
00182 }
00183 }
00184
00185
00186 Tree putSubFolder(Tree folder, Tree path, Tree item)
00187 {
00188 if (isNil(path)) {
00189
00190 return addToFolder(folder, item);
00191 } else {
00192 Tree subfolder = getFolder(folder, hd(path));
00193 if (isUiFolder(subfolder)) {
00194 return putFolder(folder, putSubFolder(subfolder, tl(path), item));
00195 } else {
00196 return putFolder(folder, makeSubFolderChain(path, item));
00197 }
00198 }
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215