- use automake defined pkgdata dir for lua script dir instead of hardcoded
[apt.git] / python / apt.i
1 %module apt
2 %include std_string.i
3 %include std_vector.i
4
5 %{
6 #include <apt-pkg/init.h>
7 #include <apt-pkg/pkgcache.h>
8 #include <apt-pkg/depcache.h>
9 #include <apt-pkg/cachefile.h>
10 #include <apt-pkg/mmap.h>
11 #include <apt-pkg/cacheiterators.h>
12 #include <apt-pkg/algorithms.h>
13 #include <apt-pkg/pkgsystem.h>
14 #include <apt-pkg/contrib/configuration.h>
15 #include <apt-pkg/contrib/progress.h>
16 #include <apt-pkg/version.h>
17 #include <apt-pkg/pkgrecords.h>
18 #include <apt-pkg/acquire-item.h>
19 #include <apt-pkg/acquire.h>
20 #include <apt-pkg/packagemanager.h>
21 #include <apt-pkg/sourcelist.h>
22 #include <apt-pkg/contrib/error.h>
23 #include <apt-pkg/luaiface.h>
24
25 #include <string>
26 #include <time.h>
27 %}
28
29 %inline %{
30 typedef pkgCache::VerIterator VerIterator;
31 typedef pkgCache::PkgIterator PkgIterator;
32 typedef pkgCache::DepIterator DepIterator;
33 typedef pkgCache::PrvIterator PrvIterator;
34 typedef pkgCache::PkgFileIterator PkgFileIterator;
35 typedef pkgCache::VerFileIterator VerFileIterator;
36 typedef pkgCache::Header Header;
37 typedef pkgCache::Package Package;
38 typedef pkgCache::PackageFile PackageFile;
39 typedef pkgCache::VerFile VerFile;
40 typedef pkgCache::Version Version;
41 typedef pkgCache::Dependency Dependency;
42 typedef pkgCache::Provides Provides;
43 typedef pkgCache::StringItem StringItem;
44 typedef pkgCache::Dep Dep;
45 typedef pkgCache::State State;
46 typedef pkgCache::Flag Flag;
47 typedef pkgDepCache::Policy Policy;
48 typedef pkgDepCache::StateCache StateCache;
49 typedef Configuration::Item Item;
50 typedef pkgRecords::Parser Parser;
51 %}
52
53 /* Fix some operators. */
54 %rename(next) operator++;
55 %rename(assign) operator=;
56 %rename(pkgCache) operator pkgCache *;
57 %rename(pkgDepCache) operator pkgDepCache *;
58 %rename(Package) operator Package *;
59 %rename(Version) operator Version *;
60 %rename(Dependency) operator Dependency *;
61 %rename(Provides) operator Provides *;
62 %rename(PackageFile) operator PackageFile *;
63 %rename(VerFile) operator VerFile *;
64 %rename(__getitem__) operator[];
65 %ignore operator pkgCache &;
66 %ignore operator pkgDepCache &;
67
68 /* Set some data as immutable. */
69 %immutable pkgVersion;
70 %immutable pkgLibVersion;
71 %immutable pkgOS;
72 %immutable pkgCPU;
73 %immutable pkgSystem::Label;
74 %immutable pkgVersioningSystem::Label;
75 %immutable pkgDepCache::StateCache::CandVersion;
76 %immutable pkgDepCache::StateCache::CurVersion;
77
78 /* One-shot initialization function. */
79 %inline %{
80 inline bool pkgInit() 
81 {
82    return pkgInitConfig(*_config) && pkgInitSystem(*_config,_system);
83 }
84 %}
85
86 /* No suport for nested classes yet. */
87 %rename(pkgCacheHeader) pkgCache::Header;
88 %rename(pkgCachePackage) pkgCache::Package;
89 %rename(pkgCachePackageFile) pkgCache::PackageFile;
90 %rename(pkgCacheVerFile) pkgCache::VerFile;
91 %rename(pkgCacheVersion) pkgCache::Version;
92 %rename(pkgCacheDependency) pkgCache::Dependency;
93 %rename(pkgCacheProvides) pkgCache::Provides;
94 %rename(pkgCacheStringItem) pkgCache::StringItem;
95 %rename(pkgCacheDep) pkgCache::Dep;
96 %rename(pkgCacheState) pkgCache::State;
97 %rename(pkgCacheFlag) pkgCache::Flag;
98 %rename(pkgCacheVerIterator) pkgCache::VerIterator;
99 %rename(pkgCachePkgIterator) pkgCache::PkgIterator;
100 %rename(pkgCacheDepIterator) pkgCache::DepIterator;
101 %rename(pkgCachePrvIterator) pkgCache::PrvIterator;
102 %rename(pkgCachePkgFileIterator) pkgCache::PkgFileIterator;
103 %rename(pkgCacheVerFileIterator) pkgCache::VerFileIterator;
104 %rename(pkgDepCacheStateCache) pkgDepCache::StateCache;
105 %rename(pkgRecordsParser) pkgRecords::Parser;
106 %rename(pkgAcquireItem) pkgAcquire::Item;
107 %rename(ConfigurationItem) Configuration::Item;
108
109 /* Wonderful SWIG magic to turn APT iterators into Python iterators. */
110 %exception next {
111         $action
112         /* Pass ahead the StopIteration exception. */
113         if (!result) return NULL;
114 }
115 #define EXTEND_ITERATOR(IterClass) \
116 %newobject IterClass::next; \
117 %newobject IterClass::__iter__; \
118 %ignore IterClass::operator++; \
119 %extend IterClass { \
120         inline bool __nonzero__() { return self->end() == false; }; \
121         inline IterClass *next() { \
122                 if (self->end() == true) { \
123                         PyErr_SetObject(PyExc_StopIteration, Py_None); \
124                         return NULL; \
125                 } \
126                 IterClass *ret = new IterClass(*self); \
127                 (*self)++; \
128                 return ret; \
129         }; \
130         /* We must return a copy here, otherwise the original object
131          * might be deallocated and the returned pointer would become
132          * invalid */ \
133         inline IterClass *__iter__() { return new IterClass(*self); }; \
134 }
135 EXTEND_ITERATOR(pkgCache::PkgIterator);
136 EXTEND_ITERATOR(pkgCache::VerIterator);
137 EXTEND_ITERATOR(pkgCache::DepIterator);
138 EXTEND_ITERATOR(pkgCache::PrvIterator);
139 EXTEND_ITERATOR(pkgCache::PkgFileIterator);
140 EXTEND_ITERATOR(pkgCache::VerFileIterator);
141
142 /* Now transform the functions returning iterators into ones with more
143  * meaningful names for that purpose. */
144 %rename(PkgIter) pkgDepCache::PkgBegin;
145 %rename(PkgIter) pkgCache::PkgBegin;
146 %rename(FileIter) pkgCache::FileBegin;
147 %ignore pkgCache::PkgEnd;
148 %ignore pkgCache::FileEnd;
149
150 /* That's the best way I found to access ItemsBegin/ItemsEnd, for now.
151  * It may be changed to behave like the iterators above in the future,
152  * so don't expect a list to be returned. */
153 %ignore pkgAcquire::ItemsBegin;
154 %ignore pkgAcquire::ItemsEnd;
155 %extend pkgAcquire {
156 PyObject *
157 ItemsIter()
158 {
159         static swig_type_info *ItemDescr = NULL;
160         PyObject *list, *o;
161         pkgAcquire::ItemIterator I;
162         if (!ItemDescr) {
163                 ItemDescr = SWIG_TypeQuery("pkgAcquire::Item *");
164                 assert(ItemDescr);
165         }
166         list = PyList_New(0);
167         if (list == NULL)
168                 return NULL;
169         for (I = self->ItemsBegin(); I != self->ItemsEnd(); I++) {
170                 o = SWIG_NewPointerObj((void *)(*I), ItemDescr, 0);
171                 if (!o || PyList_Append(list, o) == -1) {
172                         Py_XDECREF(o);
173                         Py_DECREF(list);
174                         return NULL;
175                 }
176                 Py_DECREF(o);
177         }
178         return list;
179 }
180 }
181
182 /* Wrap string members. */
183 %immutable pkgAcquire::Item::DestFile;
184 %immutable pkgAcquire::Item::ErrorText;
185 %extend pkgAcquire::Item {
186         const char *DestFile;
187         const char *ErrorText;
188 }
189 %ignore pkgAcquire::Item::DestFile;
190 %ignore pkgAcquire::Item::ErrorText;
191 %{
192 #define pkgAcquire_Item_DestFile_get(x) ((x)->DestFile.c_str())
193 #define pkgAcquire_Item_ErrorText_get(x) ((x)->ErrorText.c_str())
194 %}
195
196 /* Also from Configuration::Item. */
197 %extend Configuration::Item {
198         const char *Tag;
199         const char *Value;
200 }
201 %ignore Configuration::Item::Tag;
202 %ignore Configuration::Item::Value;
203 %{
204 #define Configuration_Item_Tag_get(x) ((x)->Tag.c_str())
205 #define Configuration_Item_Value_get(x) ((x)->Value.c_str())
206 #define Configuration_Item_Tag_set(x,y) ((x)->Tag = (y))
207 #define Configuration_Item_Value_set(x,y) ((x)->Value = (y))
208 %}
209
210 /* Typemap to present map_ptrloc in a better way */
211 %apply int { map_ptrloc };
212
213 /* That should be enough for our usage, but _error is indeed an alias
214  * for a function which returns an statically alocated GlobalError object. */
215 %immutable _error;
216 GlobalError *_error;
217
218 %immutable _lua;
219 Lua *_lua;
220
221 /* Undefined reference!? */
222 %ignore pkgCache::PkgIterator::TargetVer;
223
224 /* There's a struct and a function with the same name. */
225 %ignore SubstVar;
226
227 /* Allow threads to run while doing DoInstall() */
228 %exception pkgPackageManager::DoInstall {
229 Py_BEGIN_ALLOW_THREADS
230 $function
231 Py_END_ALLOW_THREADS
232 }
233
234 /* Preprocess string macros (note that we're %import'ing). */
235 %import <apt-pkg/contrib/strutl.h>
236
237 %include <apt-pkg/init.h>
238 %include <apt-pkg/pkgcache.h>
239 %include <apt-pkg/depcache.h>
240 %include <apt-pkg/cacheiterators.h>
241 %include <apt-pkg/cachefile.h>
242 %include <apt-pkg/algorithms.h>
243 %include <apt-pkg/pkgsystem.h>
244 %include <apt-pkg/contrib/configuration.h>
245 %include <apt-pkg/contrib/progress.h>
246 %include <apt-pkg/version.h>
247 %include <apt-pkg/pkgrecords.h>
248 %include <apt-pkg/acquire-item.h>
249 %include <apt-pkg/acquire.h>
250 %include <apt-pkg/packagemanager.h>
251 %include <apt-pkg/sourcelist.h>
252 %include <apt-pkg/contrib/error.h>
253 %include <apt-pkg/luaiface.h>
254
255 /* Create a dumb status class which can be instantiated. pkgAcquireStatus
256  * has fully abstract methods. */
257 %inline %{
258 class pkgAcquireStatusDumb : public pkgAcquireStatus
259 {
260    virtual bool MediaChange(string Media,string Drive) {};
261 };
262 %}
263
264 /* That's the real class we use for Python inheritance. */
265 %{
266 class ROpPyProgress : public OpProgress {
267         PyObject *PyObj;
268
269         public:
270         OpProgress::Op;
271         OpProgress::SubOp;
272         OpProgress::Percent;
273         OpProgress::MajorChange;
274         OpProgress::CheckChange;
275
276         virtual void Update()
277         {
278                 if (PyObject_HasAttrString(PyObj, "Update")) {
279                         PyObject *Ret;
280                         Ret = PyObject_CallMethod(PyObj, "Update", NULL);
281                         Py_XDECREF(Ret);
282                 }
283         };
284
285         virtual void Done()
286         {
287                 if (PyObject_HasAttrString(PyObj, "Done")) {
288                         PyObject *Ret;
289                         Ret = PyObject_CallMethod(PyObj, "Done", NULL);
290                         Py_XDECREF(Ret);
291                 }
292         };
293         
294         ROpPyProgress(PyObject *PyObj) : PyObj(PyObj) {Py_INCREF(PyObj);};
295         ~ROpPyProgress() {Py_DECREF(PyObj);};
296 };
297 %}
298
299 /* That's how we want SWIG to see our class. */
300 %extend ROpPyProgress {
301         const char *Op;
302         const char *SubOp;
303 }
304 %ignore ROpPyProgress::Op;
305 %ignore ROpPyProgress::SubOp;
306 %{
307 #define ROpPyProgress_Op_get(x) ((x)->Op.c_str())
308 #define ROpPyProgress_Op_set(x,y) ((x)->Op = (y))
309 #define ROpPyProgress_SubOp_get(x) ((x)->SubOp.c_str())
310 #define ROpPyProgress_SubOp_set(x,y) ((x)->SubOp = (y))
311 %}
312 class ROpPyProgress : public OpProgress {
313         public:
314         float Percent;
315         bool MajorChange;
316         bool CheckChange(float Interval=0.7);               
317         ROpPyProgress(PyObject *PyObj);
318 };
319
320 /* That's the proxy class the user sees. This exists only to pass
321  * "self" as the first parameter of ROpPyProgress. */
322 %pythoncode %{
323 class OpPyProgress(ROpPyProgress):
324         def __init__(self):
325                 ROpPyProgress.__init__(self, self)
326         def __repr__(self):
327                 return "<C OpPyProgress instance at %s>" % self.this
328 %}
329
330 #if 0
331 /* The same scheme as above for pkgAcquireStatus. */
332 %{
333 class pkgRPyAcquireStatus : public pkgAcquireStatus
334 {
335         PyObject *PyObj;
336
337         void ItemDescMethod(const char *Name, pkgAcquire::ItemDesc &Itm) {
338                 static swig_type_info *SwigType = 0;
339                 if (!SwigType) {
340                         SwigType = SWIG_TypeQuery("pkgAcquire::ItemDesc *");
341                         assert(SwigType);
342                 }
343                 PyObject *attr = PyObject_GetAttrString(PyObj, (char*)Name);
344                 if (attr != NULL) {
345                         PyObject *Arg;
346                         Arg = SWIG_NewPointerObj(&Itm, SwigType, 0);
347                         if (!Arg) return;
348                         PyObject *Ret;
349                         Ret = PyObject_CallFunction(attr, "(O)", Arg);
350                         Py_XDECREF(Arg);
351                         Py_XDECREF(Ret);
352                 } else {
353                         PyErr_Clear();
354                 }
355         };
356
357         public:
358         /* No wrapping yet. */
359         //struct timeval Time;
360         //struct timeval StartTime;
361         pkgAcquireStatus::LastBytes;
362         pkgAcquireStatus::CurrentCPS;
363         pkgAcquireStatus::CurrentBytes;
364         pkgAcquireStatus::TotalBytes;
365         pkgAcquireStatus::FetchedBytes;
366         pkgAcquireStatus::ElapsedTime;
367         pkgAcquireStatus::TotalItems;
368         pkgAcquireStatus::CurrentItems;
369    
370         /* Call only Python method, if existent, or parent method. */
371         void Fetched(unsigned long Size,unsigned long ResumePoint)
372         {
373                 PyObject *attr = PyObject_GetAttrString(PyObj, "Fetched");
374                 if (attr != NULL) {
375                         PyObject *Ret;
376                         Ret = PyObject_CallFunction(attr, "(ii)",
377                                                     Size, ResumePoint);
378                         Py_XDECREF(Ret);
379                 } else {
380                         PyErr_Clear();
381                         pkgAcquireStatus::Fetched(Size, ResumePoint);
382                 }
383         };
384
385         bool MediaChange(string Media,string Drive)
386         {
387                 PyObject *attr = PyObject_GetAttrString(PyObj, "MediaChange");
388                 if (attr != NULL) {
389                         PyObject *Ret;
390                         bool RealRet = false;
391                         Ret = PyObject_CallFunction(attr, "(ss)",
392                                                     Media.c_str(),
393                                                     Drive.c_str());
394                         if (Ret) {
395                                 RealRet = PyObject_IsTrue(Ret);
396                                 Py_DECREF(Ret);
397                         }
398                         return RealRet;
399                 } else {
400                         PyErr_Clear();
401                 }
402         };
403    
404         void IMSHit(pkgAcquire::ItemDesc &Itm)
405                 { ItemDescMethod("IMSHit", Itm); };
406         void Fetch(pkgAcquire::ItemDesc &Itm)
407                 { ItemDescMethod("Fetch", Itm); };
408         void Done(pkgAcquire::ItemDesc &Itm)
409                 { ItemDescMethod("Done", Itm); };
410         void Fail(pkgAcquire::ItemDesc &Itm)
411                 { ItemDescMethod("Fail", Itm); };
412
413         bool Pulse(pkgAcquire *Owner) {
414                 pkgAcquireStatus::Pulse(Owner);
415                 static swig_type_info *SwigType = 0;
416                 if (!SwigType) {
417                         SwigType = SWIG_TypeQuery("pkgAcquire *");
418                         assert(SwigType);
419                 }
420                 PyObject *attr = PyObject_GetAttrString(PyObj, "Pulse");
421                 if (attr != NULL) {
422                         PyObject *Arg;
423                         Arg = SWIG_NewPointerObj(Owner, SwigType, 0);
424                         if (!Arg) return false;
425                         PyObject *Ret;
426                         Ret = PyObject_CallFunction(attr, "(O)", Arg);
427                         Py_XDECREF(Arg);
428                         bool RealRet = false;
429                         if (Ret != NULL) {
430                                 RealRet = PyObject_IsTrue(Ret);
431                                 Py_DECREF(Ret);
432                         }
433                         return RealRet;
434                 } else {
435                         PyErr_Clear();
436                 }
437         };
438
439         void Start() {
440                 pkgAcquireStatus::Start();
441                 PyObject *attr = PyObject_GetAttrString(PyObj, "Start");
442                 if (attr != NULL) {
443                         PyObject *Ret;
444                         Ret = PyObject_CallFunction(attr, NULL);
445                         Py_XDECREF(Ret);
446                 } else {
447                         PyErr_Clear();
448                 }
449         };
450         void Stop() {
451                 pkgAcquireStatus::Stop();
452                 PyObject *attr = PyObject_GetAttrString(PyObj, "Stop");
453                 if (attr != NULL) {
454                         PyObject *Ret;
455                         Ret = PyObject_CallFunction(attr, NULL);
456                         Py_XDECREF(Ret);
457                 } else {
458                         PyErr_Clear();
459                 }
460         };
461    
462         pkgRPyAcquireStatus(PyObject *PyObj) : PyObj(PyObj)
463                 { Py_INCREF(PyObj); };
464         ~pkgRPyAcquireStatus()
465                 { Py_DECREF(PyObj); };
466 };
467 %}
468 class pkgRPyAcquireStatus : public pkgAcquireStatus {
469         public:
470         pkgRPyAcquireStatus(PyObject *PyObj);
471         double LastBytes;
472         double CurrentCPS;
473         double CurrentBytes;
474         double TotalBytes;
475         double FetchedBytes;
476         unsigned long ElapsedTime;
477         unsigned long TotalItems;
478         unsigned long CurrentItems;
479 };
480 %pythoncode %{
481 class pkgPyAcquireStatus(pkgRPyAcquireStatus):
482         def __init__(self):
483                 pkgRPyAcquireStatus.__init__(self, self)
484         def __repr__(self):
485                 return "<C pkgPyAcquireStatus instance at %s>" % self.this
486 %}
487 #endif
488
489 // vim:ft=swig