Avoid corruption when calling mg_get to retrieve the value
[p5sagit/p5-mst-13.2.git] / symbian / PerlApp.cpp
CommitLineData
27da23d5 1/* Copyright (c) 2004-2005 Nokia. All rights reserved. */
2
0added8b 3/* The PerlApp application is licensed under the same terms as Perl itself.
ed76c0e4 4 * Note that this PerlApp is for Symbian/Series 60/80 smartphones and it has
5 * nothing whatsoever to do with the ActiveState PerlApp. */
0added8b 6
27da23d5 7#include "PerlApp.h"
8
ed76c0e4 9#ifdef __SERIES60__
10# include <avkon.hrh>
11# include <aknnotewrappers.h>
12# include <AknCommonDialogs.h>
13# ifndef __SERIES60_1X__
14# include <CAknFileSelectionDialog.h>
15# endif
16#endif /* #ifdef __SERIES60__ */
17
18#ifdef __SERIES80__
19# include <eikon.hrh>
20# include <cknflash.h>
21# include <ckndgopn.h>
c7a4d1c0 22# include <ckndgfob.h>
23# include <eiklabel.h>
24# include <cknconf.h>
ed76c0e4 25#endif /* #ifdef __SERIES80__ */
26
27da23d5 27#include <apparc.h>
28#include <e32base.h>
29#include <e32cons.h>
30#include <eikenv.h>
31#include <bautils.h>
32#include <eikappui.h>
33#include <utf.h>
34#include <f32file.h>
35
27da23d5 36#include <coemain.h>
37
c7a4d1c0 38#ifndef PerlAppMinimal
0added8b 39
27da23d5 40#include "PerlApp.hrh"
ed76c0e4 41
27da23d5 42#include "PerlApp.rsg"
43
c7a4d1c0 44#ifdef __SERIES80__
45#include "Eikon.rsg"
46#endif /* #ifdef __SERIES80__ */
47
48#endif //#ifndef PerlAppMinimal
0added8b 49
3c09d611 50#include "EXTERN.h"
e0f47ab0 51#include "perl.h"
27da23d5 52#include "PerlBase.h"
53
0added8b 54const TUid KPerlAppUid = {
c7a4d1c0 55#ifdef PerlAppMinimalUid
56 PerlAppMinimalUid
0added8b 57#else
58 0x102015F6
59#endif
60};
61
62_LIT(KDefaultScript, "default.pl");
27da23d5 63
64// This is like the Symbian _LIT() but without the embedded L prefix,
65// which enables using #defined constants (which need to carry their
66// own L prefix).
67#ifndef _LIT_NO_L
0added8b 68# define _LIT_NO_L(n, s) static const TLitC<sizeof(s)/2> n={sizeof(s)/2-1,s}
27da23d5 69#endif // #ifndef _LIT_NO_L
70
c7a4d1c0 71#ifdef PerlAppMinimalName
72_LIT_NO_L(KAppName, PerlAppMinimalName);
0added8b 73#else
27da23d5 74_LIT(KAppName, "PerlApp");
0added8b 75#endif
76
c7a4d1c0 77#ifndef PerlAppMinimal
f26f4a2f 78
27da23d5 79_LIT_NO_L(KFlavor, PERL_SYMBIANSDK_FLAVOR);
80_LIT(KAboutFormat,
81 "Perl %d.%d.%d, Symbian port %d.%d.%d, built for %S SDK %d.%d");
82_LIT(KCopyrightFormat,
83 "Copyright 1987-2005 Larry Wall and others, Symbian port Copyright Nokia 2004-2005");
84_LIT(KInboxPrefix, "\\System\\Mail\\");
85_LIT(KScriptPrefix, "\\Perl\\");
86
87_LIT8(KModulePrefix, SITELIB); // SITELIB from Perl config.h
88
89typedef TBuf<256> TMessageBuffer;
90typedef TBuf8<256> TPeekBuffer;
91typedef TBuf8<256> TFileName8;
92
c7a4d1c0 93#endif // #ifndef PerlAppMinimal
f26f4a2f 94
27da23d5 95// Usage: DEBUG_PRINTF((_L("%S"), &aStr))
96#if 1
97#define DEBUG_PRINTF(s) {TMessageBuffer message; message.Format s; YesNoDialogL(message);}
98#endif
99
f26f4a2f 100static void DoRunScriptL(TFileName aScriptName);
101
27da23d5 102TUid CPerlAppApplication::AppDllUid() const
103{
104 return KPerlAppUid;
105}
106
107enum TPerlAppPanic
108{
109 EPerlAppCommandUnknown = 1
110};
111
112void Panic(TPerlAppPanic aReason)
113{
114 User::Panic(KAppName, aReason);
115}
116
117void CPerlAppUi::ConstructL()
118{
119 BaseConstructL();
120 iAppView = CPerlAppView::NewL(ClientRect());
121 AddToStackL(iAppView);
122 iFs = NULL;
123 CEikonEnv::Static()->DisableExitChecks(ETrue); // Symbian FAQ-0577.
124}
125
126CPerlAppUi::~CPerlAppUi()
127{
128 if (iAppView) {
129 iEikonEnv->RemoveFromStack(iAppView);
130 delete iAppView;
131 iAppView = NULL;
132 }
133 if (iFs) {
134 delete iFs;
135 iFs = NULL;
136 }
137 if (iDoorObserver) // Otherwise the embedding application waits forever.
138 iDoorObserver->NotifyExit(MApaEmbeddedDocObserver::EEmpty);
139}
140
c7a4d1c0 141#ifndef PerlAppMinimal
0added8b 142
ed76c0e4 143#ifdef __SERIES60__
144
27da23d5 145static TBool DlgOk(CAknNoteDialog* dlg)
146{
147 return dlg && dlg->RunDlgLD() == EAknSoftkeyOk;
148}
149
ed76c0e4 150#endif /* #ifdef __SERIES60__ */
151
27da23d5 152static TBool OkCancelDialogL(TDesC& aMessage)
153{
ed76c0e4 154#ifdef __SERIES60__
27da23d5 155 CAknNoteDialog* dlg =
156 new (ELeave) CAknNoteDialog(CAknNoteDialog::EConfirmationTone);
157 dlg->PrepareLC(R_OK_CANCEL_DIALOG);
158 dlg->SetTextL(aMessage);
159 return DlgOk(dlg);
ed76c0e4 160#endif /* #ifdef __SERIES60__ */
161#ifdef __SERIES80__
c7a4d1c0 162 return CCknConfirmationDialog::RunDlgWithDefaultIconLD(aMessage, R_EIK_BUTTONS_CANCEL_OK);
ed76c0e4 163#endif /* #ifdef __SERIES80__ */
27da23d5 164}
165
166static TBool YesNoDialogL(TDesC& aMessage)
167{
ed76c0e4 168#ifdef __SERIES60__
27da23d5 169 CAknNoteDialog* dlg =
170 new (ELeave) CAknNoteDialog(CAknNoteDialog::EConfirmationTone);
171 dlg->PrepareLC(R_YES_NO_DIALOG);
172 dlg->SetTextL(aMessage);
173 return DlgOk(dlg);
ed76c0e4 174#endif /* #ifdef __SERIES60__ */
175#ifdef __SERIES80__
c7a4d1c0 176 return CCknConfirmationDialog::RunDlgWithDefaultIconLD(aMessage, R_EIK_BUTTONS_NO_YES);
ed76c0e4 177#endif /* #ifdef __SERIES80__ */
27da23d5 178}
179
c7a4d1c0 180static void InformationNoteL(TDesC& aMessage)
27da23d5 181{
ed76c0e4 182#ifdef __SERIES60__
27da23d5 183 CAknInformationNote* note = new (ELeave) CAknInformationNote;
c7a4d1c0 184 note->ExecuteLD(aMessage);
ed76c0e4 185#endif /* #ifdef __SERIES60__ */
186#ifdef __SERIES80__
c7a4d1c0 187 CEikonEnv::Static()->InfoMsg(aMessage);
ed76c0e4 188#endif /* #ifdef __SERIES80__ */
27da23d5 189}
190
191static TInt WarningNoteL(TDesC& aMessage)
192{
ed76c0e4 193#ifdef __SERIES60__
27da23d5 194 CAknWarningNote* note = new (ELeave) CAknWarningNote;
195 return note->ExecuteLD(aMessage);
ed76c0e4 196#endif /* #ifdef __SERIES60__ */
197#ifdef __SERIES80__
198 CEikonEnv::Static()->AlertWin(aMessage);
199 return ETrue;
200#endif /* #ifdef __SERIES80__ */
27da23d5 201}
202
c7a4d1c0 203#ifdef __SERIES80__
204
205CPerlAppTextQueryDialog::CPerlAppTextQueryDialog(HBufC*& aBuffer) :
206 iData(aBuffer)
207{
208}
209
210TBool CPerlAppTextQueryDialog::OkToExitL(TInt /* aKeycode */)
211{
212 iData = static_cast<CEikEdwin*>(Control(EPerlAppTextQueryInputField))->GetTextInHBufL();
213 return ETrue;
214}
215
216void CPerlAppTextQueryDialog::PreLayoutDynInitL()
217{
218 SetTitleL(iTitle);
219 CEikLabel* promptLabel = ControlCaption(EPerlAppTextQueryInputField);
220 promptLabel->SetTextL(iPrompt);
221}
222
223/* TODO: OfferKeyEventL() so that newline can be seen as 'OK'.
224 * Or a hotkey for the button? */
225
226#endif /* #ifdef __SERIES80__ */
227
228static TInt TextQueryDialogL(const TDesC& aTitle, const TDesC& aPrompt, TDes& aData, const TInt aMaxLength)
27da23d5 229{
ed76c0e4 230#ifdef __SERIES60__
27da23d5 231 CAknTextQueryDialog* dlg =
232 new (ELeave) CAknTextQueryDialog(aData);
233 dlg->SetPromptL(aPrompt);
234 dlg->SetMaxLength(aMaxLength);
235 return dlg->ExecuteLD(R_TEXT_QUERY_DIALOG);
ed76c0e4 236#endif /* #ifdef __SERIES60__ */
237#ifdef __SERIES80__
c7a4d1c0 238 HBufC* data = NULL;
239 CPerlAppTextQueryDialog* dlg =
240 new (ELeave) CPerlAppTextQueryDialog(data);
241 dlg->iTitle.Set(aTitle);
242 dlg->iPrompt.Set(aPrompt);
243 dlg->iMaxLength = aMaxLength;
244 if (dlg->ExecuteLD(R_PERL_ONELINER_DIALOG)) {
245 aData.Copy(*data);
246 return ETrue;
247 }
248 return EFalse;
249#endif /* #ifdef __SERIES80__ */
250}
251
252static TBool FileQueryDialogL(TDes& aFilename)
253{
254#ifdef __SERIES60__
255 return AknCommonDialogs::RunSelectLD(aFilename,
256 R_MEMORY_SELECTION_DIALOG);
257#endif /* #ifdef __SERIES60__ */
258#ifdef __SERIES80__
259 if (CCknOpenFileDialog::RunDlgLD(aFilename,
260 CCknFileListDialogBase::EShowAllDrives
261 |CCknFileListDialogBase::EShowSystemFilesAndFolders
262 |CCknFileListDialogBase::EShowBothFilesAndFolders
263 )) {
264 TEntry aEntry; // Be paranoid and check that the file is there.
265 RFs aFs;
266 aFs.Connect();
267 if (aFs.Entry(aFilename, aEntry) == KErrNone)
268 return ETrue;
269 else
270 CEikonEnv::Static()->InfoMsg(_L("File not found"));
271 }
272 return EFalse;
273#endif /* #ifdef __SERIES80__ */
27da23d5 274}
275
276// The isXXX() come from the Perl headers.
277#define FILENAME_IS_ABSOLUTE(n) \
278 (isALPHA(((n)[0])) && ((n)[1]) == ':' && ((n)[2]) == '\\')
279
280static TBool IsInPerl(TFileName aFileName)
281{
282 TInt offset = aFileName.FindF(KScriptPrefix);
283 return ((offset == 0 && // \foo
284 aFileName[0] == '\\')
285 ||
286 (offset == 2 && // x:\foo
287 FILENAME_IS_ABSOLUTE(aFileName)));
288}
289
290static TBool IsInInbox(TFileName aFileName)
291{
292 TInt offset = aFileName.FindF(KInboxPrefix);
293 return ((offset == 0 && // \foo
294 aFileName[0] == '\\')
295 ||
296 (offset == 2 && // x:\foo
297 FILENAME_IS_ABSOLUTE(aFileName)));
298}
299
300static TBool IsPerlModule(TParsePtrC aParsed)
301{
302 return aParsed.Ext().CompareF(_L(".pm")) == 0;
303}
304
305static TBool IsPerlScript(TParsePtrC aParsed)
306{
307 return aParsed.Ext().CompareF(_L(".pl")) == 0;
308}
309
310static void CopyFromInboxL(RFs aFs, const TFileName& aSrc, const TFileName& aDst)
311{
312 TBool proceed = ETrue;
313 TMessageBuffer message;
314
315 message.Format(_L("%S is untrusted. Install only if you trust provider."), &aDst);
316 if (OkCancelDialogL(message)) {
317 message.Format(_L("Install as %S?"), &aDst);
318 if (OkCancelDialogL(message)) {
319 if (BaflUtils::FileExists(aFs, aDst)) {
320 message.Format(_L("Replace old %S?"), &aDst);
321 if (!OkCancelDialogL(message))
322 proceed = EFalse;
323 }
324 if (proceed) {
325 // Create directory?
326 TInt err = BaflUtils::CopyFile(aFs, aSrc, aDst);
327 if (err == KErrNone) {
328 message.Format(_L("Installed %S"), &aDst);
c7a4d1c0 329 InformationNoteL(message);
27da23d5 330 }
331 else {
332 message.Format(_L("Failure %d installing %S"), err, &aDst);
333 WarningNoteL(message);
334 }
335 }
336 }
337 }
338}
339
340static TBool FindPerlPackageName(TPeekBuffer aPeekBuffer, TInt aOff, TFileName& aFn)
341{
342 aFn.SetMax();
343 TInt m = aFn.MaxLength();
344 TInt n = aPeekBuffer.Length();
345 TInt i = 0;
346 TInt j = aOff;
347
348 aFn.SetMax();
349 // The following is a little regular expression
350 // engine that matches Perl package names.
351 if (j < n && isSPACE(aPeekBuffer[j])) {
352 while (j < n && isSPACE(aPeekBuffer[j])) j++;
353 if (j < n && isALPHA(aPeekBuffer[j])) {
354 while (j < n && isALNUM(aPeekBuffer[j])) {
355 while (j < n &&
356 isALNUM(aPeekBuffer[j]) &&
357 i < m)
358 aFn[i++] = aPeekBuffer[j++];
359 if (j + 1 < n &&
360 aPeekBuffer[j ] == ':' &&
361 aPeekBuffer[j + 1] == ':' &&
362 i < m) {
363 aFn[i++] = '\\';
364 j += 2;
365 if (j < n &&
366 isALPHA(aPeekBuffer[j])) {
367 while (j < n &&
368 isALNUM(aPeekBuffer[j]) &&
369 i < m)
370 aFn[i++] = aPeekBuffer[j++];
371 }
372 }
373 }
374 while (j < n && isSPACE(aPeekBuffer[j])) j++;
375 if (j < n && aPeekBuffer[j] == ';' && i + 3 < m) {
376 aFn.SetLength(i);
377 aFn.Append(_L(".pm"));
378 return ETrue;
379 }
380 }
381 }
382 return EFalse;
383}
384
385static void GuessPerlModule(TFileName& aGuess, TPeekBuffer aPeekBuffer, TParse aDrive)
386{
387 TInt offset = aPeekBuffer.Find(_L8("package"));
388 if (offset != KErrNotFound) {
389 const TInt KPackageLen = 7;
390 TFileName q;
391
392 if (!FindPerlPackageName(aPeekBuffer, offset + KPackageLen, q))
393 return;
394
395 TFileName8 p;
396 p.Copy(aDrive.Drive());
397 p.Append(KModulePrefix);
398
399 aGuess.SetMax();
400 if (p.Length() + 1 + q.Length() < aGuess.MaxLength()) {
401 TInt i = 0, j;
402
403 for (j = 0; j < p.Length(); j++)
404 aGuess[i++] = p[j];
405 aGuess[i++] = '\\';
406 for (j = 0; j < q.Length(); j++)
407 aGuess[i++] = q[j];
408 aGuess.SetLength(i);
409 }
410 else
411 aGuess.SetLength(0);
412 }
413}
414
415static TBool LooksLikePerlL(TPeekBuffer aPeekBuffer)
416{
417 return aPeekBuffer.Left(2).Compare(_L8("#!")) == 0 &&
418 aPeekBuffer.Find(_L8("perl")) != KErrNotFound;
419}
420
421static TBool InstallStuffL(const TFileName &aSrc, TParse aDrive, TParse aFile, TPeekBuffer aPeekBuffer, RFs aFs)
422{
423 TFileName aDst;
424 TPtrC drive = aDrive.Drive();
425 TPtrC namext = aFile.NameAndExt();
426
427 aDst.Format(_L("%S%S%S"), &drive, &KScriptPrefix, &namext);
428 if (!IsPerlScript(aDst) && !LooksLikePerlL(aPeekBuffer)) {
429 aDst.SetLength(0);
430 if (IsPerlModule(aDst))
431 GuessPerlModule(aDst, aPeekBuffer, aDrive);
432 }
433 if (aDst.Length() > 0) {
434 CopyFromInboxL(aFs, aSrc, aDst);
435 return ETrue;
436 }
437
438 return EFalse;
439}
440
27da23d5 441static TBool RunStuffL(const TFileName& aScriptName, TPeekBuffer aPeekBuffer)
442{
443 TBool isModule = EFalse;
444
445 if (IsInPerl(aScriptName) &&
446 (IsPerlScript(aScriptName) ||
447 (isModule = IsPerlModule(aScriptName)) ||
448 LooksLikePerlL(aPeekBuffer))) {
449 TMessageBuffer message;
450
451 if (isModule)
452 message.Format(_L("Really run module %S?"), &aScriptName);
453 else
454 message.Format(_L("Run %S?"), &aScriptName);
455 if (YesNoDialogL(message))
456 DoRunScriptL(aScriptName);
27da23d5 457 return ETrue;
458 }
459
460 return EFalse;
461}
462
463void CPerlAppUi::InstallOrRunL(const TFileName& aFileName)
464{
465 TParse aFile;
466 TParse aDrive;
467 TMessageBuffer message;
468
469 aFile.Set(aFileName, NULL, NULL);
470 if (FILENAME_IS_ABSOLUTE(aFileName)) {
471 aDrive.Set(aFileName, NULL, NULL);
472 } else {
473 TFileName appName =
474 CEikonEnv::Static()->EikAppUi()->Application()->AppFullName();
475 aDrive.Set(appName, NULL, NULL);
476 }
477 if (!iFs)
478 iFs = &CEikonEnv::Static()->FsSession();
479 RFile f;
480 TInt err = f.Open(*iFs, aFileName, EFileRead);
481 if (err == KErrNone) {
482 TPeekBuffer aPeekBuffer;
483 err = f.Read(aPeekBuffer);
484 f.Close(); // Release quickly.
485 if (err == KErrNone) {
486 if (!(IsInInbox(aFileName) ?
487 InstallStuffL(aFileName, aDrive, aFile, aPeekBuffer, *iFs) :
488 RunStuffL(aFileName, aPeekBuffer))) {
489 message.Format(_L("Failed for file %S"), &aFileName);
490 WarningNoteL(message);
491 }
492 } else {
493 message.Format(_L("Error %d reading %S"), err, &aFileName);
494 WarningNoteL(message);
495 }
496 } else {
497 message.Format(_L("Error %d opening %S"), err, &aFileName);
498 WarningNoteL(message);
499 }
500 if (iDoorObserver)
501 delete CEikonEnv::Static()->EikAppUi();
502 else
503 Exit();
504}
505
c7a4d1c0 506#endif // #ifndef PerlAppMinimal
0added8b 507
508static void DoRunScriptL(TFileName aScriptName)
509{
510 CPerlBase* perl = CPerlBase::NewInterpreterLC();
511 TRAPD(error, perl->RunScriptL(aScriptName));
c7a4d1c0 512#ifndef PerlAppMinimal
0added8b 513 if (error != KErrNone) {
514 TMessageBuffer message;
515 message.Format(_L("Error %d"), error);
516 YesNoDialogL(message);
517 }
c7a4d1c0 518#endif // #ifndef PerlAppMinimal
0added8b 519 CleanupStack::PopAndDestroy(perl);
520}
521
c7a4d1c0 522#ifndef PerlAppMinimal
f26f4a2f 523
27da23d5 524void CPerlAppUi::OpenFileL(const TDesC& aFileName)
525{
526 InstallOrRunL(aFileName);
527 return;
528}
529
c7a4d1c0 530#endif // #ifndef PerlAppMinimal
f26f4a2f 531
27da23d5 532TBool CPerlAppUi::ProcessCommandParametersL(TApaCommand aCommand, TFileName& /* aDocumentName */, const TDesC8& /* aTail */)
533{
0added8b 534 if (aCommand == EApaCommandRun) {
535 TFileName appName = Application()->AppFullName();
ed76c0e4 536 TParse p;
537 p.Set(KDefaultScript, &appName, NULL);
538 TEntry aEntry;
539 RFs aFs;
540 aFs.Connect();
541 if (aFs.Entry(p.FullName(), aEntry) == KErrNone) {
542 DoRunScriptL(p.FullName());
543 Exit();
544 }
0added8b 545 }
27da23d5 546 return aCommand == EApaCommandOpen ? ETrue : EFalse;
547}
548
c7a4d1c0 549#ifndef PerlAppMinimal
f26f4a2f 550
27da23d5 551void CPerlAppUi::SetFs(const RFs& aFs)
552{
553 iFs = (RFs*) &aFs;
554}
555
c7a4d1c0 556#endif // #ifndef PerlAppMinimal
f26f4a2f 557
ed76c0e4 558static void DoHandleCommandL(TInt aCommand) {
c7a4d1c0 559#ifndef PerlAppMinimal
27da23d5 560 TMessageBuffer message;
c7a4d1c0 561#endif // #ifndef PerlAppMinimal
27da23d5 562
563 switch(aCommand)
564 {
c7a4d1c0 565#ifndef PerlAppMinimal
27da23d5 566 case EPerlAppCommandAbout:
567 {
568 message.Format(KAboutFormat,
569 PERL_REVISION,
570 PERL_VERSION,
571 PERL_SUBVERSION,
572 PERL_SYMBIANPORT_MAJOR,
573 PERL_SYMBIANPORT_MINOR,
574 PERL_SYMBIANPORT_PATCH,
575 &KFlavor,
576 PERL_SYMBIANSDK_MAJOR,
577 PERL_SYMBIANSDK_MINOR
578 );
579 InformationNoteL(message);
580 }
581 break;
582 case EPerlAppCommandTime:
583 {
584 CPerlBase* perl = CPerlBase::NewInterpreterLC();
585 const char *const argv[] =
586 { "perl", "-le",
587 "print 'Running in ', $^O, \"\\n\", scalar localtime" };
588 perl->ParseAndRun(sizeof(argv)/sizeof(char*), (char **)argv, 0);
589 CleanupStack::PopAndDestroy(perl);
590 }
591 break;
592 case EPerlAppCommandRunFile:
593 {
27da23d5 594 TFileName aScriptUtf16;
ed76c0e4 595 aScriptUtf16.Copy(_L("C:\\"));
c7a4d1c0 596 if (FileQueryDialogL(aScriptUtf16))
597 DoRunScriptL(aScriptUtf16);
ed76c0e4 598 }
27da23d5 599 break;
600 case EPerlAppCommandOneLiner:
601 {
c7a4d1c0 602#ifdef __SERIES60__
27da23d5 603 _LIT(prompt, "Oneliner:");
c7a4d1c0 604#endif /* #ifdef __SERIES60__ */
605#ifdef __SERIES80__
606 _LIT(prompt, "Code:"); // The title has "Oneliner" already.
607#endif /* #ifdef __SERIES80__ */
ed76c0e4 608 CPerlAppUi* cAppUi =
609 STATIC_CAST(CPerlAppUi*, CEikonEnv::Static()->EikAppUi());
c7a4d1c0 610 if (TextQueryDialogL(_L("Oneliner"),
611 prompt,
ed76c0e4 612 cAppUi->iOneLiner,
613 KPerlAppOneLinerSize)) {
614 const TUint KPerlAppUtf8Multi = 3;
27da23d5 615 TBuf8<KPerlAppUtf8Multi * KPerlAppOneLinerSize> utf8;
616
ed76c0e4 617 CnvUtfConverter::ConvertFromUnicodeToUtf8(utf8, cAppUi->iOneLiner);
27da23d5 618 CPerlBase* perl = CPerlBase::NewInterpreterLC();
619 int argc = 3;
620 char **argv = (char**) malloc(argc * sizeof(char *));
621 User::LeaveIfNull(argv);
622
623 TCleanupItem argvCleanupItem = TCleanupItem(free, argv);
624 CleanupStack::PushL(argvCleanupItem);
625 argv[0] = (char *) "perl";
626 argv[1] = (char *) "-le";
627 argv[2] = (char *) utf8.PtrZ();
628 perl->ParseAndRun(argc, argv);
629 CleanupStack::PopAndDestroy(2, perl);
630 }
631 }
632 break;
633 case EPerlAppCommandCopyright:
634 {
635 message.Format(KCopyrightFormat);
636 InformationNoteL(message);
637 }
638 break;
ed76c0e4 639 case EPerlAppCommandAboutCopyright:
640 {
641 TMessageBuffer m1;
642 TMessageBuffer m2;
643 m1.Format(KAboutFormat,
644 PERL_REVISION,
645 PERL_VERSION,
646 PERL_SUBVERSION,
647 PERL_SYMBIANPORT_MAJOR,
648 PERL_SYMBIANPORT_MINOR,
649 PERL_SYMBIANPORT_PATCH,
650 &KFlavor,
651 PERL_SYMBIANSDK_MAJOR,
652 PERL_SYMBIANSDK_MINOR
653 );
c7a4d1c0 654 InformationNoteL(m1);
655 User::After((TTimeIntervalMicroSeconds32) (1000*1000));
ed76c0e4 656 m2.Format(KCopyrightFormat);
c7a4d1c0 657 InformationNoteL(m2);
ed76c0e4 658 }
659 break;
c7a4d1c0 660#endif // #ifndef PerlAppMinimal
27da23d5 661 default:
662 Panic(EPerlAppCommandUnknown);
ed76c0e4 663 }
664}
665
666#ifdef __SERIES60__
667
668void CPerlAppUi::HandleCommandL(TInt aCommand)
669{
670 switch(aCommand)
671 {
672 case EEikCmdExit:
673 case EAknSoftkeyExit:
674 Exit();
675 break;
676 default:
677 DoHandleCommandL(aCommand);
678 break;
679 }
680}
681
682#endif /* #ifdef __SERIES60__ */
683
684#ifdef __SERIES80__
685
686void CPerlAppView::HandleCommandL(TInt aCommand) {
687 DoHandleCommandL(aCommand);
688}
689
690void CPerlAppUi::HandleCommandL(TInt aCommand) {
691 switch(aCommand)
692 {
693 case EEikCmdExit:
694 Exit();
695 break;
696 default:
697 iAppView->HandleCommandL(aCommand);
27da23d5 698 break;
699 }
700}
701
ed76c0e4 702#endif /* #ifdef __SERIES80__ */
703
27da23d5 704CPerlAppView* CPerlAppView::NewL(const TRect& aRect)
705{
706 CPerlAppView* self = CPerlAppView::NewLC(aRect);
707 CleanupStack::Pop(self);
708 return self;
709}
710
711CPerlAppView* CPerlAppView::NewLC(const TRect& aRect)
712{
713 CPerlAppView* self = new (ELeave) CPerlAppView;
714 CleanupStack::PushL(self);
715 self->ConstructL(aRect);
716 return self;
717}
718
719void CPerlAppView::ConstructL(const TRect& aRect)
720{
721 CreateWindowL();
722 SetRect(aRect);
723 ActivateL();
724}
725
ed76c0e4 726CPerlAppView::~CPerlAppView()
727{
728}
729
27da23d5 730void CPerlAppView::Draw(const TRect& /*aRect*/) const
731{
732 CWindowGc& gc = SystemGc();
733 TRect rect = Rect();
734 gc.Clear(rect);
735}
736
737CApaDocument* CPerlAppApplication::CreateDocumentL()
738{
739 CPerlAppDocument* document = new (ELeave) CPerlAppDocument(*this);
740 return document;
741}
742
743CEikAppUi* CPerlAppDocument::CreateAppUiL()
744{
745 CPerlAppUi* appui = new (ELeave) CPerlAppUi();
746 return appui;
747}
748
f26f4a2f 749
c7a4d1c0 750#ifndef PerlAppMinimal
f26f4a2f 751
ed76c0e4 752CFileStore* CPerlAppDocument::OpenFileL(TBool aDoOpen, const TDesC& aFileName, RFs& aFs)
27da23d5 753{
754 CPerlAppUi* appui =
755 STATIC_CAST(CPerlAppUi*, CEikonEnv::Static()->EikAppUi());
756 appui->SetFs(aFs);
ed76c0e4 757 if (aDoOpen)
758 appui->OpenFileL(aFileName);
27da23d5 759 return NULL;
760}
761
c7a4d1c0 762#endif // #ifndef PerlAppMinimal
f26f4a2f 763
27da23d5 764EXPORT_C CApaApplication* NewApplication()
765{
766 return new CPerlAppApplication;
767}
768
769GLDEF_C TInt E32Dll(TDllReason /*aReason*/)
770{
771 return KErrNone;
772}
773