PDA

View Full Version : Parameter data type parsing BUG



xLeaves
09-08-2019, 20:22
Dear ErosOlmi:

The cJSON library adds a structure CJSON and a structure pointer for exchanging data CJSON Ptr

When exchanging data, you must use the CJSON Ptr data type. Since Ptr is used, I think it is a 32-bit pointer data. I can replace it with a Long type.

But the actual situation is, the data type must be CJSON Ptr, otherwise you can't receive the data.

For example, these two pieces of code:


Dim pRoot As cJSON Ptr
Dim sJson As String = Load_File(APP_ScriptPath & "test.json")
pRoot = cJSON_Parse(sJson)
MsgBox cJSON_Print(pRoot)


Dim pRoot As Long
Dim sJson As String = Load_File(APP_ScriptPath & "test.json")
pRoot = cJSON_Parse(sJson)
MsgBox cJSON_Print(pRoot)

The upper part is running normally, and the next part is not working properly. This is counter-intuitive.

Of course, the use of non-standard data types is not my intention, because in the function is not allowed to pass CJSON Ptr as a parameter type, will report directly, so there is a test to change the type to Long.

Such as this code:


Sub a(ByVal b As CJSON Ptr)

End Sub

I think this is two bugs.

The latter should be caused by reading only one token when parsing the data, and the former I can’t guess why.

xLeaves
09-08-2019, 20:24
In addition, I try to use the following statement to create a type alias to avoid parsing problems.


Alias CJSON Ptr As pCJSON

It also doesn't work

xLeaves
09-08-2019, 20:25
This is the code I encountered error, it directly reads the data of a node of JSON through a series of paths.




Uses "CJson"



' 以下封装原作者 : 天才 ( QQ : 94220045 )

' 根据路径获取 CJSON Ptr
Alias CJSON Ptr As pCJSON
Function cJSON_GetPathItem(ByVal pJson As CJSON Ptr, ByVal sPath As String) As CJSON Ptr
Dim As Long i, j, start
Dim As String index, item
Dim p As CJSON Ptr = pJson
i = 1
Do While (i <= Len(sPath))
If Mid$(sPath, i, 1) = "." Then
i = i + 1
ElseIf Mid$(sPath, i, 1) = "(" Then
start = i + 1
For j = start To Len(sPath)
If Mid$(sPath, j, 1) = ")" Then
Exit For
End If
Next
index = Mid$(sPath, start, j - start)
p = cJSON_GetArrayItem(p, CLng(index))
i = j + 1
Else
start = i
Do
i = i + 1
Loop While Not ((Mid$(sPath, i, 1) = ".") Or (Mid$(sPath, i, 1) = "(") Or (i > Len(sPath)))
item = Mid$(sPath, start, i - start)
p = cJSON_GetObjectItem(p, item)
End If
Loop
return p
End Function

' 从字符串中 根据路径获取 CJSON Ptr
Function cJSON_GetPathItemByString(ByVal sJson As String, ByVal sPath As String) As CJSON Ptr
Return cJSON_GetPathItem(cJSON_Parse(sJson), sPath)
End Function

' 从文件中 根据路径获取 CJSON Ptr
Function cJSON_GetPathItemByFile(ByVal sPath As String, ByVal sPath As String) As CJSON Ptr
Return cJSON_GetPathItemByString(Load_File(sPath), sPath)
End Function

' 根据路径获取字符串值
Function cJSON_GetPathValue(ByVal pJson As CJSON Ptr, ByVal sPath As String) As String
Dim p As CJSON Ptr = cJSON_GetPathItem(pJson, sPath)
Return cJSON_Item_GetValue(p)
End Function

' 从字符串中 根据路径获取字符串值
Function cJSON_GetPathValueByString(ByVal sJson As String, ByVal sPath As String) As String
Dim p As CJSON Ptr = cJSON_GetPathItemByString(sJson, sPath)
Return cJSON_Item_GetValue(p)
End Function

' 从文件中 根据路径获取字符串值
Function cJSON_GetPathValueByFile(ByVal sPath As String, ByVal sPath As String) As String
Dim p As CJSON Ptr = cJSON_GetPathItemByFile(sPath, sPath)
Return cJSON_Item_GetValue(p)
End Function

' 根据路径获取数值
Function cJSON_GetPathValueNumber(ByVal pJson As CJSON Ptr, ByVal sPath As String) As Double
Dim p As CJSON Ptr = cJSON_GetPathItem(pJson, sPath)
Return cJSON_Item_GetValueNumber(p)
End Function

' 从字符串中 根据路径获取数值
Function cJSON_GetPathValueNumberByString(ByVal sJson As String, ByVal sPath As String) As Double
Dim p As CJSON Ptr = cJSON_GetPathItemByString(sJson, sPath)
Return cJSON_Item_GetValueNumber(p)
End Function

' 从文件中 根据路径获取数值
Function cJSON_GetPathValueNumberByFile(ByVal sPath As String, ByVal sPath As String) As Double
Dim p As CJSON Ptr = cJSON_GetPathItemByFile(sPath, sPath)
Return cJSON_Item_GetValueNumber(p)
End Function

Petr Schreiber
10-08-2019, 15:36
Hi xLeaves,

thinBASIC does not perform a lot of checks at runtime, to keep reasonable execution speed.

The formal check will be provided via tool thinClippy, which you will be able to run from thinAir in thinBasic 1.10.8.0 in its early version.

You are using ALIAS incorrectly, just one keyword can be aliased with just one word. This is something which will be reported by thinClippy, so you can check before execution that everything is allright.

For your code thinClippy would give you suggestion:


In C:\userScripts\xleaves.tbasic:

--------------------------------------------------------------------------------
Line 8 - ALIAS CJSON PTR AS PCJSON
^
Exactly one keyword must be followed by AS

--------------------------------------------------------------------------------
Analysis finished: 1 issue(s) found
--------------------------------------------------------------------------------


Please note ALIAS is not a macro mechanism, but really a 1 for 1 alias for keyword.


Petr

ErosOlmi
12-08-2019, 10:36
xLeaves,

cJSon library is not my library (has I stated in help: https://www.thinbasic.com/public/products/thinBasic/help/html/index.html?cjson.htm) but a library from Dave Gable: https://github.com/DaveGamble/cJSON
thinBasic module is a wrapper of that library (not the latest version)

It uses a 2 level pointer indirection that I replicated in thinBasic module creating a pointer to a cJSon data structure: https://www.thinbasic.com/public/products/thinBasic/help/html/index.html?cjson_data_structure.htm
I think I can improve it and remove the necessity of the 2 levels of indirection.
Not sure if I will keep retro compatibility with thinBasic scripts already there.
If it will be retro compatible ... I will change otherwise ... I have to see what I can do.


Regarding ALIAS it is just ... an ALIAS: rename a current key into something else.
What you tried to do was like a C macro. Maybe I will develop somewhere in future but I need to recode thinBasic preparser completely.


Ciao
Eros