2012-05-08 17 views
5

आपूर्ति करता हूं कहता हूं कि मैंने proc f1 proc f2 और proc f3 परिभाषित किया है। अब मैं एक टीसीएल दुभाषिया बनाना चाहता हूं, उस दुभाषिया में proc f1 proc f2 और proc f3 का कोड स्रोत करें और f1, f2 और f3 के अलावा सभी आदेशों को प्रतिबंधित करें उस दुभाषिया के भीतर हैं। मैं यह कैसे कर सकता हूँ?एक टीसीएल दुभाषिया बनाएं जो केवल उन आदेशों का समर्थन करता है जो मैं

संपादित करें:

एक कमांड अन्य हैं कि F1, F2 और F3 दुभाषिया मुझे एक त्रुटि संदेश जारी किया जाना चाहिए और दुभाषिया के स्रोत वाली कोड के निष्पादन (मान बनाया है के भीतर कहा जाता है कि यह एक और कोड जो एफ 1, एफ 2 और एफ 3 प्रोसेस के साथ कोड सोर्स करने के बाद, उसी दुभाषिया में सोर्स किया जाता है) को रोका जाना चाहिए।

उत्तर

9

आप काफी ऐसा नहीं कर सकते हैं, लेकिन आप ऐसा कुछ कर सकते हैं जो अधिकांश उद्देश्यों के लिए समान है।

आपको क्या करना चाहिए सामान्य रूप से एक दुभाषिया में f1, f2 और f3 कमांड बनाना है, फिर एक उप-दुभाषिया बनाएं जिसमें कोई टीसीएल आदेश नहीं है, और उपनाम जो आप उप- माता-पिता में आदेशों के लिए दुभाषिया।

# First define f1-f3 in whatever way you want 

# Now make the context; we'll use a safe interpreter for good measure... 
set slave [interp create -safe] 

# Scrub namespaces, then global vars, then commands 
foreach ns [$slave eval namespace children ::] { 
    $slave eval namespace delete $ns 
} 
foreach v [$slave eval info vars] { 
    $slave eval unset $v 
} 
foreach cmd [$slave eval info commands] { 
    # Note: we're hiding, not completely removing 
    $slave hide $cmd 
} 

# Make the aliases for the things we want 
foreach cmd {f1 f2 f3} { 
    $slave alias $cmd $cmd 
} 

# And evaluate the untrusted script in it 
catch {$slave invokehidden source $theScript} 

# Finally, kill the untrusted interpreter 
interp delete $slave 
+2

आप भी 'अज्ञात' कमांड को परिभाषित करना चाहते हैं ताकि आप अपरिभाषित आदेशों के बेहतर संचालन कर सकें, लेकिन यह वैकल्पिक है। –

+0

बहुत बहुत धन्यवाद। मुझे लगता है कि मैं यही चाहता था। – Narek

2

यहां एक साधारण समाधान है: लाइन द्वारा इनपुट लाइन पढ़ें। तो पहले टोकन F1, F2, या f3, फिर कमांड निष्पादित है, मारा नियंत्रण + सी या exit टाइप पाश बाहर निकलने के लिए:

proc f1 {args} { puts "f1:$args" } 
proc f2 {args} { puts "f2:$args" } 
proc f3 {args} { puts "f3:$args" } 

while 1 { 
    puts -nonewline ">" 
    flush stdout 
    gets stdin line 
    set firstToken [lindex $line 0] 
    if {[lsearch {f1 f2 f3 exit} $firstToken] != -1} { 
     eval $line 
    } 
} 

इस समाधान के साथ कई समस्याएं हैं:

  1. Eval खतरनाक माना जाता है
  2. ज्यादा संपादन क्षमता है, तो आप कल्पना हो और tclreadline पैकेज का उपयोग करना चाहें

इन दोषों के बावजूद, समाधान लागू करने के लिए बहुत आसान है।

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