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 <2020> 2021 2022 2023 2024 2025 | 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 <2020> 2021 2022 2023 2024 2025 |
<== 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 On Tue, 21 Jul 2020 at 15:01, Mark Rivers via Tech-talk <tech-talk at aps.anl.gov> wrote:
Doesn't Windows use ';' (semicolon) to separate elements in path variables? I would have difficulties parsing this. How does StreamDevice do that? Cheers, |