Package platformids
1
2 """The package 'platformids' provides canonical enumerations of bit encoded numeric platform IDs
3 for the Python implementations CPython, IPython, IronPython, Jython, and PyPy.
4 """
5
6
7
8
9
10
11 from __future__ import absolute_import
12
13 import os
14 import sys
15 import re
16 import platform
17
18
19
20
21 from pythonids import PYV35Plus,ISSTR, PYVxyz, PYV33, PYV2
22 from pythonids.pythondist import isJython, ISINT, PYDIST, PYE_DIST, PYE_JYTHON
23 from yapyutils.modules.loader import get_modulelocation, load_module
24
25
26 __author__ = 'Arno-Can Uestuensoez'
27 __license__ = "Artistic-License-2.0 + Forced-Fairplay-Constraints"
28 __copyright__ = "Copyright (C) 2010-2018 Arno-Can Uestuensoez" \
29 " @Ingenieurbuero Arno-Can Uestuensoez"
30 __version__ = '0.1.31'
31 __uuid__ = "7add5ded-c39b-4b6e-8c87-1b3a1c150ee9"
32
33 __docformat__ = "restructuredtext en"
34
35
36 _debug = 0
37 _verbose = 0
38
39
40
41
42
43
44 DSKORG_ID = re.compile(r'^(?s)ID=["\']*([^"\'\n\r]*).*')
45 DSKORG_ID_LIKE = re.compile(r'^(?s)ID_LIKE=["\']*([^"\'\n\r]*).*')
46 DSKORG_NAME_RELEASE = re.compile(r'(?s)^NAME=["\']*([^ ]*) *([^"\']*).*')
47 DSKORG_RELEASE = re.compile(r'(?s)^VERSION=["\']*([^"\']*)["\']*[^(]*[(]*([^)]*)[)]*.*')
48 DSKORG_VERSION = re.compile(r'(?s)^VERSION=["\']*([^"\']*)["\']*.*')
49 PRENONNUM = re.compile(r'([^0-9]+[^ \t0-9]).*')
50 VERSION_ID = re.compile(r'(?s)^VERSION_ID=["\']*([^"\']*)["\']*.*')
51 VERSNUM = re.compile(r'([0-9]+)[.]*([0-9]*)[.]*([0-9]*)')
52
53
54
55
56
60
61
65
66
70
71
75
76
80
81
85
86
87
88
89
90 if not isJython:
91 try:
92 osname = os.name
93 except AttributeError:
94
95 raise NotImplementedError('requires special module')
96
97 if PYV35Plus:
98 PlatformIDsFileCheck = (FileNotFoundError,)
99
100 else:
101 PlatformIDsFileCheck = (Exception,)
102
103 else:
104 osname = os._name
105 PlatformIDsFileCheck = (IOError,)
106
107
108 RTE = 0
109
110
111
112
113 RTE_CATEGORY_B = 0xf0000000
114 RTE_OSTYPE_B = 0x0f800000
115 RTE_DIST_B = 0x007f0000
116 RTE_DISTREL_B = 0x0000ffff
117
118 RTE_CATEGORY_OFFSET = 0x0fffffff
119 RTE_OSTYPE_OFFSET = 0x007fffff
120 RTE_DIST_OFFSET = 0x0000ffff
121 RTE_DISTREL_OFFSET = 0x00000000
122
123 RTE_CATEGORY_SHIFT = 28
124 RTE_OSTYPE_SHIFT = 23
125 RTE_DIST_SHIFT = 16
126 RTE_DISTREL_SHIFT = 0
127
128 RTE_CATEGORY = 0xf0000000
129 RTE_OSTYPE = 0xff800000
130 RTE_DIST = 0xffff0000
131 RTE_DISTREL = 0xffffffff
132
133
134
135
136
137 RTE_DISTEXT = 0x00400000
138
139
140
141
142 RTE_POSIX = 0x10000000
143 RTE_WIN32 = 0x20000000
144 RTE_WIN = 0x20000000
145 RTE_WINDOWS = 0x20000000
146 RTE_EMU = 0x40000000
147 RTE_PWEMU = 0x70000000
148 RTE_WPEMU = 0x50000000
149 RTE_EMBEDDED = 0x80000000
150
151
152
153
154
155
156
157 RTE_NT = RTE_WIN32 + 0x00800000
158
159 RTE_CYGWINNT = RTE_PWEMU + 0x00800000
160
161
162 RTE_LINUX = RTE_POSIX + 0x00800000
163 RTE_BSD = RTE_POSIX + 0x01000000
164 RTE_DARWIN = RTE_POSIX + 0x02000000
165 RTE_UNIX = RTE_POSIX + 0x04000000
166
167
168
169
170
171
172 RTE_FEDORA = RTE_LINUX + 0x00010000
173 RTE_CENTOS = RTE_LINUX + 0x00020000
174 RTE_DEBIAN = RTE_LINUX + 0x00030000
175 RTE_RHEL = RTE_LINUX + 0x00040000
176 RTE_SLES = RTE_LINUX + 0x00050000
177 RTE_UBUNTU = RTE_LINUX + 0x00060000
178
179 RTE_OPENWRT = RTE_LINUX + 0x00070000
180 RTE_RASPBIAN = RTE_LINUX + 0x00080000
181
182
183
184
185 RTE_KALI = RTE_LINUX + RTE_DISTEXT + 0x00010000
186 RTE_ARCHLINUX = RTE_LINUX + RTE_DISTEXT + 0x00020000
187
188
189 RTE_SUNOS5 = RTE_UNIX + 0x00020000
190 RTE_SOLARIS = RTE_SUNOS5
191
192
193 RTE_OSX = RTE_DARWIN + 0x00020000
194 RTE_OSX10 = RTE_OSX
195
196
197 RTE_OPENBSD = RTE_BSD + 0x00020000
198
199
200
201
202 if 'posix' == osname:
203 if platform.system().startswith('CYGW'):
204
205 category = RTE_PWEMU
206 else:
207 category = RTE_POSIX
208
209
210
211 elif 'nt' == osname:
212 category = RTE_WIN32
213
214
216 """Implements a 'dict' with protection against modification of items. This is
217 in order to protect a repository from erroneous modifications of it's
218 entries by malicious code. The deletion is still supported, which is
219 considered as intentional, thus done beeing aware of the consequences.
220
221 The main intention for the *platformids* is to avoid inconsistencies of
222 hard-coded values of assigned enumerations by runtime redefinitions.
223 Unintentional redefinitions also may proof as hard to debug.
224
225 The member attribute *self.strict_check* controls how new items are added:
226
227 0. single new item:
228 add silently
229
230 1. single item which is already present:
231 * strict_check == True: raises exception
232 * strict_check == False: ignores silently
233
234 2. set of items, where none of the new set is present:
235 add silently
236
237 3. set of items, where at least one is present:
238 * strict_check == True: raises exception
239 * strict_check == False: add silently new, ignore present silently
240
241
242 The common variables such as central dictionaries are thus read-only protected
243 during the runtime of the process. The response style for the attempt to alter
244 a value could be modified - raised to a stronger level - by the attribute
245 'strict_check', which raises an exception once set.
246 """
248 """
249 Args:
250 args:
251 pass-through to dict
252
253 kargs:
254 non-defined are passed-through to dict
255
256 int_keys_only:
257 Controls type of valid keys. ::
258
259 int_keys_only := (
260 True # permits interger keys only
261 | False # permits any valid *dict* key
262 )
263
264 strict_check:
265 Defines the handling of values for present keys. ::
266
267 True: when True raises exception for present
268 items,
269
270 False: silently ignores new values for present
271 items
272
273 Returns:
274 Initialized object, or raises exception.
275
276 Raises:
277 pass-through
278
279 """
280 self.strict_check = kargs.get('strict_check', False)
281 try:
282 kargs.pop('strict_check')
283 except:
284 pass
285
286 self.int_keys_only = kargs.get('int_keys_only', False)
287 try:
288 kargs.pop('int_keys_only')
289 except:
290 pass
291
292 super(ProtectedDict, self).__init__(*args, **kargs)
293
295 ""
296 if name in ('strict_check_reset', 'strict_check',):
297 raise PlatformIDsCustomError("deletion not permitted for attribute: " + str(name))
298 return dict.__delattr__(self, name)
299
301 """Filters and controls attribute values to be set.
302
303 Args:
304 name:
305 Sets the attribute named by *name*. Establishes special
306 handling for the in-band control attributes.
307
308 **strict_check**:
309 The value can only be raised to *True* in order to
310 strengthen the strictness.
311
312 **strict_check_reset**:
313 If the value is set to *True*, than the member attribute
314 '*strict_check*' is set to *False*.
315
316 Else calls '*dict.__setattr__*'.
317
318 value:
319 The value is passed through to *dict*, see also for special
320 values of *name*.
321
322 Returns:
323 Either filters defined control attributes - see *name*, or
324 calls *dict.__setattr__*.
325
326 Raises:
327 pass-through
328
329 """
330 if name == 'strict_check_reset' and value == True:
331 return dict.__setattr__(self, 'strict_check', False)
332
333 elif name == 'strict_check':
334 if self.__dict__.get('strict_check'):
335 if value != True:
336 return
337
338 return dict.__setattr__(self, name, value)
339
340 return dict.__setattr__(self, name, value)
341
343 """Filter for already present mappings controlled by the
344 member *strict_check*.
345
346 Args:
347 name:
348 Sets the item named by *name*. Controlled by
349 the attribute *strict_check*. ::
350
351 self.strict_check := (
352 True # permits only creation of non-present
353 | False # normal behaviour
354 )
355
356 Dependent on the presence raises an exception when
357 strict is enabled.
358
359 value:
360 The value is passed through to *dict*, see also for special
361 values of *name*.
362
363 Returns:
364 dict.__setitem__
365
366 Raises:
367 PlatformIDsPresentError
368 Conditional based on *strict_check*, if *True* raises
369 for present attributes *PlatformIDsPresentError*.
370
371 PlatformIDsKeyError
372 For non-int keys when *int_keys_only* is set.
373
374 pass-through
375
376 """
377 try:
378 if dict.__getitem__(self, key):
379 if self.strict_check:
380 raise PlatformIDsPresentError("key-present: " + str(key))
381 return
382 except KeyError:
383 if self.int_keys_only and type(key) not in ISINT:
384 raise PlatformIDsKeyError("Integer keys only: " + str(key))
385
386 return dict.__setitem__(self, key, value)
387
388 - def update(self, dict2, *args, **kargs):
389 """Adds a set of items, filters each for presence.
390
391 * none of the new set is present:
392 adds all silently
393
394 * at least one is present:
395 * strict_check == True: raises exception
396 * strict_check == False: add silently
397
398 Args:
399
400 dict2:
401 Adds items controlled by the attribute *strict_check*. ::
402
403 self.strict_check := (
404 True # permits only creation of non-present
405 | False # normal behaviour
406 )
407
408 Dependent on the presence of at least one raises an
409 exception when strict is enabled.
410
411 args:
412 Passed to *dict.update*.
413
414 kargs:
415 Passed to *dict.update*.
416
417 Returns:
418 dict.update or None
419
420 Raises:
421 PlatformIDsPresentError
422 Conditional based on *strict_check*, if *True* raises
423 for present attributes *PlatformIDsPresentError*.
424
425 PlatformIDsKeyError
426 For non-int keys when *int_keys_only* is set.
427
428 pass-through
429
430 """
431
432
433 if self.int_keys_only:
434 for k in dict2.keys():
435 if type(k) not in ISINT:
436 if isJython:
437 try:
438 if type(k) is not long:
439 raise PlatformIDsKeyError("Numeric keys only: " + str(k))
440 except:
441 pass
442 else:
443 raise PlatformIDsKeyError("Numeric keys only: " + str(k))
444
445 if set(self.keys()) & set(dict2.keys()):
446
447
448 if self.strict_check:
449
450 _str = []
451
452
453 for x in set(self.keys()) & set(dict2.keys()):
454 if type(x) in ISSTR:
455 _str.append(x)
456 else:
457 _str.append(str(x))
458
459
460 raise PlatformIDsPresentError(
461 "keys-present:\n %s\n" % (
462 str(sorted(_str))))
463
464 else:
465
466
467 common = set(self.keys()) & set(dict2.keys())
468 for k, v in dict2.items():
469 if type(k) in common:
470 continue
471 self[k] = v
472
473 else:
474
475 return super(ProtectedDict, self).update(dict2, *args, **kargs)
476
477
479 """Implements the dynamic creation and management of numeric enumeration
480 values. These are used as dynamic assigned constants with the life time
481 of the process itself. The enums are optimized to be used in conjunction
482 with numeric bitmask vectors.
483 The values are created on-demand, e.g. for dynamic loaded packages, and
484 could be removed when no longer required. Thus are released than for the
485 reuse.
486
487 The management of the unused numeric values for assignment is performed
488 by two levels.
489
490 0. The value is managed by a protected counter within the defined range.
491 1. Once the values are exhausted, the dictionary is used as release map.
492 This is required due to the possible storage of the values by the
493 application, thus assigned values cannot be reassigned and though
494 the ranges could become used sparse.
495
496 This level is much slower, though it is based on the lookup and remove
497 form the unused-map.
498 And of course, previous releases has to be present |smilecool|.
499
500 Anyhow, e.g. in case of *platformids* for the *ostype*
501 and *dist* the ranges for the additional dynamic assigments in are
502 about 100 for the distribution *dist*, about 25 for the OS
503 type *ostype*, and about 12 for the category *category*. This should be
504 in practical realworld use-cases more than sufficient.
505
506
507 REMARK: Implemented as *dict* for coming extensions.
508
509 """
511 """Initializes key reservation.
512 The custom range values has to comply to the bitmask segments.
513 These define the minimal and maximal values in accordance to the common ranges
514 by the mathematical notation:
515
516 .. parsed-literal::
517
518 values := [custom_min, custom_max) # excluding custom_max
519
520 The values could be processed by the application of the helper constants,
521 see :ref:`Helper Constants <BITMASK_HELPERCONSTS>`.
522 E.g. in case of *dist* for the *ostype* context of *RTE_LINUX* :
523
524 .. parsed-literal::
525
526 custom_min == ((RTE_LINUX + RTE_DISTEXT + RTE_DIST_OFFSET + 0) & RTE_DIST_B)
527 custom_max == ((RTE_LINUX + RTE_DISTEXT + RTE_DIST_OFFSET + 126) & RTE_DIST_B)
528
529 or
530
531 .. parsed-literal::
532
533 (custom_min >> 16) == 0
534 (custom_max >> 16) == 126
535
536
537
538 The caller is responsible for the appropriate values.
539
540 Args:
541 kargs:
542 default pass-through to dict
543
544 custom_max:
545 Defines the maximum of custom range.
546 When missing no custom range os available.
547
548 .. parsed-literal::
549
550 custom_max > custom_min
551
552 default := None
553
554 custom_min:
555 Defines the minimum of custom range.
556 When missing no custom range os available.
557
558 default := None
559
560 custom_offset:
561 Defines the offset for the increment and decrement.
562 This is required e.g. in case of bitmask fields
563 with segments starts at bits greater than 0.
564
565 default := 0
566
567 Returns:
568 Initialized object, or raises exception.
569
570 Raises:
571 PlatformIDsEnumerationError
572 Erroneous custom range is provided.
573
574 pass-through
575
576 """
577 ProtectedDict.__setattr__(self, 'custom_offset', kargs.get('custom_offset', 0))
578 try:
579
580 kargs.pop('custom_offset')
581 except:
582 pass
583
584
585 _cm = kargs.get('custom_max', 0)
586 ProtectedDict.__setattr__(self, 'custom_max', _cm)
587
588 try:
589
590 kargs.pop('custom_max')
591
592
593 ProtectedDict.__setattr__(self, 'reserved', _cm)
594 except:
595
596 ProtectedDict.__setattr__(self, 'reserved', _cm)
597
598 ProtectedDict.__setattr__(self, 'custom_min', kargs.get('custom_min', 0))
599 try:
600
601 kargs.pop('custom_min')
602 except:
603 pass
604
605 if self.custom_min > self.custom_max or (self.custom_min == self.custom_max and self.custom_min != 0):
606 raise PlatformIDsEnumerationError(
607 "Invalid custom range min = %s - max = %s" % (str(self.custom_min), str(self.custom_max))
608 )
609
610 kargs['int_keys_only'] = True
611 super(ProtectedDictEnum, self).__init__(**kargs)
612
613
614 self.free = {}
615
617 """Prohibits unmanaged access to the enum pool, use method *delete_enum* instead for
618 managed release.
619
620 Args:
621 enum:
622 Enum key.
623
624 Returns:
625 Raises exception.
626
627 Raises:
628 PlatformIDsCustomError
629
630 """
631 raise PlatformIDsCustomError("prohibits unmanaged access, use method delete_enum")
632
634 """Protects the enumeration management attributes from deletion.
635
636 Args:
637 name:
638 Excludes reserved attributes from deletion. ::
639
640 name :=(
641 'reserved'
642 | 'custom_min'
643 | 'custom_max'
644 )
645
646 Returns:
647 None
648
649 Raises:
650 PlatformIDsEnumerationError
651
652 pass-through
653
654 """
655 if name in ('reserved', 'custom_min', 'custom_max',):
656 raise PlatformIDsEnumerationError("attribute cannot be deleted: " + str(name))
657 return ProtectedDict.__delattr__(self, name)
658
660 """Protects the enumeration management attributes from non-managed
661 direct access.
662
663 Args:
664 name:
665 Excludes reserved attributes from direct access. ::
666
667 name :=(
668 'reserved'
669 | 'custom_min'
670 | 'custom_max'
671 )
672
673 value:
674 Value to be set.
675
676 Returns:
677 None
678
679 Raises:
680 PlatformIDsEnumerationError
681
682 pass-through
683
684 """
685 if name in ('reserved', 'custom_min', 'custom_max',):
686 raise PlatformIDsEnumerationError("attribute cannot be set direct: " + str(name))
687 return ProtectedDict.__setattr__(self, name, value)
688
690 """Prohibits unmanaged access to the enum pool, use method *add_enum* instead for
691 managed release.
692
693 Args:
694 enum:
695 Enum key.
696 Returns:
697 Raises exception.
698
699 Raises:
700 PlatformIDsCustomError
701
702 """
703 raise PlatformIDsCustomError("prohibits unmanaged access, use method add_enum")
704
706 """Reserves and assigns the next free unique key to the
707 value. The assigned key value is returned for use.
708 Custom ranges are available when the values *custom_max*
709 and *custom_min* are initialized appropriately.
710
711 Args:
712 None.
713
714 Returns:
715 Either returns the reserved key, or raises exception when range is exhausted.
716
717 Raises:
718 PlatformIDsCustomError:
719 No custom ranges are configured.
720
721 PlatformIDsEnumerationError
722 The configured range is exhausted.
723
724 pass-through
725
726 """
727 if self.free:
728
729
730 _x = self.free.popitem()
731 ProtectedDict.__setitem__(self, _x[0], value)
732 return _x[0]
733
734 else:
735 if not self.reserved:
736 raise PlatformIDsCustomError(
737 "No custom ranges are available"
738 )
739
740 if self.reserved <= self.custom_min:
741 raise PlatformIDsEnumerationError(
742 "custom range exhausted"
743 )
744
745
746 ProtectedDict.__setattr__(self, 'reserved', self.reserved - self.custom_offset - 1)
747
748
749 ProtectedDict.__setitem__(self, self.reserved, value)
750
751
752 return self.reserved
753
755 """Checks and returns the next free value.
756
757 **Does not reserve, just displays next.**
758
759 Args:
760 None
761
762 Returns:
763 Value to be used by next call of *add_enum*.
764
765 Raises:
766 PlatformIDsCustomError:
767 No custom ranges are configured.
768
769 PlatformIDsEnumerationError
770 Range exhausted, no free values are available.
771
772 """
773 if not self.reserved:
774 raise PlatformIDsCustomError(
775 "No custom ranges are available"
776 )
777
778 if self.reserved > self.custom_min:
779 return self.reserved
780
781 raise PlatformIDsEnumerationError(
782 "Reserved range exhausted."
783 )
784
785 - def purge(self, **kargs):
786 """Clears the list of deleted non-continous enums.
787 Deletes all entries in the release map, which could be added
788 incremental and continous to the reserved-list of vallues
789 beginning at from *custom_min*.
790 This re-initializes for the purged items the pure numeric first level
791 assignement by ranges - spares for these the lookup in the non-continous
792 list.
793
794 Args:
795 kargs:
796 maxrel:
797 Maximum to be released.
798
799 minrel:
800 Minimum to be released.
801
802 Returns:
803 Returns the number of actual releases.
804
805 Raises:
806 PlatformIDsEnumerationError:
807 Could not fulfil *minrel*.
808
809 pass-through
810
811 """
812 minrel = kargs.get('minrel', 0)
813 maxrel = kargs.get('maxrel', len(self.free))
814
815 relcnt = 0
816
817 _n = len(self.free)
818
819 for enum in sorted(self.free.keys()):
820 if enum == self.reserved:
821
822 ProtectedDict.__setattr__(self, 'reserved', enum + self.custom_offset + 1)
823 self.free.pop(enum)
824 relcnt += 1
825 maxrel -= 1
826 if not maxrel:
827 break
828
829 else:
830
831 break
832
833 if minrel:
834 if relcnt < minrel:
835 raise PlatformIDsEnumerationError(
836 "Could not release requested range: req = %d / done = %d / free = %d" % (
837 minrel,
838 relcnt,
839 (self.reserved - self.custom_min),
840 )
841 )
842
843 return relcnt
844
846 """Releases a given enum, either continous values by changing the reserved values,
847 or by adding a non-continous values to the dict of released items.
848 The non-continous released items could be cleared by the method *purge*.
849
850 Args:
851 enum:
852 Enum key.
853
854 Returns:
855 None.
856
857 Raises:
858 pass-through
859
860 """
861 if enum == self.reserved:
862
863 ProtectedDict.__setattr__(self, 'reserved', enum + self.custom_offset + 1)
864 self.pop(enum)
865 return True
866
867 self.free[enum] = self.pop(enum)
868 return True
869
870 - def update(self, dict2, *args, **kargs):
871 """Prohibits updates.
872 This is required in order to avoid arbitrary updates which simply
873 would complicate the management and assignment of further values.
874 Thus only individual values could be added and removed.
875
876 Args:
877 None.
878
879 Returns:
880 Raises Exception.
881
882 Raises:
883 PlatformIDsEnumerationError
884
885 """
886 raise PlatformIDsCustomError("operation not permitted: update")
887
888
889
890 rte2num = ProtectedDict(
891 {
892 'bsd': RTE_BSD,
893 'darwin': RTE_DARWIN,
894 'emu': RTE_EMU,
895 'linux': RTE_LINUX,
896 'linux2': RTE_LINUX,
897 'nt': RTE_NT,
898 'wpemu': RTE_WPEMU,
899 'posix': RTE_POSIX,
900 'pwemu': RTE_PWEMU,
901 'unix': RTE_UNIX,
902 'win': RTE_WIN32,
903 'win32': RTE_WIN32,
904 'windows': RTE_WINDOWS,
905 RTE_BSD: RTE_BSD,
906 RTE_DARWIN: RTE_DARWIN,
907 RTE_EMU: RTE_EMU,
908 RTE_LINUX: RTE_LINUX,
909 RTE_NT: RTE_NT,
910 RTE_WPEMU: RTE_WPEMU,
911 RTE_POSIX: RTE_POSIX,
912 RTE_PWEMU: RTE_PWEMU,
913 RTE_WIN32: RTE_WIN32,
914 RTE_WINDOWS: RTE_WINDOWS,
915
916
917
918
919 'SunOS5': RTE_SOLARIS,
920 'arch': RTE_ARCHLINUX,
921 'archlinux': RTE_ARCHLINUX,
922 'centos': RTE_CENTOS,
923 'debian': RTE_DEBIAN,
924 'fedora': RTE_FEDORA,
925 'openbsd': RTE_OPENBSD,
926 'openwrt': RTE_OPENWRT,
927 'osx': RTE_OSX,
928 'osx10': RTE_OSX10,
929 'raspbian': RTE_RASPBIAN,
930 'rhel': RTE_RHEL,
931 'solaris': RTE_SOLARIS,
932 RTE_ARCHLINUX: RTE_ARCHLINUX,
933 RTE_CENTOS: RTE_CENTOS,
934 RTE_DEBIAN: RTE_DEBIAN,
935 RTE_FEDORA: RTE_FEDORA,
936 RTE_OPENBSD: RTE_OPENBSD,
937 RTE_OPENWRT: RTE_OPENWRT,
938 RTE_OSX10: RTE_OSX10,
939 RTE_OSX: RTE_OSX,
940 RTE_RASPBIAN: RTE_RASPBIAN,
941 RTE_RHEL: RTE_RHEL,
942 RTE_SOLARIS: RTE_SOLARIS,
943 }
944 )
945
946
947
948 num2rte = ProtectedDict(
949 {
950 RTE_ARCHLINUX: 'archlinux',
951 RTE_BSD: 'bsd',
952 RTE_CENTOS: 'centos',
953 RTE_DARWIN: 'darwin',
954 RTE_DEBIAN: 'debian',
955 RTE_EMU: 'emu',
956 RTE_FEDORA: 'fedora',
957 RTE_LINUX: 'linux',
958 RTE_NT: 'nt',
959 RTE_OPENBSD: 'openbsd',
960 RTE_OPENBSD: 'openbsd',
961 RTE_OPENWRT: 'openwrt',
962 RTE_OSX10: 'osx10',
963 RTE_WPEMU: 'wpemu',
964 RTE_POSIX: 'posix',
965 RTE_PWEMU: 'pwemu',
966 RTE_RASPBIAN: 'raspbian',
967 RTE_RHEL: 'rhel',
968 RTE_SOLARIS: 'solaris',
969 RTE_UNIX: 'unix',
970 RTE_WIN32: 'win32',
971 RTE_WINDOWS: 'windows',
972 }
973 )
974
975
976
977 num2enumstr = ProtectedDict(
978 {
979
980
981 }
982 )
983
984
985
986 num2pretty = ProtectedDict(
987 {
988 RTE_ARCHLINUX: 'Arch Linux',
989 RTE_BSD: "Berkeley Software Distribution",
990 RTE_CENTOS: "CentOS",
991 RTE_DARWIN: "Darwin",
992 RTE_DEBIAN: "Debian",
993 RTE_FEDORA: "Fedora",
994 RTE_LINUX: "Linux",
995 RTE_NT: "NT",
996 RTE_OPENBSD: "OpenBSD",
997 RTE_WPEMU: "Windows-Emulation",
998 RTE_POSIX: "POSIX",
999 RTE_PWEMU: "POSIX-Windows-Emulation",
1000 RTE_RASPBIAN: "Raspbian",
1001 RTE_RHEL: "RHEL",
1002 RTE_UNIX: "Unix",
1003 RTE_WIN32: "Windows",
1004 RTE_WIN: "Windows",
1005 RTE_WINDOWS: "Windows",
1006 }
1007 )
1008
1009
1010 custom_rte_distrel2tuple = ProtectedDict(
1011 {
1012
1013 }
1014 )
1015
1016
1017 custom_category = ProtectedDictEnum(
1018 custom_min=0x90000000,
1019 custom_max=0xf0000000,
1020 custom_offset=0x0fffffff,
1021 )
1022
1023
1024 custom_ostype = ProtectedDictEnum(
1025 custom_min=0x08000000,
1026 custom_max=0x0f800000,
1027 custom_offset=0x007fffff,
1028 )
1029
1030
1031 custom_dist = ProtectedDictEnum(
1032 custom_min=0x00410000,
1033 custom_max=0x007f0000,
1034 custom_offset=0x0000ffff,
1035 )
1036
1037
1039 """ Calls the *pythonids.get_modulelocation* function with specific default parameters
1040 for the *platformids*.
1041
1042 Args:
1043 mbase:
1044 Base for module search paths by default within the subdirectory of *platformids*.
1045 The filepath name with a trailing separator. ::
1046
1047 default := os.path.dirname(__file__) + os.sep
1048
1049 The base path is used within the post-processing of the eventually matched
1050 path, thus has to be appropriate for each item of *mpaths*.
1051
1052 mname:
1053 The relative path of the module in dotted *Python* notation. ::
1054
1055 mname := (
1056 <dotted-module-name-str>
1057 | <dotted-module-name-path-name-str>
1058 )
1059
1060 mpaths:
1061 List of module specific search paths for *platformids*, these
1062 are relative to *mbase*, ::
1063
1064 default := [
1065 'dist',
1066 'custom',
1067 'net',
1068 'embed',
1069 '',
1070 ]
1071
1072 resulting in::
1073
1074 default := [
1075 mbase + 'dist' + os.sep,
1076 mbase + 'custom' + os.sep,
1077 mbase + 'net' + os.sep,
1078 mbase + 'embed' + os.sep,
1079 mbase,
1080 ]
1081
1082 kargs:
1083 permitrel:
1084 Permit the return of relative module names within *mpath*.
1085 If *False* absolute only, which is relative to an existing
1086 *sys.path* entry. ::
1087
1088 permitrel := (
1089 True, # returns a relative module name if within subtree
1090 False # returns in any case a module name relative to sys.path
1091 )
1092
1093 Sets relative base within *platformids* as the default: ::
1094
1095 rbase = os.path.normpath(os.path.dirname(__file__)) + os.sep
1096
1097 Returns:
1098 Returns in case of a match the resulting entry within *sys.modules*::
1099
1100 match -> (<relative-module-name>, <module-file-path-name>,)
1101
1102 The default when no match occured is to rely on the more versatile
1103 search mechanism of the import implementation of the concrete
1104 *Python* implementation for another final trial by the caller::
1105
1106 default -> (<mname>, None,)
1107
1108 Raises:
1109 PlatformIDsError
1110 'mbase' does not match 'mpaths'
1111
1112 PlatformIDsPresentError
1113 missing 'mbase'
1114
1115 pass-through
1116
1117 """
1118
1119
1120 _permitrel = kargs.get('permitrel', False)
1121 if _permitrel:
1122 rbase = kargs.get('rbase')
1123 if rbase == None:
1124 rbase = os.path.normpath(os.path.dirname(__file__) + os.sep) + os.sep
1125 kargs['rbase'] = rbase
1126
1127 if mbase == None:
1128 mbase = os.path.dirname(__file__) + os.sep
1129 mbase = os.path.normpath(mbase) + os.sep
1130
1131 if mpaths == None:
1132
1133 mpaths = [
1134 mbase + 'dist' + os.sep,
1135 mbase + 'custom' + os.sep,
1136 mbase + 'net' + os.sep,
1137 mbase + 'embed' + os.sep,
1138 mbase ,
1139 ]
1140 elif mpaths and mpaths[0]:
1141
1142 for mi in range(len(mpaths)):
1143 mpaths[mi] = os.path.normpath(mbase + mpaths[mi]) + os.sep
1144
1145 elif not mpaths:
1146 raise PlatformIDsPresentError("missing 'mpaths'")
1147
1148 if mpaths and not mpaths[0].startswith(mbase):
1149 raise PlatformIDsError(
1150 "'mbase' does not match 'mpaths'\nmbase = %s\nmpaths[0] = %s" %(
1151 mbase, mpaths[0]
1152 )
1153 )
1154
1155 return get_modulelocation(mname, mbase, mpaths, **kargs)
1156
1157
1159 """Split a version string separated by '.' into an integer
1160 array. ::
1161
1162 decode_version_str_to_segments('1.22.17') => (1, 22, 17)
1163 decode_version_str_to_segments('2012.02.17') => (2012, 2, 17)
1164 decode_version_str_to_segments('10.0.1809') => (10, 0, 1809)
1165
1166 A tiny utility - frequently required.
1167
1168 Args:
1169 v: Version string with maximal 3 digits::
1170
1171 ('1.2.3') => (1, 2, 3)
1172 ('1.2') => (1, 2, 0)
1173 ('1') => (1, 0, 0)
1174
1175 Returns:
1176 Tuple of *int*. ::
1177
1178 ('1.2.3') => (1, 2, 3)
1179 ('1.2') => (1, 2, 0)
1180 ('1') => (1, 0, 0)
1181
1182 In case an error occured::
1183
1184 (0, 0, 0)
1185
1186 Raises:
1187 None.
1188
1189 """
1190
1191
1192 def tonum(x):
1193 try:
1194 return int(x)
1195 except ValueError:
1196 if x == '':
1197 return 0
1198 raise
1199
1200 return tuple([tonum(x) for x in VERSNUM.split(v)[1:4]])
1201
1202
1204 """Encodes the provided 32bit bitmask of each field into
1205 the combined integer value of the bitmask vector.
1206
1207 Args:
1208 kargs:
1209 category:
1210 The numeric 32bit bitmask of the category: ::
1211
1212 category := (
1213 <int-enum>
1214 | <category-key>
1215 )
1216 int-enum: the integer enum, preferbly a predefined value-by-var
1217 category-key: the key value as string to be evaluated by one
1218
1219 of::
1220
1221 *rte2num*: the common mapping dictionary
1222 *get_rte2num*: the function interface for *rte2num*
1223
1224 default is 0
1225
1226 ostype:
1227 The numeric 32bit bitmask of the ostype::
1228
1229 ostype := (
1230 <int-enum>
1231 | <ostype-key>
1232 )
1233 int-enum: the integer enum, preferbly a predefined value-by-var
1234 ostype-key: the key value as string to be evaluated by one
1235
1236 of::
1237
1238 *rte2num*: the common mapping dictionary
1239 *get_rte2num*: the function interface for *rte2num*
1240
1241 default is 0.
1242
1243 dist:
1244 The numeric 32bit bitmask of the dist::
1245
1246 ostype := (
1247 <int-enum>
1248 | <dist-key>
1249 )
1250 int-enum: the integer enum, preferbly a predefined value-by-var
1251 dist-key: the key value as string to be evaluated by one
1252
1253 of::
1254
1255 *rte2num*: the common mapping dictionary
1256 *get_rte2num*: the function interface for *rte2num*
1257
1258 default is 0.
1259
1260 distrel:
1261 The numeric 32bit encoded integer for the distrel, default is 0.
1262
1263 Returns:
1264 The 32bit compressed bitmask of the RTE.
1265
1266 Raises:
1267 pass-through
1268
1269 """
1270 return (
1271 get_rte2num(kargs.get('category', 0)) | get_rte2num(kargs.get('ostype', 0)) | get_rte2num(kargs.get('dist', 0)) | get_rte2num(kargs.get('distrel', 0))
1272 )
1273
1274
1276 """Converts the numeric base values of the fields into a 32bit bitmask and
1277 encodes them into the combined integer value of the bitmask vector.
1278
1279 Args:
1280 kargs:
1281 category:
1282 The non-shifted base value of the category::
1283
1284 category := (
1285 <int-val>
1286 )
1287 int-val: the relative integer value of the category bits
1288
1289 default is 0
1290
1291 ostype:
1292 The non-shifted base value of the ostype::
1293
1294 ostype := (
1295 <int-val>
1296 )
1297 int-val: the relative integer value of the ostype bits
1298
1299 default is 0.
1300
1301 dist:
1302 The non-shifted base value of the dist::
1303
1304 dist := (
1305 <int-val>
1306 )
1307 int-val: the relative integer value of the dist bits
1308
1309 default is 0.
1310
1311 distrel:
1312 The non-shifted encoded base value of the distrel, default is 0.
1313
1314 Returns:
1315 The 32bit compressed bitmask of the RTE.
1316
1317 Raises:
1318 pass-through
1319
1320 """
1321 return (
1322 kargs.get('category', 0) << 28 | kargs.get('ostype', 0) << 23 | kargs.get('dist', 0) << 16 | kargs.get('distrel', 0)
1323 )
1324
1325
1568
1569
1607
1608
1709
1710
1758
1759
1761 """Scans the platform and returns the numeric id for the current *category*.
1762
1763 Args:
1764 none
1765
1766 Returns:
1767 Returns the *category*. ::
1768
1769 res = <category-bits><ostype-bits-zero><dist-bits-zero><distrel-bits-zero>
1770
1771 Raises:
1772 PlatformIDsError
1773
1774 """
1775 try:
1776 return rte2num[osname]
1777 except KeyError:
1778 raise Exception("Platform category not supported: " + str(osname))
1779
1780
1782 """Scans the platform and returns the numeric id for the current *ostype*.
1783
1784 Args:
1785 none
1786
1787 Returns:
1788 Returns the *ostype* as integer enum. The bitmask includes
1789 the *category*. ::
1790
1791 res = <category-bits><ostype-bits><dist-bits-zero><distrel-bits-zero>
1792
1793 Raises:
1794 PlatformIDsError
1795
1796 """
1797 if osname == 'posix':
1798 if isJython:
1799
1800
1801 try:
1802 return rte2num[platform.System.getProperty('os.name').lower()] & RTE_OSTYPE
1803 except KeyError:
1804 k = platform.dist()
1805 raise Exception("OS type not supported: %s.%s (platform.dist=%s)" % (str(osname), str(k[0]), str(k)))
1806
1807 else:
1808 k = platform.uname()
1809 if k[0] == 'Linux':
1810 return RTE_POSIX | RTE_LINUX
1811
1812 elif k[0][-3:] == 'BSD':
1813 return RTE_POSIX | RTE_BSD
1814
1815 else:
1816 try:
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837 return rte2num[sys.platform] & RTE_OSTYPE
1838
1839 except KeyError:
1840 k = platform.dist()
1841 raise Exception("OS type not supported: %s.%s (platform.uname=%s)" % (str(osname), str(k[0]), str(k)))
1842
1843 elif osname == 'nt':
1844 return RTE_WIN | RTE_NT
1845
1846 else:
1847
1848 try:
1849 return rte2num[k[0].lower()] & RTE_OSTYPE
1850 except KeyError:
1851 raise Exception("Platform not supported: " + str(osname))
1852
1853
1855 """Scans the platform and returns the numeric id for the current *dist*.
1856
1857 Args:
1858 none
1859
1860 Returns:
1861 Returns the *dist* as integer enum. The bitmask includes
1862 the *category* and *ostype*. ::
1863
1864 res = <category-bits><ostype-bits><dist-bits><distrel-bits-zero>
1865
1866 Raises:
1867 PlatformIDsError
1868
1869 """
1870 _d = fetch_platform_distribution()
1871 try:
1872 return rte2num[_d[5]]
1873 except KeyError:
1874 return get_rte2num(_d[5])
1875
1876
1878 """Scans the platform and returns the complete tuple for the current *dist*.
1879
1880 Args:
1881 none
1882
1883 Returns:
1884 Returns the complete tuple of information related to a distribution. ::
1885
1886 res = (<distid-string>, <distrel-string>, <distrel-tuple>, <ditst-rel-key-string>)
1887
1888 Raises:
1889 PlatformIDsError
1890
1891 """
1892 _d = fetch_platform_distribution()
1893 return (
1894 _d[5],
1895 _d[1],
1896 _d[4],
1897 _d[0],
1898 )
1899
1900
1901
1902
1903
1904 _impmodname = None
1905 try:
1906 with open(os.path.dirname(__file__) + os.sep + "setup_platform", 'r') as f:
1907 _impmodname = f
1908
1909
1910
1911
1912
1913
1914
1915
1916 except:
1917 pass
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929 if osname == 'posix':
1930 if (
1931 os.path.exists("/etc/redhat-release") or
1932 os.path.exists("/etc/os-release")
1933 ):
1934 try:
1935 RTE = rte2num[fetch_platform_distribution()[5]]
1936 except KeyError:
1937 for r in rte2num.keys():
1938
1939
1940 if type(r) in ISINT:
1941 continue
1942 if sys.platform.startswith(r):
1943 RTE = rte2num[r]
1944
1945 else:
1946
1947 RTE = RTE_POSIX
1948
1949 elif sys.platform.startswith('openbsd'):
1950 RTE = RTE_OPENBSD
1951
1952 elif sys.platform.startswith('darwin'):
1953 RTE = RTE_DARWIN
1954
1955 elif os.path.exists("/etc/openwrt_release"):
1956 RTE = RTE_OPENWRT
1957
1958 elif sys.platform.startswith('sunos5'):
1959
1960 RTE = RTE_SOLARIS
1961
1962 elif sys.platform.startswith('cygwin'):
1963 RTE = RTE_PWEMU
1964
1965 else:
1966 RTE = RTE_POSIX
1967
1968 elif osname == 'nt':
1969
1970 RTE = RTE_WIN32
1971
1972 elif osname == 'java':
1973
1974
1975
1976 RTE = 0
1977 try:
1978 _snp = sys.getNativePlatform()
1979 RTE = rte2num[_snp]
1980
1981 except (NameError, AttributeError):
1982 if platform.linux_distribution()[0]:
1983 RTE = RTE_LINUX
1984
1985 if os.path.exists("/etc/openwrt_release"):
1986 RTE = RTE_OPENWRT
1987
1988 elif (
1989 os.path.exists("/etc/redhat-release") or
1990 os.path.exists("/etc/os-release")
1991 ):
1992 try:
1993 RTE = rte2num[fetch_platform_distribution()[5]]
1994 except KeyError:
1995 for r in rte2num.keys():
1996 if type(r) in ISINT:
1997 continue
1998 if platform.linux_distribution()[0].lower().startswith(r):
1999 RTE = rte2num[r]
2000 else:
2001 RTE = RTE_POSIX
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012 elif sys.platform.startswith('cygwin'):
2013 RTE = RTE_PWEMU
2014
2015 else:
2016 RTE = RTE_POSIX
2017
2018 elif platform.mac_ver()[0]:
2019 RTE = RTE_DARWIN
2020 elif platform.win32_ver()[0]:
2021 RTE = RTE_WIN32
2022
2023 if not RTE:
2024 raise PlatformIDsError("Unknown platform: " + str(_snp))
2025
2026 else:
2027 raise Exception("Platform not supported")
2028
2029
2030
2031
2032 if not _impmodname or not os.path.exists(_impmodname):
2033 try:
2034 _impmodname = num2rte[RTE]
2035
2036 except KeyError:
2037 if RTE == RTE_WIN32:
2038 _impmodname = 'windows'
2039 else:
2040 raise PlatformIDsError("not supported, requires:" + str(num2rte.values()))
2041
2042
2043
2044
2045
2046 modnamerel, modfpath = get_modlocation(_impmodname)
2047 if modfpath == None:
2048
2049
2050 if RTE & RTE_WIN32 or (RTE & RTE_PWEMU) == RTE_PWEMU:
2051 mbase_altbase = os.environ['CommonProgramFiles'] + os.sep + 'platformids'
2052 else:
2053 mbase_altbase = os.sep + 'etc' + os.sep + 'platformids'
2054
2055
2056 if not os.path.exists(mbase_altbase):
2057 mbase_altbase = os.getenv('PLATFORMIDS_ALTBASE', None)
2058
2059 if mbase_altbase != None:
2060 modnamerel, modfpath = get_modlocation(_impmodname, mbase=mbase_altbase, )
2061
2062
2063 if RTE & RTE_WIN32 or (RTE & RTE_PWEMU) == RTE_PWEMU:
2064 mbase_altbase = os.environ['LOCALAPPDATA'] + os.sep + 'platformids'
2065 if not os.path.exists(mbase_altbase) and RTE & RTE_LINUX:
2066 mbase_altbase = os.environ['HOME'] + os.sep + '.config' + os.sep + 'platformids'
2067 if not mbase_altbase or not os.path.exists(mbase_altbase):
2068 mbase_altbase = os.environ['HOME'] + os.sep + 'platformids'
2069
2070 try:
2071
2072 load_module(_impmodname, modfpath)
2073 except KeyError:
2074
2075 pass
2076
2077
2079 """Retrieves the bitmask encoding for current runtime environemnt.
2080
2081 Args:
2082 None.
2083
2084 Returns:
2085 The encoded bitmask to be used for caching and *RTE*.
2086
2087 Raises:
2088 pass-through
2089
2090 """
2091 ret = 0
2092 try:
2093 _pi = fetch_platform_distribution()
2094 ret = rte2num[_pi[0]]
2095
2096
2097 except KeyError:
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108 for rx in range(len(_pi[4]), 0, -1):
2109 _k = _pi[5] + ''.join((str(x) for x in _pi[4][:rx]))
2110 try:
2111 ret = rte2num[_k]
2112
2113 except KeyError:
2114 pass
2115
2116 if not ret:
2117 try:
2118
2119 ret = rte2num[_pi[5]]
2120
2121 except KeyError:
2122 try:
2123
2124 ret = rte2num[fetch_platform_os()[0]]
2125
2126 except KeyError:
2127 try:
2128
2129
2130 ret = rte2num[fetch_platform_distribution()]
2131
2132 except KeyError:
2133
2134 ret = rte2num[fetch_platform_os()]
2135
2136 return ret
2137
2138
2139
2140
2141 RTE = fetch_rte_hexversion()
2142
2143
2144
2145
2146
2147
2148
2149 RTE_GENERIC = RTE & RTE_POSIX & RTE_WIN32
2150
2151
2152 RTE_LOCAL = RTE_GENERIC + 1
2153
2154
2156 """Decodes the compressed category from the 32bit integer bitmask
2157 into the corresponding integer enum.
2158
2159 Args:
2160 rte:
2161 The comppressed runtime environment identifier bitmask.
2162
2163 default := RTE
2164
2165 Returns:
2166 Integer value of the category enum.
2167
2168 Raises:
2169 pass-through
2170
2171 """
2172 return (get_rte2num(rte) & RTE_CATEGORY)
2173
2174
2176 """Decodes the compressed ostype from the 32bit integer bitmask
2177 into the corresponding integer enum.
2178
2179 Args:
2180 rte:
2181 The comppressed runtime environment identifier bitmask.
2182
2183 default := RTE
2184
2185 Returns:
2186 Integer value of the ostype enum.
2187
2188 Raises:
2189 pass-through
2190
2191 """
2192 return (get_rte2num(rte) & RTE_OSTYPE)
2193
2194
2196 """Decodes the compressed dist from the 32bit integer bitmask
2197 into the corresponding integer enum.
2198 Recognizes the *ostype* domain e.g. for *RTE_NT*.
2199
2200 Args:
2201 rte:
2202 The comppressed runtime environment identifier bitmask.
2203
2204 default := RTE
2205
2206 Returns:
2207 Integer value of the dist enum.
2208
2209 Raises:
2210 pass-through
2211
2212 """
2213 return (get_rte2num(rte) & RTE_DIST)
2214
2215
2217 """Decodes the compressed distrel from the 32bit integer bitmask
2218 into the corresponding integer enum.
2219 Recognizes the *ostype* and *dist* domain, the distrel
2220 extension flag.
2221
2222 Args:
2223 rte:
2224 The comppressed runtime environment identifier bitmask.
2225
2226 default := RTE
2227
2228 Returns:
2229 Integer value of the encoded distrel.
2230
2231 Raises:
2232 pass-through
2233
2234 """
2235 return (get_rte2num(rte) & RTE_DISTREL)
2236
2237
2239 """Decodes the compressed distrel from the 32bit integer bitmask
2240 into the corresponding tuple of integer segments.
2241
2242 This is probably one of the most important functions, because
2243 it has the knowledge to split *distrel* including calling
2244 a custom-callback function when required.
2245 Recognizes the *ostype* and *dist* domain, the *distrel*
2246 extension flag in order to determine the further processing.
2247 The supported special cases of known and pre-loaded standard
2248 distributions are hardcoded for better performance here,
2249 currently these are: ::
2250
2251 ArchLinux, KaliLinux
2252 Windows-NT
2253
2254 BlackArch, Gentoo,
2255 Armbian, ArchLinux, BlackArch, Gentoo, KaliLinux
2256
2257 Args:
2258 rte:
2259 The comppressed runtime environment identifier bitmask.
2260
2261 default := RTE
2262
2263 Returns:
2264 Tuple of Integer values of the encoded segments, either
2265 as defined by the default layout, or any known as defined
2266 by additional extended and/or custom criteria.
2267
2268 Raises:
2269 pass-through
2270
2271 """
2272 try:
2273 _rte = rte2num[rte]
2274
2275 except KeyError:
2276 if type(rte) in ISINT:
2277
2278 _rte = rte
2279
2280 elif decode_version_str_to_segments(rte):
2281
2282 return decode_version_str_to_segments(rte)
2283
2284 else:
2285 raise PlatformIDsUnknownError("Not registered distrel = " + str(rte))
2286
2287 if _rte & RTE_OSTYPE == RTE_NT:
2288
2289 return (
2290 _rte & 0xffff,
2291 0,
2292 0,
2293 )
2294
2295 elif _rte & RTE_OSTYPE == RTE_LINUX and _rte & RTE_DISTEXT:
2296 if (_rte & RTE_DIST) in (RTE_KALI, RTE_ARCHLINUX,):
2297
2298
2299 return (
2300 ((_rte & 0xfe00) >> 9) + 1970,
2301 (_rte & 0x01e0) >> 5,
2302 _rte & 0x001f,
2303 )
2304
2305 elif _rte & RTE_DIST in custom_rte_distrel2tuple.keys():
2306
2307 return custom_rte_distrel2tuple[_rte & RTE_DIST](rte)
2308
2309
2310 return (
2311 (_rte & 0xfc00) >> 10,
2312 (_rte & 0x03e0) >> 5,
2313 _rte & 0x001f,
2314 )
2315
2316
2318 """Decodes the compressed components from the 32bit integer bitmask
2319 into the corresponding segments of relative integer values.
2320
2321 Args:
2322 rte:
2323 The comppressed runtime environment identifier bitmask.
2324
2325 default := RTE
2326
2327 Returns:
2328 Tuple of integer values of the components. ::
2329
2330 ret := => (#category-bits, #ostype-bits, #dist-bits, #distrel-bits)
2331
2332 Where the following os true: ::
2333
2334 rte == #category-bits << 28 | #ostype-bits << 23 | #dist-bits << 16 | #distrel-bits
2335 rte == encode_rte_segments_to_32bit(#category-bits, #ostype-bits, #dist-bits, #distrel-bits)
2336 rte == encode_rte_segments_to_32bit( *decode_rte_to_segments( rte ) )
2337
2338 Raises:
2339 pass-through
2340
2341 """
2342 rte = get_rte2num(rte)
2343 return ((rte & RTE_CATEGORY_B), (rte & RTE_OSTYPE_B), (rte & RTE_DIST_B), (rte & RTE_DISTREL_B))
2344
2345
2347 """Decodes the compressed components from the 32bit integer bitmask
2348 into the corresponding tuple of partial integer enums.
2349
2350 Args:
2351 rte:
2352 The comppressed runtime environment identifier bitmask.
2353
2354 default := RTE
2355
2356 Returns:
2357 Tuple of integer values of the components. ::
2358
2359 ret := => (#category-num, #ostype-num, #dist-num, #distrel-num)
2360
2361 Where the following os true: ::
2362
2363 ret == #category-num | #ostype-num | #dist-num | #distrel-num
2364 ret == #category-num + #ostype-num + #dist-num + #distrel-num
2365
2366 Raises:
2367 pass-through
2368
2369 """
2370 rte = get_rte2num(rte)
2371 return ((rte & RTE_CATEGORY), (rte & RTE_OSTYPE), (rte & RTE_DIST), (rte & RTE_DISTREL))
2372
2373
2375 """Decodes the compressed components from the 32bit integer bitmask
2376 into the corresponding tuple of string keywords.
2377
2378 Args:
2379 rte:
2380 The comppressed runtime environment identifier bitmask.
2381
2382 default := RTE
2383
2384 Returns:
2385 Tuple of keywords of string values for the components. ::
2386
2387 ret := => (<category>, <ostype>, <dist>, <distrel>)
2388
2389 Raises:
2390 pass-through
2391
2392 """
2393 try:
2394 try:
2395 _rte = rte2num[rte]
2396 except KeyError:
2397 if type(rte) not in ISINT:
2398
2399 raise
2400
2401
2402 _rte = rte
2403
2404 if (_rte & RTE_OSTYPE) == RTE_NT:
2405
2406 return (
2407 get_num2rte(_rte & RTE_CATEGORY),
2408 get_num2rte(_rte & RTE_OSTYPE),
2409 get_num2rte(_rte & RTE_DIST),
2410 get_num2rte(_rte & RTE_DIST) + str(_rte & RTE_DISTREL_B)
2411 )
2412
2413 elif _rte & RTE_DISTEXT:
2414
2415 return (
2416 get_num2rte(_rte & RTE_CATEGORY),
2417 get_num2rte(_rte & RTE_OSTYPE),
2418 get_num2rte(_rte & RTE_DIST),
2419 get_num2rte(_rte & RTE_DISTREL)
2420 )
2421
2422
2423 else:
2424
2425 return (
2426 num2rte[(_rte & RTE_CATEGORY)],
2427 num2rte[(_rte & RTE_OSTYPE)],
2428 num2rte[(_rte & RTE_DIST)],
2429 num2rte[(_rte & RTE_DISTREL)]
2430 )
2431
2432 except:
2433 if type(rte) in ISINT:
2434 pass
2435
2437 """Gets the corresponding string representation
2438 for the string numeric value.
2439
2440 Alternatively the official dict *num2rte*
2441 could be used.
2442
2443 Args:
2444 num:
2445 Numeric enum value of the requested platform.
2446
2447 Returns:
2448 The string value, or *None**.
2449
2450 Raises:
2451 None
2452
2453 """
2454 if type(num) not in ISINT:
2455 return str(num)
2456 return num2rte.get(num)
2457
2458
2460 """Gets corresponding numerical representation
2461 for the numeric or string value.
2462
2463 Alternatively the official dict *rte2num*
2464 could be used.
2465
2466 Args:
2467 rte:
2468 Numeric enum value or string representation
2469 of the requested platform.
2470
2471 Returns:
2472 The numeric value, or *None**.
2473
2474 Raises:
2475 None
2476
2477 """
2478 if type(rte) in ISINT:
2479 return rte
2480
2481
2482
2483
2484
2485 try:
2486 return rte2num.get(rte)
2487 except TypeError:
2488 raise PlatformIDsError(
2489 "TypeError: requires a valid key for 'platformids.rte2num' (int, str)- got:" + str(type(rte)))
2490
2491
2493 """Sets the numeric to string map.
2494
2495 Alternatively the official dict *num2rte*
2496 could be used.
2497
2498 Args:
2499 key:
2500 Numeric key value.
2501
2502 value:
2503 String value.
2504
2505 Returns:
2506 None
2507
2508 Raises:
2509 PlatformIDsError
2510
2511 """
2512 if type(key) != int:
2513 raise PlatformIDsError("requires a int key, got: " + str(key))
2514 if type(value) not in ISSTR:
2515 raise PlatformIDsError("requires a string value, got: " + str(value))
2516
2517 num2rte[key] = value
2518
2519
2521 """Sets the rte to numeric mapping
2522
2523 Alternatively the official dict *rte2num*
2524 could be used.
2525
2526 Args:
2527 key:
2528 Numeric or string key value.
2529
2530 value:
2531 Numeric value.
2532
2533 Returns:
2534 None
2535
2536 Raises:
2537 None
2538
2539 """
2540 if type(value) != int:
2541 raise PlatformIDsError("requires an int value, got: " + str(value))
2542 rte2num[key] = value
2543
2544
2545 pass
2546