ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/cfperl.xs
(Generate patch)

Comparing deliantra/server/server/cfperl.xs (file contents):
Revision 1.131 by root, Mon Jan 8 18:18:35 2007 UTC vs.
Revision 1.151 by root, Tue Jan 23 01:29:51 2007 UTC

101 101
102unordered_vector<attachable *> attachable::mortals; 102unordered_vector<attachable *> attachable::mortals;
103 103
104attachable::~attachable () 104attachable::~attachable ()
105{ 105{
106 assert (!(flags & F_BORROWED)); 106 assert (!self);
107} 107}
108 108
109int 109int
110attachable::refcnt_cnt () const 110attachable::refcnt_cnt () const
111{ 111{
117{ 117{
118 if (self 118 if (self
119 && SvREFCNT (self) == 1 119 && SvREFCNT (self) == 1
120 && !HvTOTALKEYS (self)) 120 && !HvTOTALKEYS (self))
121 { 121 {
122 flags &= ~F_BORROWED;
123 refcnt_inc (); 122 refcnt_inc ();
124 SvREFCNT_dec ((SV *)self); 123 SvREFCNT_dec ((SV *)self);
125 } 124 }
126} 125}
127 126
128// check wether the object really is dead 127// check wether the object really is dead
129void 128void
130attachable::do_check () 129attachable::do_check ()
131{ 130{
132 if (refcnt > 0) 131 if (refcnt > 0 || refcnt_cnt () > 0)
133 return; 132 return;
134 133
135 optimise (); 134 destroy ();
136 135
137 if (self) 136 if (self)
138 { 137 {
139 if (refcnt + SvREFCNT (self) > 0) 138 hv_clear (self);
140 return; 139 sv_unmagic ((SV *)self, PERL_MAGIC_ext);
141
142 assert (flags & F_BORROWED);
143
144 flags &= ~F_BORROWED;
145 refcnt_inc ();
146 SvREFCNT_dec (self); 140 SvREFCNT_dec (self);
147 self = 0; 141 self = 0;
148 } 142 }
149
150 if (refcnt > 0)
151 return;
152
153 destroy ();
154} 143}
155 144
156void 145void
157attachable::do_destroy () 146attachable::do_destroy ()
158{ 147{
175} 164}
176 165
177void 166void
178attachable::check_mortals () 167attachable::check_mortals ()
179{ 168{
180 for (int i = 0; i < mortals.size (); ) 169 static int i = 0;
170
171 for (;;)
181 { 172 {
173 if (i >= mortals.size ())
174 {
175 i = 0;
176
177 if (mortals.size () > 1000)
178 fprintf (stderr, "mortal queue size (%d) exceeds 1000.\n", mortals.size ());
179
180 break;
181 }
182
182 attachable *obj = mortals [i]; 183 attachable *obj = mortals [i];
183 184
184 obj->refcnt_chk (); // unborrow from perl, if necessary 185 obj->refcnt_chk (); // unborrow from perl, if necessary
185 186
187 //if (obj->refcnt > 0 || obj->self)
186 if (obj->refcnt || obj->self) 188 if (obj->refcnt || obj->self)
187 { 189 {
188#if 0 190//printf ("%p rc %d\n", obj, obj->refcnt_cnt ());//D
189 if (mortals.size() > 5)fprintf (stderr, "%d delaying %d:%p:%s %d (self %p:%d)\n", time(0),i, obj, typeid (*obj).name (),
190 obj->refcnt, obj->self, obj->self ? SvREFCNT(obj->self): - 1);//D
191#endif
192
193 ++i; // further delay freeing 191 ++i; // further delay freeing
192
193 if (!(i & 0x3ff))
194 break;
194 }//D 195 }
195 else 196 else
196 { 197 {
197 //Dfprintf (stderr, "deleteing %d:%p:%s\n", i, obj,typeid (*obj).name ());//D
198 mortals.erase (i); 198 mortals.erase (i);
199 delete obj; 199 delete obj;
200 } 200 }
201 } 201 }
202} 202}
227 227
228static int 228static int
229attachable_free (pTHX_ SV *sv, MAGIC *mg) 229attachable_free (pTHX_ SV *sv, MAGIC *mg)
230{ 230{
231 attachable *at = (attachable *)mg->mg_ptr; 231 attachable *at = (attachable *)mg->mg_ptr;
232 assert (!(at->flags & attachable::F_BORROWED));
233 at->self = 0; 232 at->self = 0;
234 // next line makes sense, but most objects still have refcnt 0 by default 233 // next line makes sense, but most objects still have refcnt 0 by default
235 //at->refcnt_chk (); 234 //at->refcnt_chk ();
236 return 0; 235 return 0;
237} 236}
248 { 247 {
249 obj->self = newHV (); 248 obj->self = newHV ();
250 sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0); 249 sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0);
251 250
252 // borrow the refcnt from the object 251 // borrow the refcnt from the object
253 obj->flags |= attachable::F_BORROWED; 252 // it is important thta no refcnt_chk is being executed here
254 obj->refcnt_dec (); 253 obj->refcnt_dec ();
255 254
256 // now bless the object _once_ 255 // now bless the object _once_
257 return sv_bless (newRV_inc ((SV *)obj->self), stash); 256 return sv_bless (newRV_inc ((SV *)obj->self), stash);
258 } 257 }
259 else 258 else
259 {
260 return newRV_inc ((SV *)obj->self); 260 SV *sv = newRV_inc ((SV *)obj->self);
261
262 if (Gv_AMG (stash)) // handle overload correctly, as the perl core does not
263 SvAMAGIC_on (sv);
264
265 return sv;
266 }
261} 267}
262 268
263static void 269static void
264clearSVptr (SV *sv) 270clearSVptr (SV *sv)
265{ 271{
318inline SV *to_sv (living * v) { return newSVptr (v, stash_cf_living_wrap); } 324inline SV *to_sv (living * v) { return newSVptr (v, stash_cf_living_wrap); }
319 325
320inline SV *to_sv (object & v) { return to_sv (&v); } 326inline SV *to_sv (object & v) { return to_sv (&v); }
321inline SV *to_sv (living & v) { return to_sv (&v); } 327inline SV *to_sv (living & v) { return to_sv (&v); }
322 328
323//TODO:
324inline SV *to_sv (New_Face * v) { return to_sv (v->name); } 329inline SV *to_sv (facetile * v) { return to_sv (v->name); }
325inline SV *to_sv (treasurelist * v) { return to_sv (v->name); } 330inline SV *to_sv (treasurelist * v) { return to_sv (v->name); }
326 331
327inline SV *to_sv (UUID v) 332inline SV *to_sv (UUID v)
328{ 333{
329 char buf[128]; 334 char buf[128];
354inline void sv_to (SV *sv, attachable * &v) { v = (attachable *)SvPTR_ornull (sv, "cf::attachable"); } 359inline void sv_to (SV *sv, attachable * &v) { v = (attachable *)SvPTR_ornull (sv, "cf::attachable"); }
355inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); } 360inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); }
356inline void sv_to (SV *sv, region * &v) { v = (region *)SvPTR_ornull (sv, "cf::region"); } 361inline void sv_to (SV *sv, region * &v) { v = (region *)SvPTR_ornull (sv, "cf::region"); }
357inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); } 362inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); }
358 363
359inline void sv_to (SV *sv, New_Face * &v) { v = &new_faces[FindFace (SvPV_nolen (sv), 0)]; } //TODO 364inline void sv_to (SV *sv, facetile * &v) { v = &new_faces[FindFace (SvPV_nolen (sv), 0)]; }
360inline void sv_to (SV *sv, treasurelist * &v) { v = find_treasurelist (SvPV_nolen (sv)); } // TODO 365inline void sv_to (SV *sv, treasurelist * &v) { v = find_treasurelist (SvPV_nolen (sv)); }
361 366
362template<class T> 367template<class T>
363inline void sv_to (SV *sv, refptr<T> &v) { T *tmp; sv_to (sv, tmp); v = tmp; } 368inline void sv_to (SV *sv, refptr<T> &v) { T *tmp; sv_to (sv, tmp); v = tmp; }
364 369
365template<int N> 370template<int N>
501 if (!ext->cb) 506 if (!ext->cb)
502 ext->cb = newAV (); 507 ext->cb = newAV ();
503 508
504 return newRV_inc ((SV *)ext->cb); 509 return newRV_inc ((SV *)ext->cb);
505} 510}
506
507#if 0
508void attachable::clear ()
509{
510 if (self)
511 {
512 // disconnect Perl from C, to avoid crashes
513 sv_unmagic (SvRV ((SV *)self), PERL_MAGIC_ext);
514
515 // clear the perl hash, might or might not be a good idea
516 hv_clear ((HV *)SvRV ((SV *)self));
517
518 SvREFCNT_dec (self);
519 self = 0;
520 }
521
522 if (cb)
523 {
524 SvREFCNT_dec (cb);
525 cb = 0;
526 }
527
528 attach = 0;
529}
530#endif
531 511
532///////////////////////////////////////////////////////////////////////////// 512/////////////////////////////////////////////////////////////////////////////
533 513
534extern "C" int cfperl_initPlugin (const char *iversion, f_plug_api gethooksptr) 514extern "C" int cfperl_initPlugin (const char *iversion, f_plug_api gethooksptr)
535{ 515{
830} 810}
831 811
832///////////////////////////////////////////////////////////////////////////// 812/////////////////////////////////////////////////////////////////////////////
833 813
834void 814void
835maptile::emergency_save () 815cfperl_emergency_save ()
836{ 816{
837 CALL_BEGIN (0); 817 CALL_BEGIN (0);
838 CALL_CALL ("cf::map::emergency_save", G_VOID); 818 CALL_CALL ("cf::emergency_save", G_VOID);
839 CALL_END; 819 CALL_END;
840} 820}
841 821
842maptile * 822maptile *
843maptile::find_sync (const char *path, maptile *origin) 823maptile::find_sync (const char *path, maptile *origin)
844{ 824{
845 CALL_BEGIN (2); 825 CALL_BEGIN (2);
846 CALL_ARG (path); 826 CALL_ARG (path);
847 CALL_ARG (origin); 827 CALL_ARG (origin);
848 CALL_CALL ("cf::map::find_sync", G_SCALAR); 828 CALL_CALL ("cf::map::find_sync", G_SCALAR);
829
830 maptile *retval;
831
832 if (count)
833 sv_to (POPs, retval);
834 else
835 retval = 0;
836
837 CALL_END;
838
839 return retval;
840}
841
842maptile *
843maptile::find_async (const char *path, maptile *origin)
844{
845 CALL_BEGIN (2);
846 CALL_ARG (path);
847 CALL_ARG (origin);
848 CALL_CALL ("cf::map::find_async", G_SCALAR);
849 849
850 maptile *retval; 850 maptile *retval;
851 851
852 if (count) 852 if (count)
853 sv_to (POPs, retval); 853 sv_to (POPs, retval);
906void 906void
907iw::alloc () 907iw::alloc ()
908{ 908{
909 pe = GEventAPI->new_idle (0, 0); 909 pe = GEventAPI->new_idle (0, 0);
910 910
911 WaREENTRANT_off (pe);
911 pe->base.callback = (void *)iw_dispatch; 912 pe->base.callback = (void *)iw_dispatch;
912 pe->base.ext_data = (void *)this; 913 pe->base.ext_data = (void *)this;
913} 914}
914 915
915static void iow_dispatch (pe_event *ev) 916static void iow_dispatch (pe_event *ev)
921void 922void
922iow::alloc () 923iow::alloc ()
923{ 924{
924 pe = GEventAPI->new_io (0, 0); 925 pe = GEventAPI->new_io (0, 0);
925 926
927 WaREENTRANT_off (pe);
926 pe->base.callback = (void *)iow_dispatch; 928 pe->base.callback = (void *)iow_dispatch;
927 pe->base.ext_data = (void *)this; 929 pe->base.ext_data = (void *)this;
928 930
929 pe->fd = -1; 931 pe->fd = -1;
930 pe->poll = 0; 932 pe->poll = 0;
1258 const_iv (FLAG_ACTIVATE_ON_RELEASE) 1260 const_iv (FLAG_ACTIVATE_ON_RELEASE)
1259 const_iv (FLAG_IS_WATER) 1261 const_iv (FLAG_IS_WATER)
1260 const_iv (FLAG_CONTENT_ON_GEN) 1262 const_iv (FLAG_CONTENT_ON_GEN)
1261 const_iv (FLAG_IS_A_TEMPLATE) 1263 const_iv (FLAG_IS_A_TEMPLATE)
1262 const_iv (FLAG_IS_BUILDABLE) 1264 const_iv (FLAG_IS_BUILDABLE)
1265 const_iv (FLAG_DESTROY_ON_DEATH)
1266 const_iv (FLAG_NO_MAP_SAVE)
1263 1267
1264 const_iv (NDI_BLACK) 1268 const_iv (NDI_BLACK)
1265 const_iv (NDI_WHITE) 1269 const_iv (NDI_WHITE)
1266 const_iv (NDI_NAVY) 1270 const_iv (NDI_NAVY)
1267 const_iv (NDI_RED) 1271 const_iv (NDI_RED)
1452 const_iv (ATNR_BLIND) 1456 const_iv (ATNR_BLIND)
1453 const_iv (ATNR_INTERNAL) 1457 const_iv (ATNR_INTERNAL)
1454 const_iv (ATNR_LIFE_STEALING) 1458 const_iv (ATNR_LIFE_STEALING)
1455 const_iv (ATNR_DISEASE) 1459 const_iv (ATNR_DISEASE)
1456 1460
1457 const_iv (MAP_FLUSH)
1458 const_iv (MAP_PLAYER_UNIQUE)
1459 const_iv (MAP_BLOCK)
1460 const_iv (MAP_STYLE)
1461 const_iv (MAP_OVERLAY)
1462
1463 const_iv (MAP_IN_MEMORY) 1461 const_iv (MAP_IN_MEMORY)
1464 const_iv (MAP_SWAPPED) 1462 const_iv (MAP_SWAPPED)
1465 const_iv (MAP_LOADING) 1463 const_iv (MAP_LOADING)
1466 const_iv (MAP_SAVING) 1464 const_iv (MAP_SAVING)
1467 1465
1560} 1558}
1561 1559
1562NV floor (NV x) 1560NV floor (NV x)
1563 1561
1564NV ceil (NV x) 1562NV ceil (NV x)
1563
1564NV rndm (...)
1565 CODE:
1566 switch (items)
1567 {
1568 case 0: RETVAL = rndm (); break;
1569 case 1: RETVAL = rndm (SvUV (ST (0))); break;
1570 case 2: RETVAL = rndm (SvIV (ST (0)), SvIV (ST (1))); break;
1571 default: croak ("cf::rndm requires none, one or two parameters."); break;
1572 }
1573 OUTPUT:
1574 RETVAL
1565 1575
1566void server_tick () 1576void server_tick ()
1567 CODE: 1577 CODE:
1568 runtime = SvNVx (sv_runtime); 1578 runtime = SvNVx (sv_runtime);
1569 server_tick (); 1579 server_tick ();
1616 } 1626 }
1617 OUTPUT: RETVAL 1627 OUTPUT: RETVAL
1618 1628
1619void abort () 1629void abort ()
1620 1630
1631void fork_abort (char *cause = "cf::fork_abort")
1632
1633void cleanup (const char *cause, bool make_core = false)
1634
1621void emergency_save () 1635void emergency_save ()
1636
1637UV sv_2watcher (SV *w)
1638 CODE:
1639 RETVAL = (UV)GEventAPI->sv_2watcher (w);
1640 OUTPUT:
1641 RETVAL
1622 1642
1623void _exit (int status = 0) 1643void _exit (int status = 0)
1624 1644
1625#if _POSIX_MEMLOCK 1645#if _POSIX_MEMLOCK
1626 1646
1715 PPCODE: 1735 PPCODE:
1716 EXTEND (SP, object::mortals.size ()); 1736 EXTEND (SP, object::mortals.size ());
1717 for (AUTODECL (i, object::mortals.begin ()); i != object::mortals.end (); ++i) 1737 for (AUTODECL (i, object::mortals.begin ()); i != object::mortals.end (); ++i)
1718 PUSHs (to_sv (*i)); 1738 PUSHs (to_sv (*i));
1719 1739
1720object *first () 1740int objects_size ()
1721 CODE: 1741 CODE:
1722 RETVAL = object::first; 1742 RETVAL = objects.size ();
1743 OUTPUT: RETVAL
1744
1745object *objects (U32 index)
1746 CODE:
1747 RETVAL = index < objects.size () ? objects [index] : 0;
1748 OUTPUT: RETVAL
1749
1750int actives_size ()
1751 CODE:
1752 RETVAL = actives.size ();
1753 OUTPUT: RETVAL
1754
1755object *actives (U32 index)
1756 CODE:
1757 RETVAL = index < actives.size () ? actives [index] : 0;
1723 OUTPUT: RETVAL 1758 OUTPUT: RETVAL
1724 1759
1725# missing properties 1760# missing properties
1726 1761
1727object *head (object *op) 1762object *head (object *op)
1728 PROTOTYPE: $ 1763 PROTOTYPE: $
1729 CODE: 1764 CODE:
1730 RETVAL = op->head ? op->head : op; 1765 RETVAL = op->head_ ();
1731 OUTPUT: RETVAL 1766 OUTPUT: RETVAL
1732 1767
1733int is_head (object *op) 1768int is_head (object *op)
1734 PROTOTYPE: $ 1769 PROTOTYPE: $
1735 CODE: 1770 CODE:
1736 RETVAL = !op->head; 1771 RETVAL = op->head_ () == op;
1737 OUTPUT: RETVAL 1772 OUTPUT: RETVAL
1738 1773
1739void 1774void
1740inv (object *obj) 1775inv (object *obj)
1741 PROTOTYPE: $ 1776 PROTOTYPE: $
1832 1867
1833void drop (object *who, object *op) 1868void drop (object *who, object *op)
1834 1869
1835void pick_up (object *who, object *op) 1870void pick_up (object *who, object *op)
1836 1871
1837object *cf_object_insert_object (object *op, object *container)
1838
1839object *cf_object_insert_in_ob (object *ob, object *where)
1840
1841int cf_object_teleport (object *op, maptile *map, int x, int y) 1872int cf_object_teleport (object *op, maptile *map, int x, int y)
1842 1873
1843void update_object (object *op, int action) 1874void update_object (object *op, int action)
1844 1875
1845object *cf_create_object_by_name (const char *name) 1876object *cf_create_object_by_name (const char *name)
1963 1994
1964void esrv_update_item (object *op, int what, object *item) 1995void esrv_update_item (object *op, int what, object *item)
1965 C_ARGS: what, op, item 1996 C_ARGS: what, op, item
1966 1997
1967void clear_los (object *op) 1998void clear_los (object *op)
1968
1969int command_teleport (object *op, char *params)
1970 1999
1971int command_summon (object *op, char *params) 2000int command_summon (object *op, char *params)
1972 2001
1973int command_arrest (object *op, char *params) 2002int command_arrest (object *op, char *params)
1974 2003
2117 2146
2118object* cf_map_present_arch_by_name (maptile *map, const char* str, int nx, int ny) 2147object* cf_map_present_arch_by_name (maptile *map, const char* str, int nx, int ny)
2119 C_ARGS: str, map, nx, ny 2148 C_ARGS: str, map, nx, ny
2120 2149
2121void 2150void
2122cf_map_normalise (maptile *map, int x, int y) 2151get_map_flags (maptile *map, int x, int y)
2123 PPCODE: 2152 PPCODE:
2124{ 2153{
2125 maptile *nmap = 0; 2154 maptile *nmap = 0;
2126 I16 nx = 0, ny = 0; 2155 I16 nx = 0, ny = 0;
2127 int flags = get_map_flags (map, &nmap, x, y, &nx, &ny); 2156 int flags = get_map_flags (map, &nmap, x, y, &nx, &ny);
2189 CODE: 2218 CODE:
2190 RETVAL = get_name_of_region_for_map (m); 2219 RETVAL = get_name_of_region_for_map (m);
2191 OUTPUT: RETVAL 2220 OUTPUT: RETVAL
2192 2221
2193# worst xs function of my life 2222# worst xs function of my life
2194maptile * 2223bool
2195_create_random_map (\ 2224_create_random_map (\
2196 char *path,\ 2225 maptile *self,\
2197 char *wallstyle,\ 2226 char *wallstyle,\
2198 char *wall_name,\ 2227 char *wall_name,\
2199 char *floorstyle,\ 2228 char *floorstyle,\
2200 char *monsterstyle,\ 2229 char *monsterstyle,\
2201 char *treasurestyle,\ 2230 char *treasurestyle,\
2205 char *origin_map,\ 2234 char *origin_map,\
2206 char *final_map,\ 2235 char *final_map,\
2207 char *exitstyle,\ 2236 char *exitstyle,\
2208 char *this_map,\ 2237 char *this_map,\
2209 char *exit_on_final_map,\ 2238 char *exit_on_final_map,\
2210 int Xsize,\ 2239 int xsize,\
2211 int Ysize,\ 2240 int ysize,\
2212 int expand2x,\ 2241 int expand2x,\
2213 int layoutoptions1,\ 2242 int layoutoptions1,\
2214 int layoutoptions2,\ 2243 int layoutoptions2,\
2215 int layoutoptions3,\ 2244 int layoutoptions3,\
2216 int symmetry,\ 2245 int symmetry,\
2221 int dungeon_depth,\ 2250 int dungeon_depth,\
2222 int decoroptions,\ 2251 int decoroptions,\
2223 int orientation,\ 2252 int orientation,\
2224 int origin_y,\ 2253 int origin_y,\
2225 int origin_x,\ 2254 int origin_x,\
2226 int random_seed,\ 2255 U32 random_seed,\
2227 val64 total_map_hp,\ 2256 val64 total_map_hp,\
2228 int map_layout_style,\ 2257 int map_layout_style,\
2229 int treasureoptions,\ 2258 int treasureoptions,\
2230 int symmetry_used,\ 2259 int symmetry_used,\
2231 region *region\ 2260 region *region,\
2261 char *custom\
2232) 2262)
2233 CODE: 2263 CODE:
2234{ 2264{
2235 random_map_params rmp; 2265 random_map_params rmp;
2236 2266
2246 assign (rmp.exit_on_final_map, exit_on_final_map); 2276 assign (rmp.exit_on_final_map, exit_on_final_map);
2247 2277
2248 rmp.origin_map = origin_map; 2278 rmp.origin_map = origin_map;
2249 rmp.final_map = final_map; 2279 rmp.final_map = final_map;
2250 rmp.this_map = this_map; 2280 rmp.this_map = this_map;
2251 rmp.Xsize = Xsize; 2281 rmp.xsize = xsize;
2252 rmp.Ysize = Ysize; 2282 rmp.ysize = ysize;
2253 rmp.expand2x = expand2x; 2283 rmp.expand2x = expand2x;
2254 rmp.layoutoptions1 = layoutoptions1; 2284 rmp.layoutoptions1 = layoutoptions1;
2255 rmp.layoutoptions2 = layoutoptions2; 2285 rmp.layoutoptions2 = layoutoptions2;
2256 rmp.layoutoptions3 = layoutoptions3; 2286 rmp.layoutoptions3 = layoutoptions3;
2257 rmp.symmetry = symmetry; 2287 rmp.symmetry = symmetry;
2268 rmp.total_map_hp = total_map_hp; 2298 rmp.total_map_hp = total_map_hp;
2269 rmp.map_layout_style = map_layout_style; 2299 rmp.map_layout_style = map_layout_style;
2270 rmp.treasureoptions = treasureoptions; 2300 rmp.treasureoptions = treasureoptions;
2271 rmp.symmetry_used = symmetry_used; 2301 rmp.symmetry_used = symmetry_used;
2272 rmp.region = region; 2302 rmp.region = region;
2303 rmp.custom = custom;
2273 2304
2274 RETVAL = generate_random_map (path, &rmp); 2305 RETVAL = self->generate_random_map (&rmp);
2275} 2306}
2276 OUTPUT: 2307 OUTPUT:
2277 RETVAL 2308 RETVAL
2278 2309
2279MODULE = cf PACKAGE = cf::arch 2310MODULE = cf PACKAGE = cf::arch

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines