2010-08-23 12 views
13

क्या आप कृपया मुझे एक कस्टम जीसीसी प्रीप्रोसेसर लिखने का उदाहरण दे सकते हैं?कस्टम जीसीसी प्रीप्रोसेसर

मेरा लक्ष्य एसआईडी ("foo") को उचित सीआरसी 32 गणना मूल्यों के साथ समान मैक्रोज़ को प्रतिस्थापित करना है। किसी भी अन्य मैक्रो के लिए मैं मानक सीपीपी प्रीप्रोसेसर का उपयोग करना चाहता हूं।

ऐसा लगता है कि -no-integrated-cpp -B विकल्पों का उपयोग करके इस लक्ष्य को हासिल करना संभव है, हालांकि मुझे उनके उपयोग का कोई आसान उदाहरण नहीं मिल रहा है।

+4

यह आपके प्रश्न का उत्तर नहीं दे रहा है, लेकिन क्या आपने अपनी टेम्पलेट फ़ाइल (उदाहरण के लिए 'example.c.tmpl') लेते हुए एक समर्थन स्क्रिप्ट लिखने पर विचार किया है, सीआरसी की गणना करता है और आउटपुट फ़ाइल में प्रतिस्थापन करता है (उदाहरण के लिए' example.c') अपनी मेक प्रक्रिया के हिस्से के रूप में? –

+1

मेरी स्थिति में यह असुविधाजनक है क्योंकि मेरे पास कोई विशेष टेम्पलेट नहीं है, इसलिए ये एसआईडी मैक्रो स्रोत कोड में कहीं भी हो सकता है। बेशक, मैं एक कस्टम मेक लक्ष्य जोड़ सकता हूं जो सभी * .cpp स्रोतों को एक साधारण स्क्रिप्ट बदलते हुए एसआईडी मैक्रो के साथ संसाधित करता है और फिर मैग्लेड स्रोतों को जीसीसी में पास करता है .... लेकिन मुझे लगता है कि एक कस्टम प्रीप्रोसेसर का उपयोग करना अधिक सुरुचिपूर्ण हो सकता है। – pachanga

+0

क्या आपने मानक तरीके से प्रयास किया है: #undef SID # एसआईडी परिभाषित करें? –

उत्तर

21

चेतावनी: खतरनाक और बदसूरत हैक। अपनी आंखें बंद करें आप जीसीसी कमांड लाइन में '-नो-एकीकृत-सीपीपी' और '-बी' स्विच जोड़कर अपने स्वयं के प्रीप्रोसेसर को हुक कर सकते हैं। '-no-integr-cpp' का अर्थ है कि जीसीसी अपने प्रीप्रोसेसरों के लिए '-B' पथ में अपने आंतरिक खोज पथ का उपयोग करने से पहले खोज करता है। प्रीप्रोसेसर के आविष्कार की पहचान की जा सकती है यदि 'सीसी 1', 'सीसी 1 प्लस' या 'सीसी 1obj' प्रोग्राम (ये सी, सी ++ और ऑब्जेक्टिव-सी कंपाइलर्स) '-E' विकल्प के साथ आते हैं। जब आप यह विकल्प देखते हैं तो आप अपना खुद का प्रीप्रोकैसिंग कर सकते हैं। जब कोई '-ई' विकल्प मूल प्रोग्राम में सभी पैरामीटर पास नहीं करता है। जब ऐसा कोई विकल्प होता है, तो आप अपना खुद का प्रीप्रोकैसिंग कर सकते हैं, और मैनिपुलेटेड फ़ाइल को मूल कंपाइलर में पास कर सकते हैं।

यह इस तरह दिखता है:

> cat cc1 
#!/bin/sh 

echo "My own special preprocessor -- [email protected]" 

/usr/lib/gcc/i486-linux-gnu/4.3/cc1 [email protected] 
exit $? 

> chmod 755 cc1 
> gcc -no-integrated-cpp -B$PWD x.c 
My own special preprocessor -- -E -quiet x.c -mtune=generic -o /tmp/cc68tIbc.i 
My own special preprocessor -- -fpreprocessed /tmp/cc68tIbc.i -quiet -dumpbase x.c -mtune=generic -auxbase x -o /tmp/cc0WGHdh.s 

यह उदाहरण मूल पूर्वप्रक्रमक कहता है, लेकिन एक अतिरिक्त संदेश और मानकों प्रिंट करता है। आप स्क्रिप्ट को अपने प्रीप्रोसेसर द्वारा प्रतिस्थापित कर सकते हैं।

खराब हैक खत्म हो गया है। अब आप अपनी आंखें खोल सकते हैं।

+0

एचएम ... अगर मैं गलत हूं तो मुझे सही करें लेकिन मैंने सोचा कि इस दृष्टिकोण का उपयोग करके मैं एसआईडी मैक्रोज़ को प्रतिस्थापित कर सकता हूं, परिणाम को कुछ temp फ़ाइल में सहेज सकता हूं और फिर इस temp फ़ाइल में मानक प्रीप्रोसेसर लागू कर सकता हूं। नहीं? – pachanga

+0

@ पचंगा हां, आपको इनपुट और आउटपुट फ़ाइलों के लिए कमांड लाइन विकल्प निकालने की आवश्यकता है, और अपने प्रोसेसर के आउटपुट के लिए दूसरी टेम्पफाइल लिखें (मुझे विश्वास है कि आपको फ़ाइल एक्सटेंशन को संरक्षित करने की आवश्यकता है)। फिर आप संसाधित फ़ाइल को इनपुट फ़ाइल पैरामीटर को पैच करके मूल फ़ाइल (टीएम) प्रीप्रोसेसर को इनपुट फ़ाइल के रूप में पास करते हैं। लेकिन वे सभी अन्य मापदंडों को जिस तरह से थे, छोड़ दें, क्योंकि उनमें से कुछ स्थिति निर्भर हैं (जैसे- I, -D या -U)। मूल (टीएम) प्रीप्रोसेसर के बाद आप अपना टेम्पफाइल साफ़ कर देते हैं और मूल (टीएम) प्रीप्रोसेसर के निकास कोड के साथ छोड़ देते हैं। – Rudi

+3

थोड़ा सा सुधार: आप स्वचालित रूप से प्राप्त कर सकते हैं जो इसी पूर्वप्रक्रमक इस तरह चला जाएगा: जी ++ --print-prog नाम = cc1plus तो अपने फिल्टर हो जाता है: #/bin/श गूंज "खुद की विशेष प्रीप्रोसेसर; args = $ @ " $ (g ++ --print-prog-name = cc1plus) $ @ $ बाहर निकलें? – blais

2

एक तरह से एक program transformation system उपयोग करने के लिए, क्या आप इससे पहले कि आप संकलन करना चाहते हैं "को फिर से लिखने के लिए" सिर्फ सिड मैक्रो मंगलाचरण, पूर्वप्रक्रमक संकलक ही निपटने के बाकी छोड़ने है।

हमारे DMS Software Reengineering Toolkit ऐसी एक प्रणाली है, जिसे सी और विशेष रूप से जीसीसी 2/3/4 श्रृंखलाओं की श्रृंखला सहित कई भाषाओं में लागू किया जा सकता है।

डीएमएस का उपयोग करके इस विचार को लागू करने के लिए, आप संकलन चरण से पहले अपने स्रोत कोड पर C front end के साथ डीएमएस चलाएंगे। डीएमएस प्रीप्रोसेसर निर्देश का विस्तार किए बिना कोड को पार्स कर सकता है, इसका प्रतिनिधित्व करने वाले अमूर्त वाक्यविन्यास पेड़ बनाएं, एएसटी पर परिवर्तन करें, और फिर परिणाम को संकलित सी टेक्स्ट के रूप में थूक दें।

विशिष्ट परिवर्तन नियम आप का प्रयोग करेंगे है:

rule replace_SID_invocation(s:STRING):expression->expression 
      = "SID(\s)" -> ComputeCRC32(s); 

जहां ComputeCRC32 कस्टम कोड है कि यह क्या कहते है। (डीएमएस में सीआरसी 32 कार्यान्वयन शामिल है, इसलिए इसके लिए कस्टम कोड बहुत छोटा है।

डीएमएस इस कार्य के लिए बहुत बड़ा हथौड़ा है। आप PERL का उपयोग कुछ समान रूप से लागू करने के लिए कर सकते हैं। PERL (या कुछ अन्य स्ट्रिंग के साथ अंतर मैच/हैक को प्रतिस्थापित करें) जोखिम है कि ए) यह पैटर्न कहीं भी मिल सकता है जहां आप प्रतिस्थापन नहीं चाहते हैं, उदाहरण के लिए

... QSID("foo")... // this isn't a SID invocation 

जो आप शायद अपने पैटर्न मैच ध्यान से कोडिंग से ठीक कर सकते हैं, ख) एक सिड कॉल आश्चर्य की बात परिस्थितियों में पाया मैच के लिए असफल:

... SID (/* master login id */ "Joel") ... // need to account for formatting and whitespace 

और ग) भागने के विभिन्न प्रकार संभाल करने में विफल अक्षर हैं जो शाब्दिक स्ट्रिंग में ही दिखाई देते हैं:

... SID("f\no\072") ... // need to handle all of GCC's weird escapes 

डीएमएस के सी सामने अंत आप के लिए सभी पलायन संभालती है; उपरोक्त ComputeCRC32 फ़ंक्शन वास्तविक इच्छित वर्ण वाले स्ट्रिंग को देखेगा, न कि स्रोत कोड में कच्चे पाठ को देखते हैं।

तो यह वास्तव में एक बात है कि आप अंधेरे कोने के मामलों की परवाह करते हैं, या यदि आपको लगता है कि आपके पास अधिक विशेष प्रसंस्करण हो सकती है।

जिस तरह से आपने समस्या का वर्णन किया है, उसे देखते हुए, मुझे सबसे पहले पर्ल मार्ग पर जाने और मजाकिया मामलों को दूर करने का लुत्फ उठाना होगा। यदि आप ऐसा नहीं कर सकते हैं, तो बड़ा हथौड़ा समझ में आता है।

संबंधित मुद्दे