Run common TCL script on Windows and Linux - tcl

I am new to TCL. How can I run a common tcl script across Windows and Linux? I'd like to check platform type first and then call appropriate tcl proc.

Yup that worked, Jackson. Basically, I wanted to know what OS my script is running on, for example,
set OS [lindex $tcl_platform(os) 0]
if { $OS == "Windows" } {
perform this ...
} else {
perform that ...
}

You can start by looking at the tcl_platform array. On my (windows) machine this reports the following:
% parray tcl_platform
tcl_platform(byteOrder) = littleEndian
tcl_platform(machine) = intel
tcl_platform(os) = Windows NT
tcl_platform(osVersion) = 5.1
tcl_platform(platform) = windows
tcl_platform(threaded) = 1
tcl_platform(tip,268) = 1
tcl_platform(tip,280) = 1
tcl_platform(user) = username
tcl_platform(wordSize) = 4
On a Unix system the os and osVersion will be the values reported by uname -s and uname -r respectivley. If you need something more sophisticated then the platform package may be the way to go!

Most things in Tcl work the same on Windows and Unix; the vast majority of details where there differences are hidden. To handle the rest:
Use file join instead of concatenating with / in between.
Use file nativename to make filenames to hand off to subprocesses.
Be careful with load; what it does is not at all portable.
The info command has some useful things, such as the name of the Tcl interpreter (info nameofexecutable) so you can start up interpreters in subprocesses portably and easily.
Some things just aren't portable (e.g., access to the Windows registry).
There are some subtle differences too, but you'll have to guide us with what you're doing with your program so that we can know what bits matter (e.g., Windows locks executables when they're running while Unix doesn't; sometimes that changes things).

Related

How to get job and telescope command on chrome's V8 x64.release version? (No symbol "_v8_internal_Print_Object" in current context)

I'm trying to get chrome's V8 (d8) x64.release version to use the V8 support tools in GDB, specifically for the job and telescope commands (predominantly the former).
My x64.debug version has this implemented and works, but even after building the x64.release version in a similar manner I still cannot get these commands to work in the x64.release version. The output is always as:
gef➤ job 0xd98082f7b51
No symbol "_v8_internal_Print_Object" in current context.
I have set args.gn before, and after building via ninja -C to include v8_enable_object_print = true in my args.gn:
is_debug = false
target_cpu = "x64"
use_goma = false
v8_enable_object_print = true
v8_enable_disassembler = true
I also have my ~/.gdbinit containing:
source ~/Desktop/tools/v8/tools/gdbinit
source ~/Desktop/tools/v8/tools/gdb-v8-support.py
See: https://chromium.googlesource.com/v8/v8/+/refs/heads/main/tools/gdbinit (for the support tool I'm trying to build V8 with).
How can I get my /v8/out.gn/x64.release/d8 to run with compatibility of the job command?
Am I missing something here? If so your help would be very helpful.
EDIT Alternatively how can I disable all x64.debug V8 DCHECKS?
Thanks all, appreciate your time here.
How can I get my /v8/out.gn/x64.release/d8 to run with compatibility of the job command?
I'm not sure. Try adding symbol_level = 1 (or even symbol_level = 2) to your args.gn. That definitely helps with stack traces, and might also be the thing that lets GDB find the _v8_internal_Print_Object function by name.
Alternatively how can I disable all x64.debug V8 DCHECKS?
There is no flag to disable them, but you can edit the source to make them do nothing. See src/base/logging.h.

STM32 StdPeriph library USART example

I downloaded Stdperiph library and i want to make USART example run on STM32F4 - Discovery. I chose STM32F40_41xxx workplace, added stm32f324x7i.c file and compiled without any errors.
Issue is that I cant receive expected message in my terminal (using Hercules), also when I check RxBuffer it is receiving some bytes but not that I sent.
I checked baudrate, wordlength, parity several times. Do you have any idea what could I do wrong?
USART conf:
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_2;
USART_InitStructure.USART_Parity = USART_Parity_Odd;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
STM_EVAL_COMInit(COM1, &USART_InitStructure);
Thank you.
First of all if you want to use hihg level abstraction libraries stop using obsolete SPL and start using HAL. Install the Cube. Generate the code - import into your favorite IDE and compile. Should work.
Your code does not show anything as USART clock may be net enabled as well as GPIOs. GPIOs may be configured wrong way. You system and peripheral clock may have wrong frequency. There are many more potential problems.

How can I monitor my Chrome App's process in Windows

I am trying to use an external process monitoring tool to alert me when my Chrome App dies. Unfortunately, all Chrome Apps seem to run inside their own chrome.exe process so there's no way to differentiate them in the monitoring tool. Is there any way to see which Chrome App is running in which process?
While this certainly is a manual solution (i.e. you won't be able to easily feed it into other tools), Chrome's built-in Task Manager (accessible via menu or Shift+Esc) allows you to correlate task (in this case, the App) to the system Process ID.
Whether it's possible from "outside" or using a command line call is still an open question.
One thing that can help distinguishing the process is that app processes always launch with --extension-process command line switch. But that doesn't allow you to tell which app (or extension) it is.
It's possible that if verbose enough logging is enabled, one would be able to parse the proccess ID from the logs.
I was finally able to do this using tasklist and looking for the window title which is set from the app name in manifest.json:
tasklist /FI "WINDOWTITLE eq MyChromeAppName" | find "chrome.exe"
For the purposes of the monitor, I wrapped it in a node.js function that the monitor app could use:
function chromeAppIsRunning(appName, cb){
var cmd = 'tasklist /FI "WINDOWTITLE eq ' + appName + '" | find "chrome.exe"';
childprocess.exec(cmd, function(err, stdout, stderr) {
stdout = (stdout || '').toLowerCase();
cb(stdout.indexOf('chrome.exe') > -1);
});
};
Then you can use it like this:
chromeAppIsRunning('MyApp', function(exists){
console.log('MyApp is running:', exists);
});
Hope that helps someone else

Wrapping program with TclApp causes smtp package to stop working properly?

So I'm getting a strange issue when trying to send an email from my company's local mail server using Tcl. The problem is I've written code that works, but it doesn't work as soon as I wrap it with TclApp. I believe I've included all the necessary packages.
Code:
package require smtp;
package require mime;
package require tls;
set body "Hello World, I am sending an email! Hear me roar.";
#mime info
set token [mime::initialize -canonical text/plain -string $body];
#mail options
set opts {};
#MAIL SERVER + PORT
lappend opts -servers "my_server";
lappend opts -ports 25;
tls::init -tls1 1;
lappend opts -username "someEmail#example.com";
lappend opts -password "somePasswordExample";
#SUBJECT + FROM + TO
lappend opts -header [list "Subject" "This is a test e-mail, beware!!"];
lappend opts -header [list "From" "theFromEmail#example.com"];
lappend opts -header [list "To" "theToEmail#yahoo.com"];
if {[catch {
smtp::sendmessage $token \
{*}$opts \
-queue false \
-atleastone false \
-usetls false \
-debug 1;
mime::finalize $token;
} msg]} {
set out [open "error_log.txt" w];
puts $out $msg;
close $out;
}
puts "Hit enter to continue...";
gets stdin;
exit;
This works when I run it and I successfully get the email sent.
But when I wrap it, it doesn't. Here's the output after wrapping and executing the program:
For whatever reason, wrapping with TclApp makes my program fail to authenticate.
*Update: I've decided to try to wrap the script with Freewrap to see if I get the same problem and amazingly I do not. Script works if not wrapped or if wrapped by Freewrap, but not TclApp; is this a bug in TclApp or am I simply missing something obvious?
It seems that this is an old problem (last post): https://community.activestate.com/forum/wrapping-package-tls151
Investigate whether the wrapped version has the same .dll
dependencies as in the article you linked.
Check in the TCL Wiki to see whether this is a known issue ( TCL
Wiki ).
Are you initializing your environment properly when wrapped ( TCL
App Initialization )?
I've found the solution to my problem and solved it! Hopefully this answer will help anyone else who ran into the same issue.
I contacted ActiveState and they were able to point me in the right direction - this link to a thread on the ActiveState forums goes over a similar issue.
I've decided to run the prefix file I've been using to wrap my programs in TclApp - I am using base-tk8.6-thread-win32-ix86. Running this opens up a console/Tcl interpreter which allowed me to try sourcing my Tcl e-mail script manually and I found that the prefix file/interpreter by itself was completely unaware of the location of any package on my system and that I needed to lappend to the auto_path the location of the packages I wanted. Moreover I found from the thread that the email script I was using required other dependencies I had not wrapped in. Namely sha1, SASL, and otp among their own dependencies. When I got these dependencies my script worked through the base-tk8.6-thread-win32-ix86 interpreter and subsequantly through my wrapped program.
Another clue that these dependencies were necessary after doing some research was that my script would give me a 530: 5.5.1 Authentication Required. I later learned SASL fixed this - but I don't know anything about networking so I wouldn't have guessed it.
The other thing I learned was there is a distinct difference between teacup get and teacup install which is why I wasn't installing Tcl packages correctly and TclApp was unaware of SASL, sha1, or otp.
What I don't understand, and perhaps someone with more in depth knowledge about these programs can tell me, how does Wish86 know about a script's package dependencies and know where to find them?? It wasn't until I tried looking for the packages in TclApp that I realized I didn't even have sha1, SASL, etc. on my system nor did I included their package require commands at the top of my script, yet Wish86 could execute my script perfectly. The frustrating thing about this is it is difficult to know whether or not you've met all dependency requirements for systems that don't have a magical Wish86 interpreter that just makes everything work (lol.)
After looking through the end of the thread, I found there is a discussion on the depth TclApp goes to look for hard and soft dependencies in projects.
EDIT: Added more information.

Adobe Air communication with cmd

Is there a way to communicate with cmd (using native process) in adobe air.
As an example;
How to send "ping www.google.com" to cmd and capture the return values in Air.
Edit
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Program Files\Adobe\Adobe Flash Builder 4.5>ping www.google.com
Pinging www.l.google.com [209.85.175.103] with 32 bytes of data:
Reply from 209.85.175.103: bytes=32 time=1733ms TTL=50
Reply from 209.85.175.103: bytes=32 time=189ms TTL=50
Reply from 209.85.175.103: bytes=32 time=188ms TTL=50
Reply from 209.85.175.103: bytes=32 time=186ms TTL=50
Ping statistics for 209.85.175.103:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 186ms, Maximum = 1733ms, Average = 574ms
C:\Program Files\Adobe\Adobe Flash Builder 4.5>
I can print above from Air application. I need to know is there a specific way to grab the values of Minimum = ?, Maximum = ? and Average = ?
Planning to explode the string. Is there another way. Please help me
Thanks in advance.
You should read up on Interacting with Native Processes in AIR. What you write in the command prompt (ping in your case) is another exe file located in a folder specified in the Windows Path. So you'll actually have to invoke the ping.exe with the NativeProcess class in AIR. OR, you could study how the exe works and then implement that logic in your AIR application.
EDIT
After you have edited your question, here are more details:
You use Regular Expressions (follow that link and learn about regular expressions)
Since you want to match this pattern
Minimum = (number)ms, Maximum = (number)ms, Average = (number)ms
your regular expression will look something like
var r:RegExp=/Minimum = ([\d\.]+)ms\, Maximum = ([\d\.]+)ms\, Average = ([\d\.]+)ms/i;
//Then, you execute this on your result string
var arr:Array=r.exec(result);
//Then check if the result matched your regex
if(arr != null) {
var min:int=arr[1];
var max:int=arr[2];
var avg:int=arr[3];
} else {
trace("invalid result from ping");
}
To execute shell command (e.g. ping,) you either need to run cmd.exe from it's location or run ping.exe. I found no direct way to execute shell commands in AIR, and execution of bat files is prohibited too. So, to call cmd.exe you need to know where it is. It's location given by environment variable %ComSpec% (I'm assuming we're talking about Windows,) but you can't get this value from AIR application too.
So, when I solved such a problem, I just bundled cmd.exe with my native AIR app. Not the best solution, because cmd.exe is taken on another OS. You can solve your problem this way:
create native helper exe which executes 'echo %ComSpec%' and exits. You can use system() command to do that, see WinApi docs.
in AIR app, run this helper and read console output.
invoke cmd.exe using this path (you can specify /C argument for single commands.)
Or, if you prefer, create native exe which gets arguments from AIR app and executes them on the shell with system(). AIR app can then read console output from this exe. Less job for ActionScript, more for C++ (or whatever you use for native helper.)
Update:
If you already got ping output, just parse it with RegExp's, like
"Reply from \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}: bytes=32 time=(\d{1,})ms TTL=\d{1,}". Convert captured time string to int, then calculate min/max/averages.