12-09-2017, 01:05 AM | #1 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
General questions
Is it possible to restrict oscii-bot from launching it's new copies, when there's already one copy running? I prefer having it's icon hidden in the tray, so, while constantly switching oscii-bot on and off, I, sometimes, launch a new copy, while the old one is hidden in the tray and can't figure out what's wrong with my script.
"Run minimized" option and other useful options in right click menu for the icon in tray would also be great additions to the future updates. |
12-09-2017, 09:10 AM | #2 |
Human being with feelings
Join Date: Feb 2016
Posts: 189
|
One should be able to achieve this (on Windows) by using autohotkey to start OSCII-bot.
autohotkey should be able to either detect a) the pre-existing minimised OSCII-bot window or b) the OSCII-bot process and then, if detected as running, decline to start a new instance of OSCII-bot. |
12-09-2017, 09:18 AM | #3 | |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Quote:
P.S. What is your name? |
|
12-11-2017, 10:30 AM | #4 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
In .ReaperOSC file.
FX_PARAM_VALUE r/fxparam/@/value r/fx/@/fxparam/@/value r/track/@/fx/@/fxparam/@/value Using rotary encoder to change fx parameters with "r/fxparam/%d/value" command. Sending "-1" and "1" values makes parameter in Reaper jump from far left to far right, respectively. Sending something, like "-.04" and "0.564" values makes parameter in Reaper move a little bit from the center each time I rotate the encoder. It always jumps back to the center (ROTARY_CENTER is set to 0) at the start of the encoder movement. Why these Reaper does not take fractional values to move parameter gradually, depending of the value sign/encoder direction? |
12-11-2017, 10:48 AM | #5 |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,793
|
I never saw that a Rotary sends increments, but usually rotaries have an LED Ring showing the would-be value and hence the device does know (and for displaying it needs to know) the absolute value.
OTOH, AFAIK, the "standard" in OSC is to encode parameter changes as 0.0 ... 1.0 in floating point as a representation of the absolute parameter value min ... max. Obviously in your example "1" is "1.0" and results in maximum and "-1" is clamped to "0.0" and results in minimum. Wich seems rather correct to me. I suppose you need to do an "OSC-dialogue" and first fetch the current value (to be displayed on the LED Ring, if exists) and then send the value esulting from the increment. -Michael |
12-11-2017, 02:06 PM | #6 | ||||
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Quote:
Code:
r: rotary. The device triggers the action in the forward direction when sent # with an argument greater than ROTARY_CENTER, and in the reverse direction when # sent with an argument less than ROTARY_CENTER. For some messages, the magnitude # of the argument affects the rate of change. There are also this commands available in ReaperOSC, but they would only work with actions (numerical or strings, in case of SWS actions) and not with ReaperOSC commands, like "r/track/volume". Code:
ACTION_SOFT f/action/@/cc/soft ACTION_RELATIVE f/action/@/cc/relative Quote:
Quote:
Quote:
Also, It seems like Reaper doesn't send FX parameter names/values to the device for me. Both with default and some third-party ReaperOSC files. I suppose, one should send Reaper some additional command to notify it that the device is in FX control mode now. |
||||
12-11-2017, 02:18 PM | #7 |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,793
|
Interesting stuff indeed !
As I did not try to use the Reaper OSC interface (with OCSII-Bot I on the contrary communicate with Reaper via Midi and with a hardware Mixer via OSC), I can't comment on that. While 0.0....1.0 is "standard" with OSC, AFAIK, it's perfectly viable to use the protocol for any kind of values and with any way to interpret them as the sender and receiver agree upon. -Michael Last edited by mschnell; 12-31-2017 at 12:07 AM. |
12-30-2017, 09:55 PM | #8 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
multiple track selection
DEVICE_TRACK_SELECT i/device/track/select t/device/track/select/@
This command selects each track from the bank exclusively, deselecting all other already selected tracks, when the corresponding button on the device is pressed. I'm fine with it, but also want to have an ability to select multiple tracks at once from the surface with a different set of buttons. How should it be done properly? What command should I use. Tried both i/device/track/select and t/device/track/select/. Even added DEVICE_TRACK_SELECT b/device/track/select/@ line to the config file. All these options are selecting track from the bank exclusively, deselecting all other tracks in the project. |
01-02-2018, 10:26 AM | #9 |
Human being with feelings
Join Date: Feb 2016
Posts: 189
|
Multiple track selection - reply
This code will select multiple tracks in a bank
Code:
oscsend(OSC_to_REAPER, "t/track/1,2,3,4,5,6,7,8/select/toggle", 1); // select all tracks in currently selected bank (reselects tracks after mixer use) |
01-02-2018, 11:54 AM | #10 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Thanks, but I don't think that this solution would be helpful for the situation, when Track 1 (in Reaper) is already selected and one needs to also select Track 16 (in Reaper).
So, we switch to bank 2 on the device and, then, when selecting tracks "1,8", device will select tracks 9 and 16 and deselect Track 1 in Reaper. Some other option needed. It may somehow be solved by performing series of custom actions, like, 1. "Script: me2beats_Save selected tracks, slot 1.lua" 3. "oscsend(OSC_to_REAPER, "t/track/@select/toggle"); 3. "Script: me2beats_Restore selected tracks, slot 1 (add to selection).lua" but this isn't a universal solution, since custom actions doesn't have persistent action IDs in Reaper. |
01-02-2018, 12:50 PM | #11 |
Human being with feelings
Join Date: Feb 2016
Posts: 189
|
If the track selections are to be wider than a bank, then try using the native Reaper actions "Track: Select Track nn"
This post may help too if there is some Reaper display or UI change also expected on doing the track selection https://forum.cockos.com/showthread.php?t=171832 |
01-02-2018, 01:06 PM | #12 | |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Quote:
Selecting tracks by 1-99 actions isn't possible by the same reason. Let's say, I've clicked track 5 in Reaper. Then, the current bank would be tracks 5-12 for buttons 1-8 on the device. So, what action should be performed when I'd press button 3? Ideally, the device should send "select track 7 (keeping selection)". We can identify the bank position by using "last touched track" feedback from Reaper. Now, let's try to select track 3 in Reaper, while track 5 is still selected. We press "bank-" button on the device. Now, the bank includes tracks 1-8 for buttons 1-8 and "last touched track" is still 5, which would mess the selection, if we would want to use "last touched" as an anchor point for direct selection action in Reaper. The script would still think that button 3 is mapped to the track 7, while we need it to select track 3. I hope, you can follow my logic here. In short: 1. Using "last selected track" for direct selecting tracks isn't an option (there could be more than one that is already selected). 2. Device never knows what bank was selected. |
|
01-03-2018, 07:41 AM | #13 |
Human being with feelings
Join Date: Feb 2016
Posts: 189
|
The problem starts to make some sense at a detailed level but without an obvious Reaper action or an OSC related "bullet" as the solution.
Might it not help to take a step back from the details and think at an abstracted design level about the design principles and the compromise(s) in user experience and implementation associated with them? Here are some suggestions
|
01-03-2018, 10:12 AM | #14 |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,793
|
Shouldn't it query such state to get in sync ?
-Michael |
01-03-2018, 04:49 PM | #15 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
There's no way to do so. Reaper never sends that information.
|
01-04-2018, 07:52 AM | #16 |
Human being with feelings
Join Date: Feb 2016
Posts: 189
|
That answer forces the design principle then:
If Reaper does not and will not give sufficient feedback on track or bank selection via OSC on a change, or on a "refresh all control surfaces" action then the Novation and the OSC control surface will have to be in charge of, and keep a record of, the track & bank selection state. Then just add to this decision the means of bringing back to a consistent state if the human changes things at the Reaper end or the imaginary state tracking information handshake goes wrong for another technical reason. Use the DAW operating human if needs as the simplest way to manually get back or keep in sync. If it can help, then in the MIDIMIX control surface when banking, an OSC string is sent for first track number in the bank when a "bank left" or a "bank right" occurs. This track number can be detected and calculated and used in the control surface code. Last edited by goldenarpharazon; 01-04-2018 at 11:34 AM. Reason: Extra help added |
01-04-2018, 12:35 PM | #17 | |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Quote:
I've tried calculating banks on the surface side. To many flows with this decision. Not worth it. |
|
01-08-2018, 10:47 AM | #18 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Why float assignments are working properly with this code, but not the strings? What is a proper way to write string values into the memset?
All I get now is empty values: |
01-08-2018, 01:48 PM | #19 |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,793
|
I do understand that you decline to accept this, but in EEL you don't write strings in memsets. There is a dedicated "StringSet".
It is possible to write (I seem to remember) up to 5 Bytes from a string into an element of an array ("memset"). But why should you want to do that ? -Michael Last edited by mschnell; 01-08-2018 at 10:29 PM. |
01-08-2018, 02:32 PM | #20 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
I don't decline memsets (i dislike address assigning and related issues, like the current one, to be exact), but there's no other option.
The thing is that, for some reason, mem_set_values doesn't work, either. There's either no value at all, or the same value is duplicated for all variables. |
01-08-2018, 02:43 PM | #21 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Here's a simpler example.
Output upon corresponding osc incoming message: .ReaperOSC entry with 'string' type for this action: Last edited by fundorin; 01-08-2018 at 02:52 PM. |
01-08-2018, 03:02 PM | #22 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
This code prints volume values for all tracks, while it should always display "Track 1" volume as in oscSelTrackVolStr[1]:
Output: UPD. This doesn't work: I'm going slightly mad. Last edited by fundorin; 01-08-2018 at 03:07 PM. |
01-08-2018, 03:12 PM | #23 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
This is getting out of hand!
|
01-08-2018, 03:39 PM | #24 |
Administrator
Join Date: Jan 2005
Location: NYC
Posts: 15,746
|
I can't see all of your code, but I think the problem your having is because of the way strings work in EEL. Strings are a bit of a second-class citizen in EEL -- variables which reference them are actually numbers which point to the string buffer.
oscSelTrackVolStr[0] through oscSelTrackVolStr[n] need to be initialized to point to distinct strings. You could do this by setting: Code:
oscSelTrackVolStr[0] = #; oscSelTrackVolStr[1] = #; oscSelTrackVolStr[2] = #; Code:
mem_set_values(oscSelTrackVolStr, #,#,#); // or any more # as you need Which would allocate an anonymous string buffer for each, but that limit is still constant. If you want to do it purely programmatically, you could assign the pointers to the values 0..1023 which are the user strings that you can use. Code:
i = 0; loop(3, oscSelTrackVolStr[i] = i; i += 1; ); Code:
oscSelTrackVolStr = 0; ... oscparm(0,'s', oscSelTrackVolStr+trackNumber); // for track number 1, use global string index 1, track number 2 use string index 2, etc. printf("Track Number: %d Value: %s\n",trackNumber,oscSelTrackVolStr+trackNumber); P.S. if you want to debug what a string points to, you can use something like: Code:
v="some string"; printf("string: %d='%s'\n", v,v); v = #str; printf("string: %d='%s'\n", v,v); |
01-08-2018, 04:11 PM | #25 | |||
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
First of all, I would like to thank you for coming here. There's literally no one one interested in OSC or osscii-bot, except, maybe, Michael and goldenpharazon. And my related questions are almost always left unanswered.
Quote:
Quote:
Quote:
I have a question about MIDIACTION and MIDILISTACTION. What is their purpose? Is it possible to use them in relative/absolute modes? If I want to control "Adjust solo in front dim (MIDI CC/mousewheel only)" (action 987) with an encoder/pot via OSC, what command should I send to Reaper and what should be sent as an argument to this command? Related thread: https://forum.cockos.com/showthread.php?t=201649 I've made a post last year about "learn" action, which is only working, when called via midi command, hotkey or from the action list, but not when it was assigned to the osc command. Thread with demonstration: https://forum.cockos.com/showthread.php?t=200551 I'm also wondering of, how to assign encoder to the internal .ReaperOSC actions, like "n/track/volume", considering that encoder sends +1/+65 when turned CW/CCW and there's no appropriate settings in .ReaperOSC. The same is true for assigning OSC commands to actions in the action list. "CC mode" button becomes disabled, and there's no similar button for osc, where it would be possible to set control type, like relative/absolute/etc. Loosely related thread here: https://forum.cockos.com/showthread.php?t=200631 Is it possible for you to check those questions and answer in those threads or just here? Thanks in advance. |
|||
01-08-2018, 10:35 PM | #26 |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,793
|
Not true. I answered to close to all your questions, but seemingly you don't understand my wording - or decline to try to make sense of what I am saying, or I don't succeed in understanding what exactly you are asking. Obviously, regarding technology, we are talking in completely different languages. (And you did not really try to thorroughly understand / check out what the (OK: rather sparse) OSCII-Bot / EEL documentation says.)
This obvious code snipped was the first I did when checking out how strings work in EEL, at the point I needed strings for my OSCII-Bot script. -Michael, getting tired of this and wishing Justin more luck on that behalf. Last edited by mschnell; 01-08-2018 at 10:49 PM. |
01-09-2018, 01:36 AM | #27 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
The thing is that I either can't understand what you're proposing, due lack of my programming skills, or I can't properly describe my issue, to get useful answer about it. Anyway, it's all about me and not you.
-Not Michael Last edited by fundorin; 01-09-2018 at 06:11 AM. |
01-09-2018, 05:25 AM | #28 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Code:
position = 11; pos = sprintf(str_out, "\\x%02X", position); pos2 = "\x11"; printf(" pos - %s\n", pos); printf(" pos2 - %s\n", pos2); printf("strpos2 - %s\n", hex2str(pos2)); Why pos is a text string, while pos2 is hex? What should be done to store pos value as hex? P.S. I've created a thread, asking how to properly convert dec numbers into hex numbers, but then I thought that the I've solved the issue and deleted that thread. Turns out, that I still need to find a way of how to convert those numbers in EEL2. In Lua and JS it's alao possible to convert digits with tostring(10) or tostring(16). Yet, I don't understand how to make constructed string value to behave like hex value in EEL2 Last edited by fundorin; 01-09-2018 at 06:10 AM. |
01-09-2018, 06:32 AM | #29 | |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,793
|
Quote:
First you need to define what exactly you mean by "string value", and by "hex value" and by "behave like". e.g.: "string value" is a string that contains decimal digits that might be able to be interpreted as an integer number. "hex value" is a string that contains decimal digits and letters A..F that might be able to be interpreted as an integer number. "behave like" ???? -Michael |
|
01-09-2018, 06:55 AM | #30 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
// HEX string. When printed to log as string, won't show anything, until converted into string with a special function, which was written by Justin. Then, log will display "0B".
pos = "\x11"; //Regular string. When printed, will display "\x0B" in log. position = 11; pos2 = sprintf(#, "\\x%2X", position); printf("%s", pos); // [] printf("%s", pos2); // \x0B printf("%s", hex2str(pos)); // 0B So, we have two variables, pos and pos2, containing the same value - "\x0B". The thing is that pos is determined as hex and pos2 as a string. The question is, how to make pos2 value type as hex. |
01-09-2018, 08:28 AM | #31 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Still can't figure this out.
So, the task is: Construct SYSEX message with various small parts, so it wouold be possible to display data from Reaper on the LCD: constants: Code:
lcdSysexHeader = "\xF0\x00\x20\x29\x03\x03\x12\x00\x02\x00\x02"; // LCD HEADER lcdSetCursor = "\x01"; // command to position cursor lcdLTLine = "\x01"; // top line on the left LCD lcdTextStart = "\x04"; // begin text part lcdTextEnd = "\x00"; // finish text part lcdSysexEnd = "\xF7"; // LCD END Code:
strcat(lcdTrackName,sprintf(#,"%s%s%s%s%s%s%s%s",lcdSysexHeader,lcdSetCursor,position,lcdLTLine,lcdTextStart,str2hex(sysexInput),lcdTextEnd, lcdSysexEnd)); 1. str2hex(sysexInput) where sysexInput is a currently selected track's name in string format. This one is working fine. using my custom string to hex conversion function. 2. position - cursor position on the LCD. Doesn't work, for now. If position will be replaced by "\x00", for example, the cursor will be set to the first symbol position at the top line of the screen. "\x01" for the second position and so on. What I need is to substitute "\x00" here with a variable\function, that would take decimal integer number as an input and convert it to hexadecimal number string, since "\x**" type of strings are used in oscii-bot. For example, 1 bill become "\x01", 11 will be converted into "\x0B". When I'm trying to construct sysex string with pos = sprintf(#, "\\x%X", position)); or some other methods, they don't work. pos value is always a text string, while I need it to be "hex string", like those constants above. |
01-09-2018, 02:45 PM | #32 | |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,793
|
Quote:
e.g: -> we have two variables, pos and pos2 each holding the id of a string. Both these strings contain the character sequence "\x0B". That obviously is not true. Regarding your "print" commands, correct is: -> we have a variable pos that holds the number 11. we have a variable pos2 that holds the index of a string. This strings contain the character sequence "\x0B". No idea what happens to your x11 which would be 17. What exactly did you intend to do by pos = "\x11" ? There is no clear definition in the OSCII-Bot code reference, but it seems that it should create a string that contains a single character with value 17 (hence not printable) and set the variable pos to the value of the index of this string. (I did not check this right now.) -Michael Last edited by mschnell; 01-09-2018 at 10:29 PM. |
|
01-09-2018, 07:03 PM | #33 | |
Human being with feelings
Join Date: Feb 2016
Posts: 189
|
Quote:
With regard to how to compose binary strings that are suitable for sending via SYSEX the key hints needed to the two key functions for accessing binary [byte] strings i.e. str_getchar() and str_setchar() were in Justin's original release post and advice that followed shortly afterwards. See https://forum.cockos.com/showpost.ph...0&postcount=17 again. Using a suitable midi monitor is probably the best and sole debug means of seeing if the binary [byte] string has been constructed correctly and then output. If one switches between midi monitor output and what is output by printf() then the understanding and learning may be more complicated 1. because of the internal representation of strings in EEL (that Justin has tried to explain) and 2. Because of the format translation that can be done in printf() on output. The output of the (hoped for) SYSEX binary [byte] string will likely different in the midi monitor and the printf(). If one uses other string functions on binary [byte] strings without developing a good understanding of the EEL internal data representation then, as found in the posts asking for help, the results may quite likely be unpredictable or not wanted. One could use that midi monitor binary [byte] string output as a constant source of truth if one is trying to reverse engineer or visualise the internal representation of strings in EEL/OSCII-bot Do keep trying using logical problem solving steps on simple example problems. Simple example problems are easier to learn and easier to explain or present on the forum when asking for help. And well done and thanks to Michael for helping too. Good luck. |
|
01-09-2018, 07:46 PM | #34 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
I suppose that getchar/setchar isn't appropriate here, cause character "9"
would be "39" in hex", while "9" in hex" is a "horizontal tab". That's how Justin's str2hex function works, picking character by character, converting them in hex and putting into the new string. This function works fine for displaying data on the screen as characters, but not for direct numbers conversion like this: |
01-10-2018, 01:05 AM | #35 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Not true. According to the reference, hex numbers should be assigned as $x** or 0x**, without using the quotation marks.
Like var = $xBF pos = "\x11"; is a string and it's a string that is used in oscii-bot to send sysex data to the controller. The function's name itself suggests it: midisend_str And the issue is that when a string is set explicitly, it's recognized by oscii-bot as a hex number, but when it's constructed with strcat(pos, sprintf(#, "\\x%X", position)); it's, suddenly, a text string. At the very same time, this code strcat(lcdTrackName,sprintf(#,"%s%s%s%s%s%s%s%s",l cdSysexHeader,lcdSetCursor,"\x00",lcdRTLine,lcdTex tStart,str2hex(sysexInput),lcdTextEnd, lcdSysexEnd)); is also a string, but it's a proper sysex message. This is what I can't understand. Even "%s%s%s%s%s%s%s%s" in the code line above suggests that "\x01" in lcdSetCursor = "\x01"; and any other part of the message is a string and not a hex number. P.S. I feel that dec numbe should be converted into hex number and the result is put into a string. The question is, how to the conversion in EEL2. Last edited by fundorin; 01-10-2018 at 01:56 AM. |
01-10-2018, 02:11 AM | #36 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
str_getchar might be a solution. Need a bit more time for experiments.
UPD. Seems like it's not. Last edited by fundorin; 01-10-2018 at 02:59 AM. |
01-10-2018, 06:01 AM | #37 |
Human being with feelings
Join Date: Feb 2016
Posts: 189
|
Guidance on EEL strings and characters
Fundorin. Take a step back from the code that is now becoming a bit frustrating and try and think about what is happening with characters and strings and their representation within EEL and in the computer itself.
Piece this thinking together one step at time. There are a number of separate but related key topics as follows, which if understood better leads to the "answer", and when, or if any character or string "conversion" is taking, or needs to take place. The (loosely called) character might appear - As a 7 bit value in a SYSEX byte - As a series of bytes concatenated together that make a SYSEX byte stream (that could be called a "byte string") -As a character value stored in an EEL string -- How that value is stored in EEL -- What that value is intended to represent internally in EEL, or mean or become externally Note that all the string functions in OSCII-bot take place on these string values not characters. Using "Unsigned chars" in str_getchar() will be the safest way to explicitly read or write the whole 8 bits of the desired character in a string. Influencing this EEL string storage there are the OSCII-bot variables that are really designed to store a 64bit double precision real number but they are also adapted for characters and strings by pointing to a string buffer. - As a character, string, hex or octal representation in an external output stream (which could be to a GUI console, terminal, printer or file output) or at compile time when coded representations and escape characters are converted into internal storage values. These representations are what is shown in the example white tables in post #34. These are not the same as the internal representations although they are related by a chosen or inbuilt input or output conversion. To manipulate characters for SYSEX one needs to understand 7 bit ASCII characters and the difference between printable and non printable characters. There is a lot of tutorial material on the nature of characters for the C programming language but take care in that C strings are rather different to EEL strings. Hope that helps a bit and gives the correct computer/EEL terminology in which to ask more detailed or specific questions. |
01-10-2018, 06:02 AM | #38 |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,793
|
You wrote:
printf("%s", hex2str(pos)); // 0B This shows that at this point in the program the value in pos is 11 (aka 0B hex). I can't comment on how that value has been assigned to pos. -Michael |
01-10-2018, 06:19 AM | #39 | |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Quote:
Let's take a simple example (variable position has int 11 value): Code:
num1 = sprintf(#,"\\x%02X", position); num2 = sprintf(#, "%s", num1); num3 = "\x0B"; printf("position - %d\n", position); printf("num1 - %s\n", num1); printf("num2 - %s\n", num2); printf("num3 - %s\n", num3); printf("cnv3 - %s\n", hex2str(num3)); We have dec int position with value 11. Printed as double. We write position into num1 in hex format as a string, adding "\x" in front and making it two characters, minimum. Printed as a string. We write num1 into num2 in string format as a string. Printed as a string. We assign "\x0B" text string as a value to num3. Cannot be printed as a string. Why?! If we convert it into string with a function, then it can be printed as a string. How come that direct assignment makes that "\x0B" string a hex value for oscii-bot? P.S. Conversion function: Code:
function hex2str(str_in) local(str_out, pos, len) ( // Formatting HEX values to strings strcpy(str_out=#,""); len=strlen(str_in); pos=0; while (pos<len) ( strcat(str_out,sprintf(#,"%02X ",str_getchar(str_in,pos))); pos+=1; ); str_setlen(str_out,strlen(str_out)-1); // returns str_out ); |
|
01-10-2018, 07:56 AM | #40 | |
Human being with feelings
Join Date: Feb 2016
Posts: 189
|
Quote:
This is probably because rather than string, "\x0B" is turned by the compiler into a single character because \x is an escape character so the executed code will end up with the single character byte for hex 0B, which is a non printable character (a vertical tab) when printf()ed with %s or other format conversion. If one uses "\\x0B" instead, then it has an \ escape character to escape the escape character \ followed by x so probably produces the string expected. Information about escape characters in C strings explains this. It's an example of a nasty kind of bug where a single character (in this case omitted) compiles without error but has completely changed the programmer's intention. Last edited by goldenarpharazon; 01-10-2018 at 12:48 PM. Reason: Better explanation with solution |
|
Thread Tools | |
Display Modes | |
|
|