How to get command line arguments for a running process - apache-flex

In my program, I have been receiving an error when I use a
command-line compile command for mxmlc. The error is related to an
embedded font name not being correctly identified by flex in the
system fonts list.
However, on a whim, I decided to copy the code to Flex Builder and
compile it there. To my surprise, it worked, and it found the proper
font using the same system name I had given (PMingLiU).
I suspected my problem may be a locale one, and that my system cannot
correctly identify the font name because of locale considerations.
I've tried setting the locale of the compile code to en_US, to no
avail. So I would like to ask if anyone here knows how exactly Flex Builder invokes the MXML compiler and what differences there are compared to running mxmlc directly? We know it's not using the mxmlc.exe directly, since we tried replacing mxmlc with our own executable to capture the command line parameters.
If it matters, the OS used is Windows XP.

Although I don't have the exact answer to your question (what command line arguments Flex Builder passes to mxmlc.exe), I do have a meta-answer for you. You can find the command line by using one of two methods.
The first is platform-agnostic but will require you to compile a small C++ program. I've used this approach before when solving similar problems. What you can do is create a wrapper application which simply outputs the command line to a file. Build this application and drop it in as a temporary replacement for your mxmlc.exe, and when Flex Builder executes it you'll be able to access the resulting file "cmdline.txt" to get the full command line that it was called with:
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char* argv[])
{
ofstream cmdLine;
cmdLine.open("cmdline.txt");
for (int i = 0; i < argc; i++) {
cmdLine << argv[i];
if (i < argc)
cmdLine << " ";
}
cmdLine.close();
return 0;
}
If you don't feel right about playing this dirty trick on Flex Builder, there is an alternative assuming you're running on Windows. You can use WMI to iterate over all of the running processes and grab their command line information. Ruby being my language of choice, this would require you to install the Ruby interpreter for Windows which you can do easily with the One-Click Ruby Installer for Windows.
After installing, just run this script as soon as Flex Builder kicks off your build:
require 'win32ole'
wmi = WIN32OLE.connect("winmgmts://")
processes = wmi.ExecQuery("select * from win32_process")
for process in processes do
cmdLine = process.CommandLine
puts "Command line: #{cmdLine}" if cmdLine =~ /mxmlc/
end
I've added in a regular expression to print out the command line only for processes which were started with "mxmlc" in the command line (which should work for your needs). For a more general solution of iterating over each process, just remove the if clause at the end of the line containing:
puts "Command line: #{cmdLine}" if cmdLine =~ /mxmlc/
This will save you the headache of doing any low-level magic with StartRemoteThread and navigating through the PEB structures.
That's about the best I could do considering the nature of your question and without more information regarding your development OS. If this solves your problem I might suggest that you edit your post so that people facing similar issues can find this solution. A title like "How to get command line arguments for a running process" might be more apt.

Related

command line compiling generates bigger file than the online version

I am testing google closure compiler on command line.
I took the latest version :
java -jar closure-compiler.jar --version
Closure Compiler (http://github.com/google/closure-compiler)
Version: v20190618
Built on: 2019-06-21 17:24
I am generating a compressed version of my javascript like this :
java -jar closure-compiler.jar my_script.js > out.js
The problem is that the generated code is bigger than the one I get when I use the online service at https://closure-compiler.appspot.com/home
I noticed that the command line version added, at the beginning, the following code :
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.findInternal=function(a,c,b){a instanceof String&&(a=String(a));for(var d=a.length,e=0;e<d;e++){var f=a[e];if(c.call(b,f,e,a))return{i:e,v:f}}return{i:-1,v:void 0}};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;
$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(a,c,b){a!=Array.prototype&&a!=Object.prototype&&(a[c]=b.value)};$jscomp.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global&&null!=global?global:a};$jscomp.global=$jscomp.getGlobal(this);
$jscomp.polyfill=function(a,c,b,d){if(c){b=$jscomp.global;a=a.split(".");for(d=0;d<a.length-1;d++){var e=a[d];e in b||(b[e]={});b=b[e]}a=a[a.length-1];d=b[a];c=c(d);c!=d&&null!=c&&$jscomp.defineProperty(b,a,{configurable:!0,writable:!0,value:c})}};$jscomp.polyfill("Array.prototype.find",function(a){return a?a:function(a,b){return $jscomp.findInternal(this,a,b).v}},"es6","es3");
I do not have such a code in my script: Where does it come from ?
how can I produce the same output as the online version ?
To get the compiler command line work as the web service, I just added an option :
--language_out=ECMASCRIPT_2015
This is likely a discrepancy between the settings on the web service and the ones you're using locally.
Have a look at a Closure Compiler: Flags and Options to see what settings you might prefer.
If you'd share your source, it'd be possible to try and help you narrow down the options.
As for the extra code, I believe it is at least partially a polyfill for Array.prototype.find (aka [].find), which I assume is in your code?
If so, that's Closure injecting code to improve your cross browser compatibility.

qDebug()<<qstring no longer compiling

I have built a QWidgets application in Qt 5.3.1 and in some places have used
qDebug() << msg;
where msg is a QString.
I had had this compiling and running for a few years, but tonight I decided to recompile it and I got the message:
D:\devt\myapp\extcoder.cpp:29: error: no matching function for call to 'QMessageLogger::debug()'
qDebug()<<msg;
^
In fact I got a similar problem in another app I wrote the other day, and by experimenting I thought I had fixed it by replacing such calls by qDebug(msg).
But it looks as if some kind of software rot is setting in!
Any ideas? Of course the file starts with
#include <QDebug>
To test this problem I built a barebones QWidgets application (of a QMainWindow kind), and the only code I wrote, was (apart from the #include)
qDebug()<<"Hello world";
in the MainWindow constructor. I get exactly the same compilation error.
Reinstallation of Qt made qDebug()<<s work again.
It was indeed a kind of "software rot": I reinstalled qt 5.3.1 after making a copy of the original so I could compare the new with the old.
Using Winmerge I was able to uncover the error:
I dont know exactly how it happened but the file qlogging.h got corrupted.
Here's what happened: at lines 118 and 120 the declarations of two versions of debug got rewritten to NBIS_debug.
Now I have worked trying to port free software from the NBIS. At some stage I must have renamed a debug function from debug to NBIS_debug, and this modification must have been propagated all the way to qlogging.h.
QDebug &QDebug::operator<<(const QString &s) is supported in Qt.
Output example:
QString s;
s = "a";
qDebug().noquote() << s; // prints: a
qDebug() << s; // prints: "a"
Your Qt environment must be broken. Please, check your environment and re-install Qt if needed.
I had to reinstall Ubuntu and Qt. The reinstall only Qt did not help.

Resetting Arduino via code

I have looked at a dozen different ways to reset my arduino, from connecting pins to the reset pin and jury rigging weird bits of code.
None of them work.
The one bit of code that everybody seems to be using is
void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
{
asm volatile (" jmp 0");
}
To which my arduino responds with
C:\Users\Leonardo\AppData\Local\Temp\ccGUYdTQ.s:2259: Error: bad
instruction `jmp 0'
And it then fails uploading the code. I don't know what to do. My full code can be found here http://pastebin.com/CA2Ms2hB but it's huge and I'm not sure if it will be of help.
If anyone could help me understand why software_Reset(); I would really appreciate it, I'm at the end of my rope here.
(also if you have other methods to reset arduino I'll gladly try them)
On ARM based microcontrollers you can call NVIC_SystemReset().
All ARM based microcontrollers are required to implement that.
This is useful because resetFunc() at address 0 may not work on newer ARM based microcontrollers.
I think you are trying to write assembly code in your arduino code editor.
Let me tell you one thing. Arduino code editor does not support assembly language code by default. You can write assembly language code in arduino code editor by going through the process mentioned below:
Caution: We will be modifying the arduino source code to do that.
Get the source code for Arduino IDE: https://github.com/arduino/arduino
Extract the downloaded zip file, you will get a folder named Arduino-master
Open the Sketch.java file in a text editor of your choice. The location of sketch.java is : Arduino-master/app/src/processing/app/Sketch.java
Insert the .s capability:
a. Search for: sc.isExtension("c");
you will see something like this:
//3. then loop over the code[] and save each .java file
for (SketchCode sc : code){
if(sc.isExtension("c") || sc.isExtension("cpp") || sc.isExtension("h")){
//no pre-processing services necessary for java files
b. Add sc.isExtension("s") at the end of the if condition. Now your code should look like below:
//3. then loop over the code[] and save each .java file
for (SketchCode sc : code){
if(sc.isExtension("c") || sc.isExtension("cpp") || sc.isExtension("h") || sc.isExtension("s")){
//no pre-processing services necessary for java files
Search for: String[] getExtensions()
You will see some code like this:
/**
* Returns a String[] array of proper extensions.
*/
public String[] getExtensions() {
return new String[] { "ino", "pde", "c", "cpp", "h" };
}
Insert "s" in the returned Array. So, now your code should look like this:
/**
* Returns a String[] array of proper extensions.
*/
public String[] getExtensions() {
return new String[] { "ino", "pde", "c", "cpp", "h", "s" };
}
Save Sketch.java
Open Compiler.java in text editor of your choice. The location of Compiler.java is: Arduino-master/app/src/processing/app/debug/Compiler.java
Search for: compileFiles(
In the command findFilesInFolder(), replace the capital S with a lowercase s.
Repeat step 8 : 3 times more... (4 tiems in total)
Save the Compiler.java file
Download the latest version of java SE 8u111 from http://www.oracle.com
Download and install any java command line tool. But I would recommend Apache ANT.
If you are a windows user:
You can download it here: http://ant.apache.org/
More help on download and install on windows: https://www.mkyong.com/ant/how-to-install-apache-ant-on-windows/
If you are a Mac user:
You need to install it using Homwbrew:
To install Homebrew:
ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
And then to install Apache ANT:
brew install ant
In Command line go to the directory for Arduino-master/build
Build the Arduino IDE using : ant build, which should end with Build Successful message.
Package the Arduino IDE using: ant dist
It will ask you to enter a version number and give a suggestion e.g.[0105]. Just enter the suggested number with dots and asm. For example: If suggestion is [0105] then enter: 1.0.5.asm
This command may take 6 - 10 minutes to finish. (depending on the speed of your computer)
Then you must get Build Successful!!!
The Arduino IDE that supports assembly language programming can be found in the newly created .zip file
Unzip the file and install the Arduino IDE application.
Now, you should be able to write assembly programs without getting errors in the Arduino IDE.
If you have any problems, Please feel free to ask.

Programming Arduino with Ada

I am am unable to get avr-elf-windows and WinAVR to work. I have managed to build the example supplied with avr-elf-windows (ATmega2560). But if I try and expand to use another chip or start using the WinAVR supplied packages and projects I keep getting errors I cannot work out.
Method 1:
Modify the ATmega2560 example to use the WinAVR packages.
Changed:
with Atmega2560; use Atmega2560;
to:
with AVR; use AVR;
with AVR.Atmega328p; use AVR.atmega328p;
Create a project file to include:
with "C:\WinAVR-20100110\lib\gnat\avr.gpr";
with "C:\WinAVR-20100110\lib\gnat\avr_app.gpr";
Running make I get the following error:
avr-gnatmake: "C:\WinAVR-20100110\lib\gnat\avr_lib\avr-int_img.adb" compilation error
Great, I have a compilation issue, but I cannot see the error.
Method 2:
Open the above project file in GPS. Change the build setting to be gnatmake. GPS now starts reporting errors and warnings:
Project warning: object directory "avr_lib/avr5/obj" not found
Project library directory "C:\WinAVR-20100110\lib\gnat\avr_lib\avr5\lib\" does not exist
The latter issue is very clearly the fact that I have not set up GPS correctly to tell it the values of microcontroller and architecture, but I cannot seem to find anything to resolve this.
Method 3:
To use the WinAVR set up directly using makefiles which then gives me the error:
avr-gnatmake: RTS path not valid: missing adainclude and adalib directories
If I follow the instructions I can find by searching the web I can only find details for building the required libraries under Linux.
Platform: Windows 7.
With the combination of the two answers above I have now managed to link my sample code. As to wether it will work on the Arduino, that is a different issue.
Many thanks for the help.
I have found it a bit frustrating to get this far, and I wonder if there are others out there who may just give up on Ada on the Arduino and go back to the Arduino IDE and therefore missing out on the opportunity to learn a language with more structure. There are many misleading pages out there that also do not help.
You might want to take a look in the paper Integrating 8-bit AVR Micro-Controllers in Ada. Basically you can use a GPS project file arduino.gpr like
project Arduino is
for Source_Dirs use (".", "src");
for Object_Dir use "obj";
for Exec_Dir use "bin";
for Main use ("main.adb");
package Compiler is
for Default_Switches ("ada") use ("-mmcu=avr5");
end Compiler;
package Ide is
for Gnat use "avr-gnat";
for Gnatlist use "avr-gnatls";
for Debugger_Command use "avr-gdb";
end Ide;
package Builder is
for Executable_Suffix use ".elf";
for Default_Switches ("ada") use ("--RTS=rts-zfp");
end Builder;
package Linker is
for Default_Switches ("ada") use ("obj\crtm328p._o", "-nostdlib", "-lgcc", "-mavr5", "-Tdata=0x00800200", "-mmcu=avr5");
end Linker;
end Arduino;
and you can code a spec for your ATmega328P like
with Interfaces; use Interfaces;
with System;
package ATmega328P is
-- PORTB: Port B Data Register
PORTB : Unsigned_8;
for PORTB'Address use System'To_Address (16#25#);
-- DDRB: Port B Data Direction Register
DDRB : Unsigned_8;
for DDRB'Address use System'To_Address (16#24#);
-- PINB: Port B Input Pins
PINB : Unsigned_8;
for PINB'Address use System'To_Address (16#23#);
end ATmega328P;
to be imported by your main file or libraries.
Bear with me if this isn't the immediate answer; I have only used the AVR-Ada toolchain on Linux, so we may have to iterate towards a solution unless someone else spots the problem first.
The first thing to decipher is which version of the AVR-Ada tools you have:
your project file USED to need (using avr-ada 1.1)
with "C:\WinAVR-20100110\lib\gnat\avr.gpr";
Now with avr-ada 1.2.1 you need (instead)
with "C:\WinAVR-20100110\lib\gnat\avr_app.gpr";
for building applications, and <same path>/avr_lib.gpr for libraries.
I don't believe you ever need both! And they may conflict with each other.
I don't know the state of the Windows binary build, but if you need the latest version (recommended : it's a real improvement) you may need to build it from source.
Method 1 : were you running Make from a command line? If so, I would expect to see errors in all their gory details.
Method 2 : can't help you here, I don't know GPS well enough. However I can say that on Linux there are no "avr5" folders in [wherever]/avr/lib/gnat/avr_lib. (AVR5 is correct for the 328p)
Instead there IS a [wherever]/avr/lib/avr5 containing libc and other C-related objects - including the crtm328p.o that Rego names in his linker switches, and a [wherever]/lib/gcc/avr/4.7.2/avr5 folder containing libgcc.a. You probably need to find the former and point GPS at it...
Method 3 : This looks the easiest to fix. The "gnatmake" command needs an --RTS= option pointing at the correct RTS for the 328p. This should be --RTS=rts/avr5 assuming the RTS is correctly installed.
Alternatively a full path ought to work. Here, that would be
--RTS=/opt/avr_472_gnat/lib/gcc/avr/4.7.2/rts/avr5
on Windows you may have to poke around to find the correct path.
Using Method 1 this --RTS option is automatically generated by avr_app.gpr.
It appears that having a mix of 3 or 4 tool chains installed that provide one of aspects of WinAvr, AvrAda causes significant problems (these included WinAvr, Avr-Ada, Cygwin, AVR compiler by Adacore and MinWG).
Starting with a brand new Win7 or Win8 installation perform the following:
Install WinAVR-20100110 to C:\WinAVR-20100110
Copy the content of the Avr-Ada-1.2.0_bin to C:\avr-ada-1.2.0
Add C:\avr-ada-1.2.0\bin to the PATH
Compiling the content of each of the examples in C:\avr-ada-1.2.0\share\doc\avr-ada\apps identifies that some DLLs are missing: libiconv-2.dll, libgmp-10.dll, libmpc-2.dll, libmpfr-1.dll
These can be found in a MinGW installtion.
Create a virtual machine to install MinGW on, in order to ensure it did not mess with the main PC.
Copy the missing DLLs in C:\WinAVR-20100110\bin
The example in DS1820 will not compile due to crc_lib being missing.
In order to upload to the Arduino the makefiles must be modified for your local installation, board type etc.

Run a program from Qt

I am working with Qt in Linux. I need to run the "evince" pdf reader from Qt.
I have been searching and as I understand I can use Qprocess to make it work. Something like this:
QStringList args;
args.append("/home/user/presentacion0.pdf");
QProcess p(this);
p.start("/usr/bin/evince", args, QIODevice::ReadWrite);
p.waitForFinished();
QString p_stdout = p.readAllStandardOutput();
QString p_stderr = p.readAllStandardError();
But I always get the following error:
No protocol specified
Cannot parse arguments: Cannot open display:
So I tried the system(char *cmd) from stdlib.h and does not work
system("/usr/bin/evince /home/user/presentacion0.pdf");
I think system() does not work because "evince" is a graphical application. However I can run "ls", "mkdir", etc. commands with system() without problems.
Please I need help with this topic.
I Really appreciate your help in advance.
Thank you.
You're running your Qt app from an application (most likely shell) that doesn't have DISPLAY environment variable set properly (it's usually :0). QProcess uses environment of the calling process.
If you're not really interested in grabbing evince's stdout and stderr, and you don't need to wait for its finish, then I would go with QProcess::startDetached().

Resources