t_tran.cpp
来自「在手机操作系统symbina上使用的一个脚本扩展语言的代码实现,可以参考用于自己」· C++ 代码 · 共 653 行
CPP
653 行
// T_TRAN.CPP
//
// Copyright (c) 1997-2000 Symbian Ltd. All rights reserved.
//
// Command line transaltor ala OPL1993 WATRAN
//
#include <f32file.h>
//#include <fbs.h>
#include <opltran.h>
#include <e32twin.h>
#include "textfile.h"
LOCAL_D RFs theFileServer;
LOCAL_D ROplTextSystem theTextSystem;
LOCAL_D CConsoleTextWin *theConsole=NULL;
LOCAL_D COplModuleTranslator *theTranslator=NULL;
LOCAL_D CTextTranslator::TDebugFlag theDebugFlag=CTextTranslator::ERelease;
LOCAL_D TBuf<0x400> aBuf(0x400); // for console output
LOCAL_C void Printf(TRefByValue<const TDesC> aFmt,...)
//
// Print to the console
//
{
VA_LIST list;
VA_START(list,aFmt);
aBuf.Zero();
aBuf.AppendFormatList(aFmt,list);
theConsole->Write(aBuf);
}
class CLineEdit : public CBase
{
public:
enum TCursorType {ECursorNone=0,ECursorNormal=20,ECursorInsert=100};
enum TEditMode {EEditOverWrite,EEditInsert};
public:
static CLineEdit* NewL(CConsoleBase* aConsole,TInt aMaxHistory);
~CLineEdit();
const TFileName& Edit(const TDesC& aPrompt);
void SetDefaultMode(TEditMode aMode);
protected:
CLineEdit();
TPoint Where();
TInt Lines();
TInt WordLeft();
TInt WordRight();
void ClearLine();
void ClearLast(TInt aCnt);
void Recall();
void Cursor();
void Refresh();
private:
CArrayFixFlat<HBufC*>* iHistory;
CConsoleBase* iConsole; // Not owned
TInt iMaxHistory;
TInt iWidth;
TInt iHeight;
TInt iPos;
TInt iOrg;
TInt iLine;
TInt iRecall;
TEditMode iDefaultMode;
TEditMode iCurrentMode;
TFileName iBuf;
TFileName iPrompt;
};
CLineEdit::CLineEdit()
//
// Constructor
//
{
// iHistory=NULL;
// iConsole=NULL;
// iMaxHistory=0;
// iWidth=0;
// iHeight=0;
// iPos=0;
// iOrg=0;
// iLine=0;
// iRecall=0;
// iDefaultMode=EEditOverWrite;
// iCurrentMode=EEditOverWrite;
// iBuf=_L("");
// iPrompt=_L("");
}
CLineEdit::~CLineEdit()
//
// Destroy the line editor
//
{
TInt count=iHistory->Count();
while (count--)
User::Free((*iHistory)[count]);
delete iHistory;
}
CLineEdit* CLineEdit::NewL(CConsoleBase* aConsole,TInt aMaxHistory)
//
// Create a new line editor
//
{
CLineEdit* pE=new(ELeave) CLineEdit;
pE->iHistory=new(ELeave) CArrayFixFlat<HBufC*>(aMaxHistory+2);
pE->iConsole=aConsole;
pE->iMaxHistory=aMaxHistory;
pE->iWidth=pE->iConsole->ScreenSize().iWidth;
pE->iHeight=pE->iConsole->ScreenSize().iHeight;
return(pE);
}
TInt CLineEdit::Lines()
//
// The number of lines being edited.
//
{
TInt nL=1;
if (((TInt)iBuf.Length())>=(iWidth-2-iOrg))
nL+=(((TInt)iBuf.Length())+iOrg)/(iWidth-2);
return(nL);
}
TPoint CLineEdit::Where()
//
// Return the real cursor position.
//
{
if (iPos>=(iWidth-2-iOrg))
return(TPoint((iPos+iOrg)%(iWidth-2),((iPos+iOrg)/(iWidth-2))+iLine));
return(TPoint(iPos+iOrg,iLine));
}
void CLineEdit::ClearLine()
//
// Clears the line being edited.
//
{
if (iBuf.Length())
{
TInt nL=Lines();
while (nL--)
{
iConsole->SetPos(nL ? 0 : iOrg,iLine+nL);
iConsole->ClearToEndOfLine();
}
iBuf.Zero();
iPos=0;
}
}
void CLineEdit::ClearLast(TInt aCnt)
//
// Clears the last aCnt characters.
//
{
TInt aPos=iPos;
iPos=((TInt)iBuf.Length())-aCnt;
while (iPos<((TInt)iBuf.Length()))
{
TPoint p=Where();
iConsole->SetCursorPosAbs(p);
iConsole->ClearToEndOfLine();
iPos+=(iWidth-p.iX);
}
iPos=aPos;
}
void CLineEdit::Recall()
//
// Recall a line for editing.
//
{
if (iRecall!=(-1))
{
ClearLine();
HBufC* pL=(*iHistory)[iRecall];
iBuf=(*pL);
iConsole->Write(iBuf);
iPos=iBuf.Length();
TInt nL=Lines();
if ((iLine+nL)>(iHeight-2))
iLine=iHeight-2-nL;
iBuf=(*pL);
}
}
TInt CLineEdit::WordLeft()
//
// Position the cursor to the next word left.
//
{
TInt x=iPos-1;
while (x && TChar(iBuf[x]).IsSpace())
x--;
while (x && TChar(iBuf[x]).IsGraph())
x--;
if (TChar(iBuf[x]).IsSpace())
x++;
return(x);
}
TInt CLineEdit::WordRight()
//
// Position the cursor to the next word right.
//
{
TInt x=iPos;
while (x<(TInt)iBuf.Length() && TChar(iBuf[x]).IsGraph())
x++;
while (x<(TInt)iBuf.Length() && TChar(iBuf[x]).IsSpace())
x++;
return(x);
}
void CLineEdit::Cursor()
//
// Position the cursor.
//
{
iConsole->SetCursorPosAbs(Where());
}
void CLineEdit::Refresh()
//
// Refresh the line.
//
{
iConsole->SetCursorHeight(ECursorNone);
iConsole->SetPos(iOrg,iLine);
iConsole->Write(iBuf);
Cursor();
iConsole->SetCursorHeight(iCurrentMode==EEditOverWrite ? ECursorNormal : ECursorInsert);
}
void CLineEdit::SetDefaultMode(TEditMode aMode)
//
// Set the default edit mode
//
{
iDefaultMode=aMode;
}
const TFileName& CLineEdit::Edit(const TDesC& aPrompt)
//
// Start the editor or a single key fetch.
//
{
iPos=0;
iPrompt=aPrompt;
iBuf.Zero();
iCurrentMode=iDefaultMode;
iConsole->SetCursorHeight(iCurrentMode==EEditOverWrite ? ECursorNormal : ECursorInsert);
iConsole->Write(iPrompt);
iOrg=iConsole->WhereX();
iLine=iConsole->WhereY();
iRecall=(-1);
TInt hCount=iHistory->Count();
if (hCount>iMaxHistory)
hCount=iMaxHistory;
FOREVER
{
TChar gChar=iConsole->Getch();
switch (gChar)
{
case EKeyEscape:
ClearLine();
iRecall=(-1);
break;
case EKeyHome:
iPos=0;
Cursor();
break;
case EKeyLeftArrow:
if (iPos)
{
if(iConsole->KeyModifiers()==EModifierCtrl)
{
iPos=WordLeft();
}
else
{
iPos--;
}
Cursor();
}
break;
case EKeyRightArrow:
if (iPos<((TInt)iBuf.Length()))
{
if(iConsole->KeyModifiers()==EModifierCtrl)
{
iPos=WordRight();
}
else
{
iPos++;
}
Cursor();
}
break;
case EKeyEnd:
iPos=((TInt)iBuf.Length());
Cursor();
break;
case EKeyPageUp:
if (hCount==0)
break;
iRecall=hCount-1;
Recall();
break;
case EKeyUpArrow:
if (iRecall==(-1))
{
if (hCount==0)
break;
iRecall=0;
}
else if (iRecall>=(hCount-1))
{
ClearLine();
iRecall=(-1);
break;
}
else
iRecall++;
Recall();
break;
case EKeyDownArrow:
if (iRecall==(-1))
{
if (hCount==0)
break;
iRecall=hCount-1;
}
else if (iRecall==0)
{
ClearLine();
iRecall=(-1);
break;
}
else
iRecall--;
Recall();
break;
case EKeyPageDown:
if (hCount==0)
break;
iRecall=0;
Recall();
break;
case EKeyEnter:
iConsole->SetCursorHeight(ECursorNone);
iConsole->SetPos(0,iLine+Lines()-1); // CR on the last line
iConsole->Write(_L("\n")); // Just a line feed
iConsole->SetCursorHeight(iDefaultMode==EEditOverWrite ? ECursorNormal : ECursorInsert);
iRecall=(-1);
if (((TInt)iBuf.Length())>2)
{
if (((TInt)iHistory->Count())==(iMaxHistory+1))
{
User::Free((*iHistory)[iMaxHistory]);
iHistory->Delete(iMaxHistory);
}
HBufC* pB=iBuf.Alloc();
if (pB!=NULL)
{
TRAPD(r,iHistory->InsertL(0,pB))
};
}
return(iBuf);
case EKeyBackspace:
if (iPos)
{
TInt iN=1;
if (iConsole->KeyModifiers()==EModifierCtrl)
iN=iPos-WordLeft();
ClearLast(iN);
iPos-=iN;
iBuf.Delete(iPos,iN);
Refresh();
}
break;
case EKeyDelete:
if (iPos<((TInt)iBuf.Length()))
{
TInt iN=1;
if (iConsole->KeyModifiers()==EModifierCtrl)
iN=WordRight()-iPos;
ClearLast(iN);
iBuf.Delete(iPos,iN);
Refresh();
}
break;
case EKeyInsert:
iCurrentMode=(iCurrentMode==EEditOverWrite ? EEditInsert : EEditOverWrite);
iConsole->SetCursorHeight(iCurrentMode==EEditOverWrite ? ECursorNormal : ECursorInsert);
break;
default:
if(iConsole->KeyModifiers()&EModifierAlt)
{
if(hCount && gChar>='0' && gChar<='9')
{
iRecall=(gChar-TChar('0'));
if (iConsole->KeyModifiers()&EModifierShift)
iRecall+=10;
if (iRecall>=hCount)
iRecall=hCount-1;
Recall();
}
break;
}
if (!gChar.IsPrint())
break;
if (iCurrentMode==EEditOverWrite && iPos<((TInt)iBuf.Length()))
iBuf[iPos++]=(TText)gChar;
else if (((TInt)iBuf.Length())<0x100)
{
TInt oL=Lines();
TBuf<0x02> b;
b.Append(gChar);
iBuf.Insert(iPos++,b);
TInt nL=Lines();
if (nL!=oL)
{
iConsole->SetCursorHeight(ECursorNone);
iConsole->SetPos(0,iLine+oL-1);
iConsole->Write(_L("\n"));
iConsole->SetPos(0,iLine);
if (iLine+nL>iHeight-2)
iLine=iHeight-2-nL;
}
}
else
{
iConsole->Write(_L("\7"));
break;
}
Refresh();
}
}
}
LOCAL_C void Error(const TDesC& mess,TInt err)
//
//
//
{
Printf(_L("%S failed with error number %d\r\n"),&mess,err);
TRequestStatus status;
theConsole->Read(status);
User::WaitForRequest(status);
}
LOCAL_C TBool ParseCommandLine(TParse &aParse)
//
// Gets the command line from source. Returns ETrue if there is possible on
// the command line and EFalse otherwise
//
{
TBool ret=EFalse;
TBuf<0x100> cmd;
RProcess().CommandLine(cmd);
cmd.Trim();
TLex iLex(cmd);
if (!iLex.Eos())
{
if (theFileServer.Parse(iLex.NextToken(),_L("*.OPL"),aParse)==KErrNone && iLex.Eos())
ret=ETrue;
}
return ret;
}
LOCAL_C void TranslateFile(const TDesC& aSource)
{
Printf(_L("Translating %S\r\n"),&aSource);
TParse output;
TInt r=theFileServer.Parse(_L(".OPO"),aSource,output);
if (r!=KErrNone)
Error(_L("Parsing output file name"),r);
else
{
TSourceTranslateError anErr;
TRAP(r,theTranslator->StartTranslateL(theTextSystem,aSource,output.FullName(),theDebugFlag,anErr));
if (r!=KErrNone)
Error(_L("Starting translation"),r);
else
{
do
{
r=theTranslator->TranslateChunk();
Printf(_L("."));
} while (r==KErrNone);
if (r!=KErrGeneral || anErr.Error()!=EErrSuccess)
{
Printf(_L("\r\nTranslating failed with Error %d, at Offset %d in %S\r\n"), anErr.Error(),anErr.Position(),&anErr.Source());
TRequestStatus status;
theConsole->Read(status);
User::WaitForRequest(status);
}
else
Printf(_L("\r\n%S translated OK\r\n"),&aSource);
}
}
}
LOCAL_D void Translate(TParse& aSource)
//
// Checks for wild-cards and does the necessary
//
{
if (!aSource.IsWild())
TranslateFile(aSource.FullName());
else
{
RDir dir;
TInt r=dir.Open(theFileServer,aSource.FullName(),KEntryAttNormal);
if (r!=KErrNone)
Error(_L("Opening directory"),r);
else
{
TEntry entry;
while (dir.Read(entry)==KErrNone)
{
theFileServer.Parse(entry.iName,aSource.FullName(),aSource);
TranslateFile(aSource.FullName());
}
}
}
}
LOCAL_C TBool ProcessCommand(const TDesC& aCommandLine)
//
// Command line starting with !
//
{
TPtrC command=aCommandLine.Mid(1); // Stuff after the !
TBool ret=EFalse;
if (command.CompareF(_L("QUIT"))==0)
ret=ETrue;
else if (command.CompareF(_L("DEB"))==0)
theDebugFlag=CTextTranslator::EDebug;
else if (command.CompareF(_L("REL"))==0)
theDebugFlag=CTextTranslator::ERelease;
else // if (command.CompareF(_L("HELP")))
Printf(_L("!QUIT to end\r\n!DEB - Produce debug ouput\r\n!REL - Produce release output\r\n!Help Display this message\r\nFilename to translate a file\r\n"));
return ret;
}
GLDEF_C TInt E32Main()
//
//
//
{
CTrapCleanup *trapCleanup=CTrapCleanup::New();
TParse src;
theFileServer.Connect();
theTextSystem.Connect();
// FbsStartup();
// RFbsSession::Connect();
// ER5u problems -- Unresolved external CConsoleTextWin::NewL(Class TDesC16 const &,class TSize
TRAPD(r,theConsole=CConsoleTextWin::NewL(_L("T_TRAN"),TSize(KDefaultConsWidth,KDefaultConsHeight)));
if (r!=KErrNone || theConsole->Console().Control(_L("+Maximize +NewLine -Lock -Wrap"))!=KErrNone)
User::Beep(440,5);
else
{
TBool getKey=ETrue;
TRAPD(r,theTranslator=COplModuleTranslator::NewL())
if (r!=KErrNone)
Error(_L("Allocating the translator"),r);
else
{
TRAP(r,theTranslator->SetTarget(EOplTargetER1));
if (r!=KErrNone)
Error(_L("Setting translator target"),r);
else if (ParseCommandLine(src)) // Passed something plausible on the command line
Translate(src);
else
{
Printf(_L("Enter the name of the file to translate\r\n"));
Printf(_L("Type '!Help' for instructions\r\n"));
CLineEdit*editor=NULL;
TRAP(r,editor=CLineEdit::NewL(theConsole,8));
if (r!=KErrNone)
Error(_L("Creating the line editor"),r);
else
{
FOREVER
{
const TFileName& file=editor->Edit(theDebugFlag==CTextTranslator::ERelease ? _L("Release>") : _L("Debug>"));
if (file.Length()==0)
continue;
if (file.Left(1).Compare(_L("!"))==0)
{
if (ProcessCommand(file))
break;
}
else if ((r=theFileServer.Parse(file,_L("*.OPL"),src))!=KErrNone)
Error(_L("Parsing the file name"),r);
else
Translate(src);
}
getKey=EFalse;
}
}
}
if (getKey)
{
TRequestStatus aStatus;
theConsole->Read(aStatus);
User::WaitForRequest(aStatus);
}
delete theTranslator;
}
delete theConsole;
// RFbsSession::Disconnect();
theTextSystem.Close();
theFileServer.Close();
delete trapCleanup;
return KErrNone;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?