00001
00002
00003
00004
00005
00006
00007 #include "unidefgen.h"
00008 #include "wvmoniker.h"
00009
00010 #include <ctype.h>
00011 #include <stdlib.h>
00012
00013 #include "wvlinkerhack.h"
00014
00015 WV_LINK(UniDefGen);
00016
00017
00018
00019
00020 static IUniConfGen *creator(WvStringParm s)
00021 {
00022 return new UniDefGen(wvcreate<IUniConfGen>(s));
00023 }
00024
00025
00026 static WvMoniker<IUniConfGen> reg("default", creator);
00027
00028
00029 static WvMoniker<IUniConfGen> reg2("wildcard", creator);
00030
00031
00032 UniConfKey UniDefGen::finddefault(const UniConfKey &key, char *p, char *q)
00033 {
00034 UniConfKey result;
00035
00036 if (!p)
00037 {
00038 q++;
00039 if (inner() && inner()->exists(q))
00040 return q;
00041 else
00042 return UniConfKey();
00043 }
00044
00045
00046 char *r = strchr(p, '/');
00047 if (r)
00048 *r++ = '\0';
00049
00050
00051 char *s = strchr(q, '\0');
00052 *s++ = '/';
00053 *s = 0;
00054 q = strcat(q, p);
00055
00056
00057 result = finddefault(key, r, q);
00058 if (result.numsegments())
00059 return result;
00060
00061
00062 *s++ = '*';
00063 *s = '\0';
00064 result = finddefault(key, r, q);
00065
00066 if (r)
00067 *--r = '/';
00068
00069 return result;
00070 }
00071
00072
00073 WvString UniDefGen::replacewildcard(const UniConfKey &key,
00074 const UniConfKey &defkey, WvStringParm in)
00075 {
00076
00077 if (in.len() < 2 || in[0] != '*')
00078 return in;
00079
00080 const char *s = in.cstr();
00081 int idx = atoi(s+1);
00082 if (idx == 0)
00083 return in;
00084
00085
00086 UniConfKey k(defkey);
00087 int loc = key.numsegments();
00088 for (int i = 0; i < idx; i++)
00089 {
00090 if (i != 0)
00091 {
00092 k = k.removelast();
00093 loc--;
00094 }
00095 while (!k.last().iswild())
00096 {
00097 k = k.removelast();
00098 loc--;
00099 if (k.isempty())
00100 {
00101
00102 return WvString();
00103 }
00104 }
00105 }
00106
00107
00108
00109 return key.segment(loc-1);
00110 }
00111
00112
00113 bool UniDefGen::keymap(const UniConfKey &unmapped_key, UniConfKey &mapped_key)
00114 {
00115 WvString tmp_key(unmapped_key), tmp("");
00116 char *p = tmp_key.edit();
00117
00118 tmp.setsize(strlen(tmp_key) * 2);
00119 char *q = tmp.edit();
00120 *q = '\0';
00121
00122 mapped_key = finddefault(unmapped_key, p, q);
00123 if (!mapped_key.numsegments())
00124 mapped_key = unmapped_key;
00125
00126
00127 return true;
00128 }
00129
00130
00131 WvString UniDefGen::get(const UniConfKey &key)
00132 {
00133 UniConfKey mapped_key;
00134 if (keymap(key, mapped_key))
00135 return replacewildcard(key, mapped_key,
00136 inner() ? inner()->get(mapped_key) : WvString());
00137 else
00138 return WvString::null;
00139 }
00140
00141
00142 void UniDefGen::set(const UniConfKey &key, WvStringParm value)
00143 {
00144
00145 if (inner())
00146 inner()->set(key, value);
00147 }