Frama-C: how to get the start line number and the location of starting character? - ocaml

Now I have PdgTypes.Node.stmt, I just can use:
Format.printf "%a"
Printer.pp_location (Cil_datatype.Stmt.loc PdgTypes.Node.stmt)
to print the result like this:
mkdir.c:500
But I want the result that like this:
mkdir.c:500:23
It means that the output should contain the location of starting character. What should I do?
Thanks in advance for your help!

A Location in Frama-C (defined in module Cil_datatype, in file src/kernel_services/ast_queries/cil_datatype.ml) is a pair of Positions (defined in the same file), the start and end position of an AST element.
A Position is very similar to an OCaml's Lexing.position. The only difference is that Lexing's position has a string field pos_fname, while Frama-C's position has a Datatype.Filepath (defined by Frama-C) field pos_fpath.
Both Location and Position have functions pretty_debug, which includes the character number. Position also has pp_with_col, which prints the column number but in format %a char %d, which is different from what you want.
In any case, these functions can serve as inspiration to the one you want.
Important note: pos_cnum stands for character offset (from the start of the file) and not column offset, so you need to subtract pos_bol, the offset of the beginning of the current line, to get the actual column number of a character: pos_cnum - pos_bol.
Here's an example of some code that should be close to what you want (you may need an open Cil_types or open Cil_datatypes for these to work):
let (pos_start, _pos_end) = Cil_datatype.Stmt.loc PdgTypes.Node.stmt in
Format.fprintf fmt "%a:%d:%d"
Datatype.Filepath.pretty pos_start.Filepath.pos_path
pos_start.Filepath.pos_lnum
(pos_start.Filepath.pos_cnum - pos_start.Filepath.pos_bol)

Related

How to find the Postion of all matching substrings in a QStringList

i am looking for a way to find the cell position of all matching substrings in a QStringList.
The List is filled form a txt file looking like that:
10:36:50,590/2002/1800
10:36:50,621/2002/1801
10:36:50,652/2002/1802
10:36:50,684/2002/1803
10:36:50,715/2002/1803
10:36:50,746/2002/1803
10:36:50,777/2002/1803/0/0/Target_Hit
10:36:50,809/2002/1802
10:36:50,840/2002/1802
10:36:50,871/2002/1802
10:36:50,965/2000/1831/0/0/Target_Hit
Each cell of the QStringList contain one line of the txt file.
Now i want to find the absolut number of hits and postion of the cells conatining the substring "Target_Hit".
I tried to find the number of it like that:
int number_of_hits = List.indexOf(QRegExp(".*\Target_Hit$)); but that returns a -1
so i guess the QRegExp is incorrect.
You cannot use indexOf for this because it would only return you one index, and it seems that you are looking for multiple.
I would read the file line by line, check each line if it contains what you are looking for, and take note of that, effectively this pseudo code:
initialise a counter to zero.
initialise a position list to an empty list.
read each line
check if the line contains the search string.
if it does: append the position into a list and increment the counter.
continue the next line.
Then, at the end, you could have all that you desired to have.

Tcl - How to Add Text after last character through regex?

I need a tip, tip or suggestion followed by some example of how I can add an extension in .txt format after the last character of a variable's output line.
For example:
set txt " ONLINE ENGLISH COURSE - LESSON 5 "
set result [concat "$txt" .txt]
Print:
Note that there is space in the start, means and fin of the variable phrase (txt). What must be maintained are the spaces of the start and means. But replace the last space after the end of the sentence, with the format of the extension [.txt].
With the built-in concat method of Tcl, it does not achieve the desired effect.
The expected result was something like this:
ONLINE ENGLISH COURSE - LESSON 5.txt
I know I could remove spaces with string map but I don't know how to remove just the last occurrence on the line.
And otherwise I don’t know how to remove the last space to add the text [.txt]
If anyone can point me to one or more solutions, thank you in advance.
set result "[string trimright $txt].txt"
or
set result [regsub {\s*$} $txt ".txt"]

GetPositionAtOffset() don't return good position

I use a RichTextBox in WPF (4.0) and I use the GetPositionAtOffset() method to get a text range between two position in the content in RichTextBox.
1) I initialize the text pointer "position" from MyRichTextBox.Document.ContentStart :
TextPointer position = RTBEditor.Document.ContentStart;
2) I get the text from my RichTextBox like that :
var textRun = new TextRange(RTBEditor.Document.ContentStart, RTBEditor.Document.ContentEnd).Text;
3) With Regex I find a string that I want in textRun and get the begin's index and the end's index (I search a text between "/*" and "*/"):
Regex regex = new Regex(#"/\*([^\*/])*\*/");
var match = regex.Match(textRun);
TextPointer start = position.GetPositionAtOffset(matchBegin.Index, LogicalDirection.Forward);
TextPointer end = position.GetPositionAtOffset(matchBegin.Index + matchBegin.Length, LogicalDirection.Backward);
But, when I use these pointers in a textrange and colorize the text inside, it's not the good text matched in my regex (with goods indexes) which is colorized in my RichTextBox.
Why the GetPositionAtOffset() method don't give the position at the index specified ? It's this method the problem or it's somewhere else ?
Thank's for reply, I am stopped in my development.
According to this, https://msdn.microsoft.com/en-us/library/ms598662%28v=vs.110%29.aspx
GetPositionAtOffset returns a TextPointer to the position indicated by the specified offset, in symbols, from the beginning of the current TextPointer.
Any of the following is considered to be a symbol:
An opening or closing tag for the TextElement element.
A UIElement element contained in an InlineUIContainer or BlockUIContainer. Note that such a UIElement is always counted as exactly one symbol; any additional content or elements contained by the UIElement are not counted as symbols.
A 16-bit Unicode character inside of a text Run element.
Sorry to bother you, the problem was somewhere else.
I initialized the text of my RichTextBox with AppendText() method and not with a paragraph that I added in the blocks. So now it works fine !

How can I get a token from a search in a whole file in vimscript?

Someone may have asked this before, but I can't find an answer on google...
The search function looks at the whole file in the buffer, but only returns the line number of the match.
The matchstr function can return a token, but only looks at one given string.
How can I realise the functionality that combines the two, and get the token from a search in a whole file? Is there a simple solution?
There are several possibilities:
Option A
You can use searchpos() to get line number and start column of the match, then use getline() and grab the match via matchstr(), using the column as the {start} argument (to properly handle multiple matches in a line).
Option B
Use searchpos() twice, the second time with the ceW argument to get the end of the match. Now you have two positions, and you can either set marks to both, then yank the text between them, or use getline() and strpart().
Option C
My ingo-library plugin has a ingo#text#frompattern#Get( firstLine, lastLine, pattern, replacement, isOnlyFirstMatch, isUnique ) function that can extract such matches.
In recent versions of Vim (7.3.610 and above), you can (ab)use Vim's normal-mode search object "gn" to do this.
First, set the "last search" register to the pattern you want:
let #/='my pattern'
Next, go to the beginning of the file, and yank the next search hit:
normal! ggygn
Now, the search text is in register #0
If you want to use a different register, you can do that too:
normal! gg"aygn
Now it's in register #a
Note, all this will clobber the search and other registers, so it is polite to save and restore those registers. Something like:
function MyGetSearch(pattern)
let oldpat=#/
let #/=a:pattern
let old_a=#a
normal! gg"aygn
let result=#a
let #a=old_a
let #/=oldpat
return result
endfun
You can get even crazier with this, restoring cursor position and the like, but that's the basic idea.
Another option is to convert the contents of the file to a string and then pass that as the expr argument of matchstr():
//get a list containing all lines in the file as items:
let lineList = readfile(<filename>)
//join the lines into a single string using "\n" or your preferred line delimiter:
let fileString = join(lineList, "\n")
//search fileString for your pattern:
let matchedText = matchstr(fileString, <pattern to match>)
readfile()
join()
matchstr()
Bonus: If you want to do this with the current buffer instead of an arbitrary file, you can replace the call to readfile() with getline(1,'$') to get a list containing all lines of the current buffer.

Regex for splitting below data

I have a data one on each line in a file as below
BMT.PQ
DMZ.IV
VLD.Q
WPS.T
I am looking for a regex to split out into two categories of output
One where starting letter of the data is between A to M
and other
where starting letter of the data is from N to Z
I tried this
[A-M].* for getting first half of data with first beginning letter from A to M
and i was expecting a result/regex text match of
only :
BMT.PQ
DMZ.PQ
but it also gave a match for
LD.Q which was incorrect for me.
I even unsuccessfully tried [(A-M)(A-M)(A-M)].*
Basically i want to split based on starting letter in the data. One half for data beginning with letters from A to M and second half for data beginning with letter N to Z.
You are close, all you need is to add the ^ for start of string and $ for end of string.
^[A-M].*$
and
^[N-Z].*$
Make sure you enable multiline mode. Multiline mode (usually the m flag) allows ^ and $ to detect start of line and end of line respectively.
The carat symbol represents the start of the string being searched/matched. The two regexs that you probably need are:
^[A-M]
^[N-Z]