]>
git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/c++-lib/c++/tcl-if.cpp
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
19 // file: .../c++-lib/src/tcl-if.C
21 // $Header: /cvs/root/Security/SecuritySNACCRuntime/c++-lib/c++/Attic/tcl-if.cpp,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
22 // $Log: tcl-if.cpp,v $
23 // Revision 1.1.1.1 2001/05/18 23:14:06 mb
24 // Move from private repository to open source repository
26 // Revision 1.2 2001/05/05 00:59:17 rmurphy
27 // Adding darwin license headers
29 // Revision 1.1 2000/06/15 18:44:58 dmitch
30 // These snacc-generated source files are now checked in to allow cross-platform build.
32 // Revision 1.2 2000/06/08 20:05:37 dmitch
33 // Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
35 // Revision 1.1.1.1 2000/03/09 01:00:06 rmurphy
36 // Base Fortissimo Tree
38 // Revision 1.2 1999/02/26 00:23:41 mb
41 // Revision 1.1 1999/02/25 05:21:57 mb
42 // Added snacc c++ library
44 // Revision 1.6 1997/02/28 13:39:47 wan
45 // Modifications collected for new version 1.3: Bug fixes, tk4.2.
47 // Revision 1.5 1997/01/01 23:24:35 rj
48 // `typename' appears to be a reserved word in gcc 2.7, so prefix it with `_'
50 // Revision 1.4 1995/09/07 18:57:13 rj
51 // duplicate code merged into a new function SnaccTcl::gettypedesc().
53 // Revision 1.3 1995/08/17 15:09:09 rj
54 // snacced.[hC] renamed to tcl-if.[hC].
55 // class SnaccEd renamed to SnaccTcl.
56 // set Tcl's errorCode variable.
58 // Revision 1.2 1995/07/27 09:53:38 rj
59 // comment leader fixed
61 // Revision 1.1 1995/07/27 09:52:22 rj
62 // new file: tcl interface used by snacced.
64 #if !defined(macintosh) && !defined(__APPLE__)
65 #include <sys/types.h>
72 #include <strstream.h>
81 extern "C" int strncasecmp (const char* s1
, const char* s2
, size_t number
);
82 extern "C" int strcasecmp (const char* s1
, const char* s2
);
88 //\[banner "utility functions"]-----------------------------------------------------------------------------------------------------
89 static bool strniabbr (const char *pattern
, const char *test
, size_t min
)
93 if (strlen (pattern
)<min
)
94 fprintf (stderr
, "strniabbr(): strlen (pattern) < min\n");
95 if ((len
= strlen (test
))<min
)
97 return !strncasecmp (pattern
, test
, len
);
100 //\[banner "ctor & dtor"]-----------------------------------------------------------------------------------------------------------
101 ASN1File::ASN1File (const AsnTypeDesc
*typedesc
)
104 pdu
= type
->create();
110 ASN1File::ASN1File (const AsnTypeDesc
*typedesc
, const char *_fn
, int _fd
)
113 pdu
= type
->create();
115 int fnlen
= strlen (_fn
) + 1;
116 fn
= new char [fnlen
];
117 memcpy (fn
, _fn
, fnlen
);
122 ASN1File::~ASN1File()
135 int ASN1File::finfo (Tcl_Interp
*interp
)
137 Tcl_AppendElement (interp
, fn
? fn
: "");
142 if ((flags
= fcntl (fd
, F_GETFL
)) != -1)
143 switch (flags
& O_ACCMODE
)
156 Tcl_AppendElement (interp
, acc
);
161 int ASN1File::read (Tcl_Interp
*interp
, const char *rfn
)
167 pdu
= type
->create();
171 if ((rfd
= open (rfn
, O_RDONLY
)) < 0)
173 Tcl_AppendResult (interp
, "can't open \"", rfn
, "\": ", Tcl_PosixError (interp
), NULL
);
180 Tcl_AppendResult (interp
, "can't read, file is not open", NULL
);
181 Tcl_SetErrorCode (interp
, "SNACC", "MUSTOPEN", NULL
);
187 lseek (rfd
= fd
, 0l, SEEK_SET
);
191 if (fstat (rfd
, &statbuf
))
193 Tcl_AppendResult (interp
, "can't fstat \"", rfn
, "\": ", Tcl_PosixError (interp
), NULL
);
197 filesize
= statbuf
.st_size
;
199 char* buf
= new char[filesize
];
200 if (::read (rfd
, buf
, filesize
) != filesize
)
202 Tcl_AppendResult (interp
, "can't read \"", rfn
, "\": ", Tcl_PosixError (interp
), NULL
);
208 inputBuf
.InstallData (buf
, filesize
);
210 size_t decodedLen
= 0;
213 if (eval
= setjmp (env
))
216 sprintf (eno
, "%d", eval
);
217 Tcl_AppendResult (interp
, "can't decode (error ", eno
, ")", NULL
);
218 Tcl_SetErrorCode (interp
, "SNACC", "DECODE", eno
, NULL
);
222 pdu
->BDec (inputBuf
, decodedLen
, env
);
223 if (inputBuf
.ReadError())
225 Tcl_AppendResult (interp
, "can't decode, out of data", NULL
);
226 Tcl_SetErrorCode (interp
, "SNACC", "DECODE", "EOBUF", NULL
);
232 cout
<< "DECODED:" << endl
<< *pdu
<< endl
;
235 if (decodedLen
!= filesize
)
236 sprintf (interp
->result
, "decoded %d of %d bytes", decodedLen
, filesize
);
242 int ASN1File::write (Tcl_Interp
*interp
, const char *wfn
)
249 if ((wfd
= open (wfn
, O_CREAT
|O_TRUNC
|O_WRONLY
, 0666)) < 0)
251 Tcl_AppendResult (interp
, "can't open \"", wfn
, "\": ", Tcl_PosixError (interp
), NULL
);
258 Tcl_AppendResult (interp
, "can't write, file is not open", NULL
);
259 Tcl_SetErrorCode (interp
, "SNACC", "MUSTOPEN", NULL
);
266 if ((flags
= fcntl (fd
, F_GETFL
)) == -1)
268 Tcl_AppendResult (interp
, "can't fcntl \"", wfn
, "\": ", Tcl_PosixError (interp
), NULL
);
273 if ((flags
& O_ACCMODE
) == O_RDONLY
)
275 Tcl_AppendResult (interp
, "can't write, file is read only", NULL
);
276 Tcl_SetErrorCode (interp
, "SNACC", "WRITE", "RDONLY", NULL
);
280 lseek (wfd
= fd
, 0l, SEEK_SET
);
283 size_t size
= filesize
? filesize
: 10240;
290 buf
= new char[size
];
291 outputBuf
.Init (buf
, size
);
292 outputBuf
.ResetInWriteRvsMode();
293 encodedLen
= pdu
->BEnc (outputBuf
);
294 if (!outputBuf
.WriteError())
299 outputBuf
.ResetInReadMode();
300 size_t hunklen
= 8192;
301 char* hunk
= new char[hunklen
];
302 for (size_t written
=0; written
<encodedLen
; written
+=hunklen
)
304 if (encodedLen
-written
< hunklen
)
305 hunklen
= encodedLen
- written
;
306 outputBuf
.CopyOut (hunk
, hunklen
);
307 if (::write (wfd
, hunk
, hunklen
) != hunklen
)
309 Tcl_AppendResult (interp
, "write error on \"", wfn
, "\": ", Tcl_PosixError (interp
), NULL
);
310 delete hunk
; // may affect errno
311 delete buf
; // may affect errno
319 filesize
= encodedLen
;
321 ftruncate (wfd
, filesize
);
326 //\[banner "import & export"]-------------------------------------------------------------------------------------------------------
327 int import (Tcl_Interp
*interp
, int argc
, char **argv
)
331 strcpy (interp
->result
, "wrong # args: should be \"snacc import filename\"");
335 const char *fn
= argv
[1];
337 if ((fd
= open (fn
, O_RDONLY
)) < 0)
339 Tcl_AppendResult (interp
, "can't open \"", fn
, "\": ", Tcl_PosixError (interp
), NULL
);
345 if (fstat (fd
, &statbuf
))
347 Tcl_AppendResult (interp
, "can't fstat \"", fn
, "\"'s fd: ", Tcl_PosixError (interp
), NULL
);
351 off_t filesize
= statbuf
.st_size
;
353 char* ibuf
= new char[filesize
];
354 if (::read (fd
, ibuf
, filesize
) != filesize
)
356 Tcl_AppendResult (interp
, "read error on \"", fn
, "\": ", Tcl_PosixError (interp
), NULL
);
361 int result
= debinify (interp
, ibuf
, filesize
);
366 int export (Tcl_Interp
*interp
, int argc
, char **argv
)
370 strcpy (interp
->result
, "wrong # args: should be \"snacc export str filename\"");
374 const char *str
= argv
[1], *fn
= argv
[2];
375 char* obuf
= new char[strlen (str
)]; // the binary buffer is as most as long as the escaped Tcl string.
377 if (binify (interp
, str
, obuf
, &olen
) != TCL_OK
)
384 if ((fd
= open (fn
, O_CREAT
|O_TRUNC
|O_WRONLY
, 0666)) < 0)
386 Tcl_AppendResult (interp
, "can't open \"", fn
, "\": ", Tcl_PosixError (interp
), NULL
);
392 if (::write (fd
, obuf
, olen
) != olen
)
394 Tcl_AppendResult (interp
, "write error on \"", fn
, "\": ", Tcl_PosixError (interp
), NULL
);
403 //\[banner "ctor & dtor"]-----------------------------------------------------------------------------------------------------------
404 SnaccTcl::SnaccTcl (Tcl_Interp
*i
)
408 Tcl_InitHashTable (&modules
, TCL_STRING_KEYS
);
409 Tcl_InitHashTable (&types
, TCL_STRING_KEYS
);
411 const AsnModuleDesc
**moddesc
;
412 for (moddesc
=asnModuleDescs
; *moddesc
; moddesc
++)
415 Tcl_HashEntry
*entry
= Tcl_CreateHashEntry (&modules
, (char*)(*moddesc
)->name
, &created
);
417 Tcl_SetHashValue (entry
, *moddesc
);
419 const AsnTypeDesc
**typedesc
;
420 for (typedesc
=(*moddesc
)->types
; *typedesc
; typedesc
++)
423 sprintf (buf
, "%s %s", (*moddesc
)->name
, (*typedesc
)->name
);
424 char *_typename
= strdup (buf
);
426 Tcl_HashEntry
*entry
= Tcl_CreateHashEntry (&types
, _typename
, &created
);
429 cerr
<< "fatal error: duplicate type " << _typename
<< endl
;
432 Tcl_SetHashValue (entry
, *typedesc
);
436 Tcl_InitHashTable (&files
, TCL_STRING_KEYS
);
439 SnaccTcl::~SnaccTcl()
441 Tcl_DeleteHashTable (&files
);
444 //\[banner "utility functions"]-----------------------------------------------------------------------------------------------------
445 const AsnTypeDesc
*SnaccTcl::gettypedesc (const char *cmdname
, const char *_typename
)
447 Tcl_HashEntry
*typedescentry
;
448 if (typedescentry
= Tcl_FindHashEntry (&types
, (char*)_typename
))
449 return (const AsnTypeDesc
*)Tcl_GetHashValue (typedescentry
);
452 Tcl_SetErrorCode (interp
, "SNACC", "ILLTYPE", NULL
);
453 Tcl_AppendResult (interp
, "snacc ", cmdname
, ": no type \"", _typename
, "\"", NULL
);
458 //\[banner "data manipulation functions"]-------------------------------------------------------------------------------------------
459 Tcl_HashEntry
*SnaccTcl::create()
461 static unsigned int id
;
463 Tcl_HashEntry
*entry
;
466 sprintf (interp
->result
, "file%u", id
++);
467 entry
= Tcl_CreateHashEntry (&files
, interp
->result
, &created
);
473 int SnaccTcl::create (int argc
, char **argv
)
477 strcpy (interp
->result
, "wrong # args: should be \"snacc create {module type}\"");
481 const char *_typename
= argv
[1];
482 const AsnTypeDesc
*typedesc
;
483 if (!(typedesc
= gettypedesc ("type", _typename
)))
486 Tcl_HashEntry
*entry
= create();
487 ASN1File
*file
= new ASN1File (typedesc
);
488 Tcl_SetHashValue (entry
, file
);
493 //\[sep]----------------------------------------------------------------------------------------------------------------------------
494 // snacc open {module type} filename ?flags? ?permissions?
496 int SnaccTcl::openfile (int argc
, char **argv
)
498 if (argc
< 3 || argc
> 5)
500 strcpy (interp
->result
, "wrong # args: should be \"snacc open {module type} filename ?flags? ?permissions?\"");
504 const char *_typename
= argv
[1];
505 const char *filename
= argv
[2];
506 bool rw_spec
= false;
507 int oflags
= 0, omode
= 0666, fd
= -1;
512 if (Tcl_GetInt (interp
, argv
[4], &omode
))
518 if (Tcl_SplitList (interp
, argv
[3], &flags
.c
, &flags
.v
) != TCL_OK
)
521 for (int i
=0; i
<flags
.c
; i
++)
523 if (strniabbr ("truncate", flags
.v
[i
], 1))
525 else if (strniabbr ("create", flags
.v
[i
], 1))
527 else if (!strcasecmp ("ro", flags
.v
[i
]))
532 else if (!strcasecmp ("rw", flags
.v
[i
]))
539 Tcl_AppendResult (interp
, "snacc open: illegal argument \"", flags
.v
[i
], "\" in flags", NULL
);
547 const AsnTypeDesc
*typedesc
;
548 if (!(typedesc
= gettypedesc ("open", _typename
)))
552 fd
= open (filename
, oflags
, omode
);
554 if ((fd
= open (filename
, oflags
| O_RDWR
, omode
)) < 0)
555 fd
= open (filename
, oflags
| O_RDONLY
, omode
);
559 Tcl_AppendResult (interp
, "can't open \"", filename
, "\": ", Tcl_PosixError (interp
), NULL
);
563 ASN1File
*file
= new ASN1File (typedesc
, filename
, fd
);
567 Tcl_AppendResult (interp
, "internal error on \"", filename
, "\": bad status", NULL
);
568 Tcl_SetErrorCode (interp
, "SNACC", "OPEN", "BAD", NULL
);
572 Tcl_HashEntry
*entry
= create();
573 Tcl_SetHashValue (entry
, file
);
575 return file
->read (interp
);
578 //\[sep]----------------------------------------------------------------------------------------------------------------------------
579 int SnaccTcl::finfo (int argc
, char **argv
)
583 strcpy (interp
->result
, "wrong # args: should be \"snacc finfo file\"");
587 Tcl_HashEntry
*entry
= Tcl_FindHashEntry (&files
, argv
[1]);
590 Tcl_AppendResult (interp
, "no file named \"", argv
[1], "\"", NULL
);
594 ASN1File
*file
= (ASN1File
*)Tcl_GetHashValue (entry
);
596 return file
->finfo (interp
);
599 //\[sep]----------------------------------------------------------------------------------------------------------------------------
600 // snacc read file ?{module type} filename?
602 int SnaccTcl::read (int argc
, char **argv
)
604 const char *_typename
, *filename
;
608 case 2: // reread from old fd
609 _typename
= filename
= NULL
;
616 strcpy (interp
->result
, "wrong # args: should be \"snacc read file ?{module type} filename?\"");
620 Tcl_HashEntry
*entry
= Tcl_FindHashEntry (&files
, argv
[1]);
623 Tcl_AppendResult (interp
, "no file named \"", argv
[1], "\"", NULL
);
627 ASN1File
*file
= (ASN1File
*)Tcl_GetHashValue (entry
);
631 const AsnTypeDesc
*typedesc
;
632 if (!(typedesc
= gettypedesc ("read", _typename
)))
636 file
= new ASN1File (typedesc
);
637 Tcl_SetHashValue (entry
, file
);
640 return file
->read (interp
, filename
);
643 //\[sep]----------------------------------------------------------------------------------------------------------------------------
644 int SnaccTcl::write (int argc
, char **argv
)
646 if (argc
< 2 || argc
> 3)
648 strcpy (interp
->result
, "wrong # args: should be \"snacc write file ?filename?\"");
652 Tcl_HashEntry
*entry
= Tcl_FindHashEntry (&files
, argv
[1]);
655 Tcl_AppendResult (interp
, "no file named \"", argv
[1], "\"", NULL
);
659 ASN1File
*file
= (ASN1File
*)Tcl_GetHashValue (entry
);
661 return file
->write (interp
, argv
[2]);
664 //\[sep]----------------------------------------------------------------------------------------------------------------------------
665 int SnaccTcl::closefile (int argc
, char **argv
)
669 strcpy (interp
->result
, "wrong # args: should be \"snacc close file\"");
673 Tcl_HashEntry
*entry
= Tcl_FindHashEntry (&files
, argv
[1]);
676 Tcl_AppendResult (interp
, "no file named \"", argv
[1], "\"", NULL
);
680 ASN1File
*file
= (ASN1File
*)Tcl_GetHashValue (entry
);
683 Tcl_DeleteHashEntry (entry
);
688 //\[sep]----------------------------------------------------------------------------------------------------------------------------
689 int SnaccTcl::modulesinfo (int argc
, char **argv
)
693 strcpy (interp
->result
, "wrong # args: should be \"snacc modules\"");
697 Tcl_HashEntry
*moduleentry
;
699 for (moduleentry
=Tcl_FirstHashEntry (&modules
, &hi
); moduleentry
; moduleentry
=Tcl_NextHashEntry (&hi
))
700 Tcl_AppendElement (interp
, Tcl_GetHashKey (&modules
, moduleentry
));
705 //\[sep]----------------------------------------------------------------------------------------------------------------------------
706 int SnaccTcl::typesinfo (int argc
, char **argv
)
711 Tcl_HashEntry
*typeentry
;
713 for (typeentry
=Tcl_FirstHashEntry (&types
, &hi
); typeentry
; typeentry
=Tcl_NextHashEntry (&hi
))
714 Tcl_AppendElement (interp
, Tcl_GetHashKey (&types
, typeentry
));
717 Tcl_HashEntry
*moduleentry
;
718 if (moduleentry
= Tcl_FindHashEntry (&modules
, argv
[1]))
720 const AsnModuleDesc
*moddesc
= (const AsnModuleDesc
*)Tcl_GetHashValue (moduleentry
);
721 const AsnTypeDesc
**typedesc
;
722 for (typedesc
=moddesc
->types
; *typedesc
; typedesc
++)
723 Tcl_AppendElement (interp
, (char*)(*typedesc
)->name
);
728 Tcl_AppendResult (interp
, "snacc types: no module \"", argv
[1], "\"", NULL
);
732 strcpy (interp
->result
, "wrong # args: should be \"snacc types ?module?\"");
737 //\[sep]----------------------------------------------------------------------------------------------------------------------------
738 int SnaccTcl::typeinfo (int argc
, char **argv
)
742 strcpy (interp
->result
, "wrong # args: should be \"snacc type {module type}\"");
746 const char *_typename
= argv
[1];
747 const AsnTypeDesc
*typedesc
;
748 if (!(typedesc
= gettypedesc ("type", _typename
)))
752 Tcl_DStringInit (&desc
);
753 int rc
= typedesc
->TclGetDesc (&desc
);
754 Tcl_DStringResult (interp
, &desc
);
758 //\[sep]----------------------------------------------------------------------------------------------------------------------------
759 int SnaccTcl::info (int argc
, char **argv
)
763 strcpy (interp
->result
, "wrong # args: should be \"snacc info path\"");
768 if (Tcl_SplitList (interp
, argv
[1], &path
.c
, &path
.v
) != TCL_OK
)
773 strcpy (interp
->result
, "snacc info: wrong # args in path");
777 Tcl_HashEntry
*entry
= Tcl_FindHashEntry (&files
, path
.v
[0]);
780 Tcl_AppendResult (interp
, "snacc info: no file named \"", path
.v
[0], "\"", NULL
);
784 ASN1File
*file
= (ASN1File
*)Tcl_GetHashValue (entry
);
786 AsnType
*var
= (AsnType
*)*file
;
787 for (int i
=1; i
<path
.c
; i
++)
788 if (!(var
= var
->_getref (path
.v
[i
])))
790 Tcl_AppendResult (interp
, "snacc info: illegal component \"", path
.v
[i
], "\" in path", NULL
);
795 Tcl_DStringInit (&desc
);
797 if ((rc
= var
->_getdesc()->AsnTypeDesc::TclGetDesc (&desc
)) == TCL_OK
)
798 rc
= var
->TclGetDesc (&desc
);
799 Tcl_DStringResult (interp
, &desc
);
803 //\[sep]----------------------------------------------------------------------------------------------------------------------------
804 int SnaccTcl::getval (int argc
, char **argv
)
808 strcpy (interp
->result
, "wrong # args: should be \"snacc get path\"");
813 if (Tcl_SplitList (interp
, argv
[1], &path
.c
, &path
.v
) != TCL_OK
)
818 strcpy (interp
->result
, "snacc get: wrong # args in path");
822 Tcl_HashEntry
*entry
= Tcl_FindHashEntry (&files
, path
.v
[0]);
825 Tcl_AppendResult (interp
, "snacc get: no file named \"", path
.v
[0], "\"", NULL
);
829 ASN1File
*file
= (ASN1File
*)Tcl_GetHashValue (entry
);
831 AsnType
*var
= (AsnType
*)*file
;
832 for (int i
=1; i
<path
.c
; i
++)
833 if (!(var
= var
->_getref (path
.v
[i
])))
835 Tcl_AppendResult (interp
, "snacc get: illegal component \"", path
.v
[i
], "\" in path", NULL
);
839 return var
->TclGetVal (interp
);
842 //\[sep]----------------------------------------------------------------------------------------------------------------------------
843 int SnaccTcl::test (int argc
, char **argv
)
847 strcpy (interp
->result
, "wrong # args: should be \"snacc get path\"");
852 if (Tcl_SplitList (interp
, argv
[1], &path
.c
, &path
.v
) != TCL_OK
)
857 strcpy (interp
->result
, "snacc get: wrong # args in path");
861 Tcl_HashEntry
*entry
= Tcl_FindHashEntry (&files
, path
.v
[0]);
864 Tcl_AppendResult (interp
, "snacc get: no file named \"", path
.v
[0], "\"", NULL
);
868 ASN1File
*file
= (ASN1File
*)Tcl_GetHashValue (entry
);
870 AsnType
*var
= (AsnType
*)*file
;
871 for (int i
=1; i
<path
.c
; i
++)
872 if (!(var
= var
->_getref (path
.v
[i
])))
874 Tcl_AppendResult (interp
, "snacc test: illegal component \"", path
.v
[i
], "\" in path", NULL
);
882 cout
<< strlen(s
.str()) << endl
;
883 cout
<< s
.str() << endl
;
888 //\[sep]----------------------------------------------------------------------------------------------------------------------------
889 int SnaccTcl::setval (int argc
, char **argv
)
893 strcpy (interp
->result
, "wrong # args: should be \"snacc set path value\"");
898 if (Tcl_SplitList (interp
, argv
[1], &path
.c
, &path
.v
) != TCL_OK
)
903 strcpy (interp
->result
, "snacc set: wrong # args in path");
907 Tcl_HashEntry
*entry
= Tcl_FindHashEntry (&files
, path
.v
[0]);
910 Tcl_AppendResult (interp
, "snacc set: no file named \"", path
.v
[0], "\"", NULL
);
914 ASN1File
*file
= (ASN1File
*)Tcl_GetHashValue (entry
);
916 AsnType
*var
= (AsnType
*)*file
;
917 for (int i
=1; i
<path
.c
; i
++)
918 if (!(var
= var
->_getref (path
.v
[i
], true)))
920 Tcl_AppendResult (interp
, "snacc set: illegal component \"", path
.v
[i
], "\" in path", NULL
);
924 return var
->TclSetVal (interp
, argv
[2]);
927 //\[sep]----------------------------------------------------------------------------------------------------------------------------
928 int SnaccTcl::unsetval (int argc
, char **argv
)
932 strcpy (interp
->result
, "wrong # args: should be \"snacc unset path\"");
937 if (Tcl_SplitList (interp
, argv
[1], &path
.c
, &path
.v
) != TCL_OK
)
942 strcpy (interp
->result
, "snacc unset: sorry, but you are not allowed to unset the file itself");
947 strcpy (interp
->result
, "snacc unset: wrong # args in path");
951 Tcl_HashEntry
*entry
= Tcl_FindHashEntry (&files
, path
.v
[0]);
954 Tcl_AppendResult (interp
, "snacc unset: no file named \"", path
.v
[0], "\"", NULL
);
958 ASN1File
*file
= (ASN1File
*)Tcl_GetHashValue (entry
);
960 AsnType
*var
= (AsnType
*)*file
;
961 for (int i
=1; i
<path
.c
-1; i
++)
963 if (!(var
= var
->_getref (path
.v
[i
])))
965 Tcl_AppendResult (interp
, "snacc unset: illegal component \"", path
.v
[i
], "\" in path", NULL
);
970 return var
->TclUnsetVal (interp
, path
.v
[path
.c
-1]);
973 //\[sep]----------------------------------------------------------------------------------------------------------------------------
974 int Snacc_Cmd (ClientData cd
, Tcl_Interp
*interp
, int argc
, char **argv
)
976 SnaccTcl
*ed
= (SnaccTcl
*)cd
;
984 strcpy (interp
->result
, "wrong # args: should be \"snacc option arg ?arg ...?\"");
993 if (!strcmp (*argv
, "close"))
994 return ed
->closefile (argc
, argv
);
995 else if (!strcmp (*argv
, "create"))
996 return ed
->create (argc
, argv
);
999 if (!strcmp (*argv
, "export"))
1000 return export (interp
, argc
, argv
);
1003 if (!strcmp (*argv
, "finfo"))
1004 return ed
->finfo (argc
, argv
);
1007 if (!strcmp (*argv
, "get"))
1008 return ed
->getval (argc
, argv
);
1011 if (!strcmp (*argv
, "import"))
1012 return import (interp
, argc
, argv
);
1013 else if (!strcmp (*argv
, "info"))
1014 return ed
->info (argc
, argv
);
1017 if (!strcmp (*argv
, "modules"))
1018 return ed
->modulesinfo (argc
, argv
);
1021 if (!strcmp (*argv
, "open"))
1022 return ed
->openfile (argc
, argv
);
1025 if (!strcmp (*argv
, "read"))
1026 return ed
->read (argc
, argv
);
1029 if (!strcmp (*argv
, "set"))
1030 return ed
->setval (argc
, argv
);
1033 if (!strcmp (*argv
, "test"))
1034 return ed
->test (argc
, argv
);
1035 else if (!strcmp (*argv
, "type"))
1036 return ed
->typeinfo (argc
, argv
);
1037 else if (!strcmp (*argv
, "types"))
1038 return ed
->typesinfo (argc
, argv
);
1041 if (!strcmp (*argv
, "unset"))
1042 return ed
->unsetval (argc
, argv
);
1045 if (!strcmp (*argv
, "write"))
1046 return ed
->write (argc
, argv
);
1049 sprintf (interp
->result
, "bad command option %s: should be close, create, export, finfo, get, import, info, modules, open, read, set, type, types, unset or write", *argv
);
1054 //\[banner "check for proper initialization & finalization"]------------------------------------------------------------------------
1067 check::check (int v
)
1077 return i
!= CK
|| j
!= ~CK
;
1082 //\[banner "initialization & finalization"]-----------------------------------------------------------------------------------------
1083 void Snacc_Exit (ClientData data
)
1085 delete (SnaccTcl
*)data
;
1088 // prohibit function name mangling to enable tkAppInit.c:Tcl_AppInit() to call this function:
1089 extern "C" int Snacc_Init (Tcl_Interp
*interp
)
1093 static const char emsg
[] = "linkage error, constructors of static variables didn't get called!\n";
1094 write (2, emsg
, sizeof emsg
);
1098 SnaccTcl
*data
= new SnaccTcl (interp
);
1099 Tcl_CreateCommand (interp
, "snacc", Snacc_Cmd
, (ClientData
)data
, Snacc_Exit
);