(Py) gccxml का उपयोग करके C / C ++ कोड से मेटा जानकारी निकालें

Gccxml के आगमन से पहले, C / C ++ कोड से मेटा जानकारी निकालने का केवल एक ही तरीका था। शुरू करने के लिए, एक पार्सर लिखना आवश्यक था जो सी ++ भाषा के व्याकरण के साथ सामना कर सकता था। यह वह समस्या नहीं है जो आप आमतौर पर सप्ताहांत में घर पर हल करते हैं।

अब, पार्सर लिखना अब आवश्यक नहीं है। संशोधित gcc संकलक आपके कोड का विश्लेषण करता है और कार्यक्रम में आने वाले सभी नामस्थान, प्रकार, वर्ग और कार्यों का विवरण प्रदान करता है। डेटा XML प्रारूप में जारी किया जाता है और, सिद्धांत रूप में, आगे के स्वचालित विश्लेषण और प्रसंस्करण के लिए तैयार है।

Pygccxml लाइब्रेरी gccxml से प्राप्त XML डेटा को पार्स करने के लिए उपयोगी है। यह सिर्फ एक gccxml प्रारूप पाठक नहीं है - पुस्तकालय एकत्र मेटाडेटा की जांच के लिए इंटरफेस प्रदान करता है; विशेष रूप से, ऐसे तैयार कार्य हैं जो "टी टाइप 1 और टी 2 संगत हैं?" जैसे सवालों का जवाब देते हैं? या "क्लास सी 1 को सी 2 से विरासत में मिला है?" पुस्तकालय पाइथन में लिखा गया है।


पेश है gccxml


Gccxml को किटवेयर में विकसित किया गया था (वे CMake के लेखक भी हैं)। यह GCC से संशोधित C ++ पार्सर है।

आपने शायद अभी तक gxxml स्थापित नहीं किया है। व्यक्तिगत रूप से, मैंने पैकेज मैनेजर का उपयोग करके gccxml स्थापित किया है और इस चरण पर विस्तार से ध्यान देने की आवश्यकता नहीं है। अगर आपके OS के लिए कोई पैकेज मैनेजर नहीं है, तो मुझे डर है कि मैं मदद नहीं कर सकता।

चलिए एक साधारण फ़ंक्शन परिभाषा के साथ शुरू करते हैं।
namespace test { int fn(int a, int b); } 

हम संकलन करते हैं:
 gccxml -fxml=test.xml test.cpp 

आउटपुट निम्न सामग्री (टुकड़ा) के साथ test.xml है:
 <GCC_XML> <Namespace id="_1" name="::" members="… _96 …" mangled="_Z2::" demangled="::"/> <Namespace id="_96" name="test" context="_1" members="_141 " mangled="_Z4test" demangled="test"/> <FundamentalType id="_128" name="int" size="32" align="32"/> <Function id="_141" name="fn" returns="_128" context="_96" mangled="_ZN4test2fnEii" demangled="test::fn(int, int)" location="f1:2" file="f1" line="2" extern="1" > <Argument name="a" type="_128" location="f1:2" file="f1" line="2"/> <Argument name="b" type="_128" location="f1:2" file="f1" line="2"/> </Function> <File id="f1" name="test.cpp"/> </GCC_XML> 

प्रलेखन के बिना यहाँ सब कुछ स्पष्ट है। मैं सी ++ भाषा के अन्य निर्माणों के लिए उदाहरण नहीं दूंगा - वहां सब कुछ समान है। प्राथमिक लक्ष्य हासिल किया जाता है - मेटा-सूचना को आगे के स्वचालित प्रसंस्करण के लिए उपयुक्त प्रारूप में निकाला जाता है।

अधिक मेटा जानकारी पुनर्प्राप्त करना


कभी-कभी स्रोत कोड में C ++ भाषा के शब्दार्थ से अधिक जानकारी होती है। उदाहरण: विंडोज पर एसएएल-एनोटेशन (__in, __out, आदि)

 BOOL WINAPI CreateProcess( __in_opt LPCTSTR lpApplicationName, __inout_opt LPTSTR lpCommandLine, __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes, __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in BOOL bInheritHandles, __in DWORD dwCreationFlags, __in_opt LPVOID lpEnvironment, __in_opt LPCTSTR lpCurrentDirectory, __in LPSTARTUPINFO lpStartupInfo, __out LPPROCESS_INFORMATION lpProcessInformation ); 

उदाहरण: मैक ओएस एक्स के न्यूनतम संस्करण के बारे में जानकारी जिसमें एपीआई फ़ंक्शन उपलब्ध है।

 CFErrorRef CFErrorCreate( CFAllocatorRef allocator, CFStringRef domain, CFIndex code, CFDictionaryRef userInfo ) AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER; 

यहां तक ​​कि यह अतिरिक्त मेटा जानकारी gccxml का उपयोग करके निकाली जा सकती है। Gcc- विशिष्ट C ++ सिंटैक्स एक्सटेंशन, विशेषता निर्माण, हमें यहां मदद करेगा। हम फ़ंक्शन fn की परिभाषा के साथ प्रयोग करेंगे:

 #define __foo __attribute__((gccxml("__foo")) #define __bar __attribute__((gccxml("__bar")) namespace test { __foo int fn(__bar int a, int b); } 

स्रोत पाठ में निकटतम शब्दार्थ इकाई में विशेषताएँ "लागू" की जाती हैं। तो पहला गुण फ़ंक्शन fn से संबंधित है, और दूसरा पैरामीटर a के लिए। Gcc विभिन्न विशेषताओं को समझता है, लेकिन इस मामले में हम केवल gccxml विशेषता में रुचि रखते हैं।

Gccxml fn फ़ंक्शन पर निम्नलिखित जानकारी प्रदान करता है। जैसा कि हम देख सकते हैं, सभी एनोटेशन सहेजे गए हैं और आगे की प्रक्रिया के लिए उपलब्ध हैं।

 <Function id="_141" name="fn" returns="_128" context="_96" mangled="_ZN4test2fnEii" demangled="test::fn(int, int)" location="f1:7" file="f1" line="7" extern="1" attributes="gccxml(__foo)"> <Argument name="a" type="_128" location="f1:7" file="f1" line="7" attributes="gccxml(__bar)"/> <Argument name="b" type="_128" location="f1:7" file="f1" line="7"/> </Function> 


पेश है pygccxml


Pygccxml को रोमन याकोवेन्को और सह द्वारा विकसित किया गया है। परियोजना का लक्ष्य C ++ / Python बाइंडर्स का ऑटोमैटिक प्रोडक्शन है, जो बढ़ावा देने के लिए उपयोग कर रहा है :: python। मुझे आश्चर्य है कि उन्हें SWIG क्यों पसंद नहीं आया?

Pygccxml को पैकेज मैनेजर के माध्यम से या मैन्युअल रूप से ( यहां डाउनलोड करें , स्थापना निर्देश README.txt में) स्थापित किया जा सकता है।

Pygccxml का दस्तावेज़ खराब है। आरंभ करने के लिए, यह पर्याप्त है, लेकिन अगर आपको कुछ ऐसी चीज़ों की ज़रूरत है जो बुनियादी क्षमताओं से परे हैं, तो आपको लाइब्रेरी के स्रोत कोड पर ध्यान देना होगा। यह अजीब है, लेकिन ऑनलाइन देखने के लिए प्रलेखन उपलब्ध नहीं है, इसे केवल डाउनलोड किया जा सकता है।

निम्नलिखित pygccxml लाइब्रेरी का उपयोग करके एक सरल C ++ कोड विश्लेषक का एक उदाहरण है।
स्क्रिप्ट परीक्षण नाम स्थान में घोषित सभी कार्यों को प्रिंट करती है।

 import pygccxml db = pygccxml.parser.parse(['test.cpp']) global_ns = pygccxml.declarations.get_global_namespace(db) for test_ns in global_ns.namespaces('test'): for function in test_ns.calldefs(): pygccxml.declarations.print_declarations(function) 

यहाँ स्क्रिप्ट का परिणाम है:

 free_function_t: 'fn' location: [./test.cpp]:4 artificial: 'False' attributes: gccxml(__foo) demangled: test::fn(int, int) mangled: _ZN4test2fnEii return type: int arguments type: int a, int b 


अपने कोड के लिए विचार


यदि मुझे भाषाओं और संकलक में रुचि नहीं है तो मुझे C ++ कोड का प्रोग्रामेटिक विश्लेषण क्यों करना चाहिए? व्यावहारिक पाठक पूछता है। अब मैं कुछ बहुत ही वास्तविक कार्यों के बारे में बात करूंगा जिनके लिए स्वचालित कोड विश्लेषण की आवश्यकता है।

यहाँ अलेक्सई पखुनोव उर्फ ​​नोटाकेंगुरी लिखते हैं :
मुझे हाल ही में आश्चर्य हुआ कि Win32 API स्तर पर UTF-8 समर्थन का अनुकरण करने वाली कोई लाइब्रेरी क्यों नहीं है। यानी ऐसी लाइब्रेरी लागू होती है, कहते हैं, CreateFileUtf8 प्रस्तावित सिस्टम CreateFileA और CreateFileW के अलावा, और CreateFile मैक्रो तीन विकल्पों में से वांछित कार्यान्वयन का चयन करेगा।
2007 में, अलेक्सी ने नोटपैड 2 में यूनिकोड समर्थन के पारदर्शी कार्यान्वयन के लिए इस तरह की एक लाइब्रेरी बनाने का फैसला किया। यह विंडोज हेडर फाइलों को स्वचालित रूप से संसाधित करने और वांछित लाइब्रेरी को प्रोग्रामेटिक रूप से उत्पन्न करने वाला था। एलेक्सी ने gccxml का उपयोग नहीं किया है और 2012 में उनकी लाइब्रेरी अभी भी तैयार नहीं है।

मेरे अभ्यास से निम्नलिखित दो उदाहरण हैं।

Gccxml का उपयोग करते हुए, मैंने CoreFoundation के लिए C ++ रैपर बनाया, मैक ओएस एक्स में बेस ऑब्जेक्ट ओरिएंटेड सी एपीआई। इस प्रोजेक्ट का लक्ष्य CF वस्तुओं के जीवनकाल पर स्वत: नियंत्रण लागू करना है। हां, मैं एआरसी से वाकिफ हूं।

और यहाँ एक दूसरा उदाहरण है। मेरे पास C ++ में लिखा गया डाटा प्रोसेसिंग सिस्टम है। सिस्टम शुरू में एकल-थ्रेडेड है, प्रदर्शन को बढ़ाने के लिए यह इंटरेक्टिंग ऑब्जेक्ट के हिस्से को विभिन्न प्रवाह में वितरित करने की योजना है। ऐसा करने के लिए, यह प्रॉक्सी कक्षाओं की एक श्रृंखला बनाने वाला है जो एक संदेश को दूसरे धागे पर भेजने के लिए विधि कॉल को रूपांतरित करेगा, जहां संदेश को अनपैक करने के बाद, प्रॉक्सी के पीछे छिपी वस्तु की विधि को बुलाया जाएगा। मौजूदा कोड में परिवर्तन की आवश्यकता नहीं है, क्योंकि किसी भी वस्तु तक पहुंच अभी भी एक ही धारा से की जाती है। एक ही प्रकार के बहुत सारे कोड लिखना आवश्यक है, और यह कार्य एक स्वचालित जनरेटर को सौंपा गया है।

Gccxml की सीमाएँ


दुर्भाग्य से, gccxml के कुछ नुकसान हैं। केवल घोषणाओं को कोड से निकाला जाता है, और फ़ंक्शन निकाय उपलब्ध नहीं हैं। टेम्प्लेट घोषणाएँ भी उपलब्ध नहीं हैं। Gccxml जीसीसी के काफी पुराने संस्करण पर आधारित है और विकास बहुत सक्रिय नहीं है।

Source: https://habr.com/ru/post/In138906/


All Articles