2009-05-06 2 views
5

होता है, मैं उन कार्यों को एक बड़ी सीपीपी फ़ाइल में ढूंढना चाहता हूं जिसमें उनके शरीर में एक विशिष्ट शब्द हो।एक cpp फ़ाइल में फ़ंक्शन कैसे ढूंढें जिसमें grep, vim's grep, या अन्य यूनिक्स शैल कमांड का उपयोग करते हुए एक विशिष्ट शब्द

जिन फ़ाइलों के साथ मैं काम कर रहा हूं, उनमें से एक इंडेंट लाइन पर काम कर रहा है, संबंधित फ़ंक्शन हेडर इंडेंट लाइन से ऊपर की पहली पंक्ति है जो स्थिति 0 से शुरू होती है और '{' ।

उदाहरण के लिए

निम्नलिखित कोड का टुकड़ा में JOHN_DOE के लिए खोज

int foo (int arg1) 
{ 
    /// code 
} 
void bar (std::string arg2 ) 
{ 
    /// code 
    aFunctionCall(JOHN_DOE); 
    /// more code 
} 

मुझे

void bar (std::string arg2 ) 

एल्गोरिथ्म है कि मैं ग्रेप/vim/यूनिक्स शेल स्क्रिप्ट में पकड़ने के लिए आशा देना चाहिए होगा शायद सबसे अच्छा उपयोग सी/सी ++ का विश्लेषण करने के बजाय इंडेंटेशन और स्वरूपण धारणाएं।

आपके सुझावों के लिए धन्यवाद।

उत्तर

2

जहाँ तक मुझे पता है, यह नहीं किया जा सकता है। यहां बताया गया है:

सबसे पहले, आपको लाइनों में खोजना होगा। कोई समस्या नहीं, एक वर्ण वर्ग में _ जोड़ने के लिए इसे नई लाइनों को शामिल करने के लिए कहा जाता है। इसलिए {_। *} कई लाइनों में उन ब्रैकेट्स के बीच सब कुछ मेल खाएगा।

तो अब आप मैच के लिए जो कुछ भी पैटर्न एक समारोह हेडर के लिए (भंगुर भले ही आप इसे काम करने के लिए मिलता है) है, तो जरूरत है, और यहाँ समस्या, जो कुछ लाइनों यह और अपने खोज स्ट्रिंग के बीच हैं, और अंत में अपनी खोज स्ट्रिंग से मेल खाते हैं। तो अगर आप की तरह

/^\(void \+\a\+ *(.*)\)\_.*JOHN_DOE 

एक regex हो सकता है लेकिन क्या होता पहली बार vim एक समारोह हैडर पाता है, यह मिलान शुरू होता है। यह तब प्रत्येक चरित्र से मेल खाता है जब तक कि यह JOHN_DOE नहीं मिलता है। जिसमें फ़ाइल में सभी फ़ंक्शन हेडर शामिल हैं।

तो समस्या के रूप में तक मुझे पता है, वहाँ कोई रास्ता नहीं इस regex पैटर्न को छोड़कर हर चरित्र से मेल करने के vim बताने का, है। और यहां तक ​​कि अगर वहां था, तो इस नौकरी के लिए एक रेगेक्स उपकरण नहीं है। यह एक हथौड़ा के साथ एक बियर खोलने की तरह है। हमें क्या करना चाहिए एक साधारण लिपि लिखना जो आपको यह जानकारी देता है, और मेरे पास है।

fun! FindMyFunction(searchPattern, funcPattern) 
    call search(a:searchPattern) 
    let lineNumber = line(".") 
    let lineNumber = lineNumber - 1 
    "call setpos(".", [0, lineNumber, 0, 0]) 

    let lineString = getline(lineNumber) 
    while lineString !~ a:funcPattern 
    let lineNumber = lineNumber - 1 
    if lineNumber < 0 
     echo "Function not found :/" 
    endif 
    let lineString = getline(lineNumber) 
    endwhile 

    echo lineString 

endfunction 

है कि आप परिणाम देना चाहिए आप चाहते हैं और यह भी तरह से, साझा डिबग, और एक नियमित रूप से खुद को Cthulhu के मुंह से थूक अभिव्यक्ति से repurpose करने के लिए आसान है।

1

कठिन कॉल, हालांकि एक शुरुआती बिंदु के रूप में मैं इस अद्भुत VIM Regex Tutorial का सुझाव दूंगा।

1

आप नियमित अभिव्यक्ति के साथ विश्वसनीय रूप से ऐसा नहीं कर सकते हैं, क्योंकि कोड नियमित भाषा नहीं है। प्रश्न में भाषा के लिए आपको एक असली पार्सर चाहिए।

1

यू grep -r -n -H JOHN_DOE * उपयोग कर सकते हैं यह फ़ाइलों रिकर्सिवली वर्तमान निर्देशिका

आप निम्नलिखित कोड का उपयोग कर सकते व्यावहारिक रूप से समारोह जो पाठ अभिव्यक्ति होता है खोजने के लिए से शुरू में "JOHN_DOE" के लिए दिखेगा:

public void findFunction(File file, String expression) { 
    Reader r = null; 
    try { 
     r = new FileReader(file); 
    } catch (FileNotFoundException ex) { 
     ex.printStackTrace(); 
    } 
    BufferedReader br = new BufferedReader(r); 

    String match = ""; 
    String lineWithNameOfFunction = ""; 

    Boolean matchFound = false; 

    try { 
     while(br.read() > 0) { 
      match = br.readLine(); 
      if((match.endsWith(") {")) || 
        (match.endsWith("){")) || 
        (match.endsWith("()")) || 
        (match.endsWith(")")) || 
        (match.endsWith("()"))) { 
       // this here is because i guessed that method will start 
       // at the 0 
       if((match.charAt(0)!=' ') && !(match.startsWith("\t"))) { 
        lineWithNameOfFunction = match;       
       } 
      } 

      if(match.contains(expression)) { 
       matchFound = true; 
       break; 
      } 
     } 
     if(matchFound) 
      System.out.println(lineWithNameOfFunction); 
     else 
      System.out.println("No matching function found"); 
    } catch (IOException ex) { 
     ex.printStackTrace(); 
    } 
} 

मैंने इसे जावा में लिखा, इसका परीक्षण किया और एक आकर्षण की तरह काम करता है। हालांकि कुछ कमियां हैं, लेकिन शुरुआत के लिए यह ठीक है। एक ही अभिव्यक्ति और शायद कुछ अन्य चीजों वाले कई कार्यों के लिए समर्थन नहीं जोड़ा। कोशिश करो।

+0

तो फ़ंक्शन का नाम कहां से आया है? –

+0

हां, ऊपर दिए गए कोड से आना चाहिए, लेकिन मेरा grep कमांड फ़ंक्शन का नाम प्राप्त करने में सक्षम नहीं है। –

0

रॉबर्ट ने कहा कि रेगेक्स मदद करेगा। कमांड मोड में आपके regex के बाद "/" वर्ण टाइप करके एक रेगेक्स खोज शुरू करें।

सीटीएजी 1 आपके लिए भी उपयोग किया जा सकता है। यह एक परियोजना के लिए एक टैग फ़ाइल उत्पन्न कर सकते हैं। यह टैग फ़ाइल किसी उपयोगकर्ता को फ़ंक्शन कॉल से सीधे इसकी परिभाषा तक कूदने की अनुमति देती है भले ही यह "CTRL +]" का उपयोग कर किसी अन्य फ़ाइल में हो।

1

उस तरह की सामग्री के लिए, हालांकि यह फिर से आदिम खोज की बात आती है, मैं compview प्लगइन की अनुशंसा करता हूं। यह एक खोज विंडो खुल जाएगा, ताकि आप पूरी लाइन देख सकें जहां खोज हुई और स्वचालित रूप से उस पर कूदें। एक अच्छा अवलोकन देता है।

alt text http://axisym3.net/jdany/wp-content/images/compview.jpg

1

Arggh! मैं मानता हूं यह शीर्ष पर एक सा है:

एक छोटी सी कार्यक्रम stdin को फिल्टर, पट्टी टिप्पणी, और एक ही लाइन पर समारोह निकायों डाल करने के लिए। यह अन्य चीजों के अलावा, कक्षा घोषणाओं के अंदर नामस्थान और कार्य परिभाषाओं द्वारा बेवकूफ हो जाएगा। लेकिन यह एक अच्छी शुरुआत हो सकती है:

#include <stdio.h> 
#include <assert.h> 

int main() { 
    enum { 
     NORMAL, 
     LINE_COMMENT, 
     MULTI_COMMENT, 
     IN_STRING, 
    } state = NORMAL; 
    unsigned depth = 0; 
    for(char c=getchar(),prev=0; !feof(stdin); prev=c,c=getchar()) { 
     switch(state) { 
     case NORMAL: 
      if('/'==c && '/'==prev) 
       state = LINE_COMMENT; 
      else if('*'==c && '/'==prev) 
       state = MULTI_COMMENT; 
      else if('#'==c) 
       state = LINE_COMMENT; 
      else if('\"'==c) { 
       state = IN_STRING; 
       putchar(c); 
      } else { 
       if(('}'==c && !--depth) || (';'==c && !depth)) { 
        putchar(c); 
        putchar('\n'); 
       } else { 
        if('{'==c) 
         depth++; 
        else if('/'==prev && NORMAL==state) 
         putchar(prev); 
        else if('\t'==c) 
         c = ' '; 
        if(' '==c && ' '!=prev) 
         putchar(c); 
        else if(' '<c && '/'!=c) 
         putchar(c); 
       } 
      } 
      break; 
     case LINE_COMMENT: 
      if(' '>c) 
       state = NORMAL; 
      break; 
     case MULTI_COMMENT: 
      if('/'==c && '*'==prev) { 
       c = '\0'; 
       state = NORMAL; 
      } 
      break; 
     case IN_STRING: 
      if('\"'==c && '\\'!=prev) 
       state = NORMAL; 
      putchar(c); 
      break; 
     default: 
      assert(!"bug"); 
     } 
    } 
    putchar('\n'); 
    return 0; 
} 

इसके C++, तो बस यह एक फ़ाइल में, यह 'स्ट्रिपर' नाम की एक फ़ाइल को संकलन, और उसके बाद:

cat my_source.cpp | ./stripper | grep JOHN_DOE 

तो इनपुट पर विचार करें:

int foo (int arg1) 
{ 
    /// code 
} 
void bar (std::string arg2 ) 
{ 
    /// code 
    aFunctionCall(JOHN_DOE); 
    /// more code 
} 

"cat example.cpp | ./stripper" के उत्पादन में है:

int foo (int arg1) { } 
void bar (std::string arg2){ aFunctionCall(JOHN_DOE); } 

"cat example.cpp | ./stripper | grep JOHN_DOE" के उत्पादन में है:

void bar (std::string arg2){ aFunctionCall(JOHN_DOE); } 

समारोह नाम खोजने का काम पाठक के लिए एक व्यायाम के रूप में छोड़ दिया जाता है (पूर्व में होना करने के लिए एक "(" अपने पिछले पहचानकर्ता लगता है)।

3

मुझे शायद इसके लिए वोट दिया जाएगा!

मैं एक उत्साही (G) विम उपयोगकर्ता हूँ लेकिन जब मैं की समीक्षा करने या कुछ कोड मैं Source Insight का उपयोग समझना चाहते हैं। हालांकि मैं इसे लगभग एक वास्तविक संपादक के रूप में कभी भी उपयोग नहीं करता हूं।

यह इस मामले में वास्तव में आप क्या चाहते हैं करता है, जैसे कि सभी कार्यों/तरीकों का उपयोग करने वाले कुछ प्रकाश डाला डेटा प्रकार दिखाने/परिभाषित/लगातार/आदि ... एक संबंधों विंडो में ...

gif of the relations window from the source insight website http://www.sourceinsight.com/docs35/ae1183f1.gif

आउच! मेरा प्रतिनिधि चला जाता है

+0

चिंता न करें, सुझाव के लिए मेरे अपवित्र से छुटकारा पाने के लिए कुछ डाउनवॉट्स लेंगे। माना जाता है कि मैं व्हेल्डॉग विस्क्रिप्ट को पसंद करता हूं क्योंकि यह सवाल बहुत सटीक रूप से मेल खाता है, जबकि इसके लिए अतिरिक्त सॉफ्टवेयर के उपयोग की आवश्यकता है। – Andy

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