EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: RE: RE: SteamDevice 2.8.x build on Windows issue
From: Mark Rivers via Tech-talk <tech-talk at aps.anl.gov>
To: 'Ralph Lange' <ralph.lange at gmx.de>
Cc: "tech-talk at aps.anl.gov" <tech-talk at aps.anl.gov>
Date: Tue, 21 Jul 2020 17:43:55 +0000

Hi Ralph,

 

Ø  Doesn't Windows use ';' (semicolon) to separate elements in path variables?

Ø  I would have difficulties parsing this. How does StreamDevice do that?

 

I was wondering that myself.  Here is the relevant part of the code in StreamProtocol.cc:

 

#ifdef windows

    const char pathseparator = ';';

    const char dirseparator = '\\';

#else

    const char pathseparator = ':';

    const char dirseparator = '/';

#endif

 

Note that the code is checking if “windows” is defined.  That seems unusual.  According to the MSVC documentation that is not something their compiler defines:

https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=vs-2019

 

The next question is whether “windows” is defined on the compiler command line.  This is the output when I build. I added line breaks for clarity, and omitted a bunch of the –I directories.

 

cl -EHsc -GR              

-nologo -FC

-D__STDC__=0

-D_CRT_SECURE_NO_DEPRECATE

-D_CRT_NONSTDC_NO_DEPRECATE 

-DUSE_TYPED_RSET -DSTREAM_INTERNAL  

-Ox -Oy-  

-W3 -w44355 -w44344 -w44251    

-D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING   

-MT  -TP 

-I. -I../O.Common -I. -I. -I.. -I../../../include/compiler/msvc

-I../../../include/os/WIN32 -I../../../include  

-IJ:/epics/devel/include -IH:/epics-devel/base-7.0.4/include/compiler/msvc

-IH:/epics-devel/base-7.0.4/include/os/WIN32 -IH:/epics-devel/base-7.0.4/include  

-IJ:/epics/devel/alive-1-1-1/include   -IJ:/epics/devel/allenBradley-2-3/include      

-IJ:/epics/devel/tpmac-3-11dls5/include  

-IJ:/epics/devel/vac-1-9/include  

-IJ:/epics/devel/vme-2-9-2/include  

-IJ:/epics/devel/xspress3-2-2/include                

-c ../StreamProtocol.cc

 

I don’t see “windows” being defined there.

 

I set the iocsh variable streamDebug to 1 and started the IOC.  StreamProtocol will print the full path to the protocol file when it tries to open it in each of the directories in STREAM_PROTOCOL_PATH until it succeeds.  If it cannot find the file it will print an error message.  This is what I see:

 

2020/07/21 11:44:36.989409 win4b28 j:\epics\devel\stream-2-8-14\src\streamprotocol.cc:187: StreamProtocolParser::readFile: try 'J/LQExcel.proto'

2020/07/21 11:44:36.996306 win4b28 j:\epics\devel\stream-2-8-14\src\streamprotocol.cc:187: StreamProtocolParser::readFile: try '/epics/devel/ip-2-20-1/db/LQExcel.proto'

2020/07/21 11:44:37.005726 win4b28 j:\epics\devel\stream-2-8-14\src\streamprotocol.cc:187: StreamProtocolParser::readFile: try 'J/LQExcel.proto'

2020/07/21 11:44:37.014293 win4b28 j:\epics\devel\stream-2-8-14\src\streamprotocol.cc:187: StreamProtocolParser::readFile: try '/epics/devel/CARS/db/LQExcel.proto'

2020/07/21 11:44:37.024689 win4b28 j:\epics\devel\stream-2-8-14\src\streamprotocol.cc:573: StreamProtocolParser::readToken: Special ' '

2020/07/21 11:44:37.029678 win4b28 j:\epics\devel\stream-2-8-14\src\streamprotocol.cc:265: StreamProtocolParser::parseProtocol: token=' '

2020/07/21 11:44:37.039544 win4b28 j:\epics\devel\stream-2-8-14\src\streamprotocol.cc:579: StreamProtocolParser::readToken: word

2020/07/21 11:44:37.044808 win4b28 j:\epics\devel\stream-2-8-14\src\streamprotocol.cc:590: StreamProtocolParser::readToken: word='on' c=' '

2020/07/21 11:44:37.050567 win4b28 j:\epics\devel\stream-2-8-14\src\streamprotocol.cc:265: StreamProtocolParser::parseProtocol: token='on<00><08><00><00><00>'

2020/07/21 11:44:37.058528 win4b28 j:\epics\devel\stream-2-8-14\src\streamprotocol.cc:763: new Protocol(name="on", line=8)

2020/07/21 11:44:37.063879 win4b28 j:\epics\devel\stream-2-8-14\src\streamprotocol.cc:778: StreamProtocolParser::Protocol::Protocol $0="on"

2020/07/21 11:44:37.069036 win4b28 j:\epics\devel\stream-2-8-14\src\streamprotocol.cc:573: StreamProtocolParser::readToken: Special ' '

 

It is stripping out the : characters, and using / as the directory separator. So “windows” is clearly not defined and it is using the wrong pathseparator and dirseparator.

 

But the bizarre thing is that somehow it works!  It is finding LQExcel.proto using this path '/epics/devel/CARS/db/LQExcel.proto’.  That looks very weird, but I just figured out what is happening.  Windows is interpreting that path as an absolute path on the current drive, J:.  Indeed J:/epics/devel/CARS/db/LQExcel.proto is the correct path.

 

So the answer as to why it works is 2 errors that cancelled, and 1 coincidence!

 

-          Error #1: StreamDevice is testing the macro “windows” which is not defined so it is using the wrong pathseparator and dirseparator.

-          Error #2: I was using ‘;’ rather than ‘;’ as the path separator.

-          Coincidence: The protocol file happened to be on the current default Windows drive, J:.

 

I then changed StreamProtocol.cc as follows:

 

corvette:~/devel/stream/src>git diff .

diff --git a/src/StreamProtocol.cc b/src/StreamProtocol.cc

index 77741b9..a60b6b0 100644

--- a/src/StreamProtocol.cc

+++ b/src/StreamProtocol.cc

@@ -157,7 +157,7 @@ StreamProtocolParser* StreamProtocolParser::

readFile(const char* filename)

{

     FILE* file;

-#ifdef windows

+#ifdef _WIN32

     const char pathseparator = ';';

     const char dirseparator = '\\';

#else

 

Now when I start the IOC still using ‘:’ as the path separator it fails as it should:

 

epicsEnvSet(STREAM_PROTOCOL_PATH, J:/epics/devel/ip-2-20-1/db:J:/epics/devel/CARS/db)

 

2020/07/21 12:34:02.309651 win1fe4 j:\epics\devel\stream\src\streamprotocol.cc:187: StreamProtocolParser::readFile: try 'J:/epics/devel/ip-2-20-1/db:J:/epics/devel/CARS/db\LQExcel.proto'

2020/07/21 12:34:02.322569 win1fe4 Can't find readable file 'LQExcel.proto' in 'J:/epics/devel/ip-2-20-1/db:J:/epics/devel/CARS/db'

2020/07/21 12:34:02.329335 win1fe4 while reading protocol 'PowerOut' for '13LQE1:L1PowerOut'

2020/07/21 12:34:02.332623 win1fe4 13LQE1:L1PowerOut: Protocol parse error

2020/07/21 12:34:02.338519 win1fe4 13LQE1:L1PowerOut: Record initialization failed

 

I then changed the path separator to ‘;’ and now it works correctly:

 

epicsEnvSet(STREAM_PROTOCOL_PATH, J:/epics/devel/ip-2-20-1/db;J:/epics/devel/CARS/db)

2020/07/21 12:37:38.633552 win3804 j:\epics\devel\stream\src\streamprotocol.cc:187: StreamProtocolParser::readFile: try 'J:/epics/devel/ip-2-20-1/db\LQExcel.proto'

2020/07/21 12:37:38.643656 win3804 j:\epics\devel\stream\src\streamprotocol.cc:187: StreamProtocolParser::readFile: try 'J:/epics/devel/CARS/db\LQExcel.proto'

2020/07/21 12:37:38.668548 win3804 j:\epics\devel\stream\src\streamprotocol.cc:573: StreamProtocolParser::readToken: Special ' '

2020/07/21 12:37:38.675654 win3804 j:\epics\devel\stream\src\streamprotocol.cc:265: StreamProtocolParser::parseProtocol: token=' '

2020/07/21 12:37:38.683407 win3804 j:\epics\devel\stream\src\streamprotocol.cc:579: StreamProtocolParser::readToken: word

2020/07/21 12:37:38.688735 win3804 j:\epics\devel\stream\src\streamprotocol.cc:590: StreamProtocolParser::readToken: word='on' c=' '

2020/07/21 12:37:38.696055 win3804 j:\epics\devel\stream\src\streamprotocol.cc:265: StreamProtocolParser::parseProtocol: token='on<00><08><00><00><00>'

2020/07/21 12:37:38.706280 win3804 j:\epics\devel\stream\src\streamprotocol.cc:763: new Protocol(name="on", line=8)

2020/07/21 12:37:38.713675 win3804 j:\epics\devel\stream\src\streamprotocol.cc:778: StreamProtocolParser::Protocol::Protocol $0="on"

 

Mark

 

 

From: Tech-talk <tech-talk-bounces at aps.anl.gov> On Behalf Of Ralph Lange via Tech-talk
Sent: Tuesday, July 21, 2020 10:50 AM
To: EPICS Tech Talk <tech-talk at aps.anl.gov>
Subject: Re: RE: SteamDevice 2.8.x build on Windows issue

 

On Tue, 21 Jul 2020 at 15:01, Mark Rivers via Tech-talk <tech-talk at aps.anl.gov> wrote:

[...] 

epicsEnvSet(STREAM_PROTOCOL_PATH, J:/epics/devel/ip-2-20-1/db:J:/epics/devel/CARS/db)

 

Doesn't Windows use ';' (semicolon) to separate elements in path variables?

I would have difficulties parsing this. How does StreamDevice do that?

 

Cheers,
~Ralph

 


Replies:
Re: SteamDevice 2.8.x build on Windows issue Johnson, Andrew N. via Tech-talk
References:
SteamDevice 2.8.x build on Windows issue 吴煊 via Tech-talk
RE: SteamDevice 2.8.x build on Windows issue Mark Rivers via Tech-talk
RE: SteamDevice 2.8.x build on Windows issue Freddie Akeroyd - UKRI STFC via Tech-talk
Re: RE: SteamDevice 2.8.x build on Windows issue 吴煊 via Tech-talk
RE: RE: SteamDevice 2.8.x build on Windows issue Mark Rivers via Tech-talk
Re: RE: SteamDevice 2.8.x build on Windows issue Ralph Lange via Tech-talk

Navigate by Date:
Prev: Re: RE: SteamDevice 2.8.x build on Windows issue Ralph Lange via Tech-talk
Next: Re: SteamDevice 2.8.x build on Windows issue Johnson, Andrew N. via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024 
Navigate by Thread:
Prev: Re: RE: SteamDevice 2.8.x build on Windows issue Ralph Lange via Tech-talk
Next: Re: SteamDevice 2.8.x build on Windows issue Johnson, Andrew N. via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024 
ANJ, 21 Jul 2020 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·