diff --git a/examples/examples/Database/PictureDatabase/FormPictureDatabase.class b/examples/examples/Database/PictureDatabase/FormPictureDatabase.class
index 9ceffb0a5..5b82db37a 100644
--- a/examples/examples/Database/PictureDatabase/FormPictureDatabase.class
+++ b/examples/examples/Database/PictureDatabase/FormPictureDatabase.class
@@ -58,11 +58,11 @@
'
'''
-PUBLIC SUB Form_Open()
+Public Sub Form_Open()
- 'DB.Debug = TRUE
+ 'DB.Debug = True
- ME.Center()
+ Me.Center()
Dialog.Path = User.Home
GridViewImages.Columns.Count = 2
GridViewImages.Columns[0].Text = "Thumb"
@@ -83,130 +83,130 @@ PUBLIC SUB Form_Open()
' Display the database content
ModuleDatabase.Select()
DisplayImages()
-CATCH
- PanelButtons.Enabled = FALSE
+Catch
+ PanelButtons.Enabled = False
Message.Warning(ERROR.Text)
-END
+End
-PUBLIC SUB Form_Close()
+Public Sub Form_Close()
ModuleDatabase.CloseDatabase()
-END
+End
'''
''' Buttons
'''
-PUBLIC SUB ToolButtonAdd_Click()
- Dialog.Filter = FileFilter(TRUE)
+Public Sub ToolButtonAdd_Click()
+ Dialog.Filter = FileFilter(True)
Dialog.Title = "Add image to database"
- IF Dialog.OpenFile() THEN RETURN
+ If Dialog.OpenFile() Then Return
ModuleDatabase.Add(Dialog.Path)
ModuleDatabase.Select()
DisplayImages()
-CATCH
+Catch
Message.Warning(ERROR.Text)
-END
+End
-PUBLIC SUB ToolButtonRemove_Click()
- DIM m AS String
- IF GridViewImages.Row >= 0 THEN
+Public Sub ToolButtonRemove_Click()
+ Dim m As String
+ If GridViewImages.Row >= 0 Then
m = "Are you sure you want to delete image " & (GridViewImages.Row + 1)
m &= " from the database:\n\n" & TextAreaDescription.Text
- IF Message.Question(m, "Delete", "Cancel") = 1 THEN
+ If Message.Question(m, "Delete", "Cancel") = 1 Then
ModuleDatabase.Delete(GridViewImages.Row)
ModuleDatabase.Select()
DisplayImages()
- END IF
- END IF
-CATCH
+ End If
+ End If
+Catch
Message.Warning(ERROR.Text)
-END
+End
-PUBLIC SUB ToolButtonExport_Click()
- Dialog.Filter = FileFilter(FALSE)
+Public Sub ToolButtonExport_Click()
+ Dialog.Filter = FileFilter(False)
Dialog.Title = "Save image from database"
- IF Dialog.SaveFile() THEN RETURN
+ If Dialog.SaveFile() Then Return
PictureBoxImage.Picture.Save(Dialog.Path)
-CATCH
+Catch
Message.Warning("Error saving image:\n\n" & ERROR.Text)
-END
+End
-PUBLIC SUB ToolButtonUpdate_Click()
+Public Sub ToolButtonUpdate_Click()
ModuleDatabase.Update(GridViewImages.Row, TextAreaDescription.Text)
GridViewImages[GridViewImages.Row, 1].Text = TextAreaDescription.Text
-CATCH
+Catch
Message.Warning(ERROR.Text)
-END
+End
'''
''' GridView events
'''
-PUBLIC SUB GridViewImages_Click()
- IF GridViewImages.Row >= 0 THEN
+Public Sub GridViewImages_Click()
+ If GridViewImages.Row >= 0 Then
ShowImage(GridViewImages.Row)
- END IF
-END
+ End If
+End
'''
''' Functions
'''
-PRIVATE SUB DisplayImages()
- DIM i AS Integer
- DIM tempFile AS String
- DIM tempPicture AS String
+Private Sub DisplayImages()
+ Dim i As Integer
+ Dim tempFile As String
+ Dim tempPicture As String
GridViewImages.Clear()
GridViewImages.Rows.Count = ModuleDatabase.ResultPictures.Count
- IF ModuleDatabase.ResultPictures.Count > 0 THEN
+ If ModuleDatabase.ResultPictures.Count > 0 Then
tempFile = Temp() & ".png"
- FOR EACH ModuleDatabase.ResultPictures
+ For Each ModuleDatabase.ResultPictures
i = ModuleDatabase.ResultPictures.Index
tempPicture = ModuleDatabase.ResultPictures["thumb"].Data
- IF tempPicture THEN
+ If tempPicture Then
File.Save(tempFile, tempPicture)
GridViewImages[i, 0].Picture = Picture.Load(tempFile)
- END IF
+ End If
GridViewImages[i, 1].Text = ModuleDatabase.ResultPictures["description"]
- NEXT
+ Next
GridViewImages.Row = 0
ShowImage(0)
- ELSE
+ Else
TextAreaDescription.Text = ""
- PictureBoxImage.Picture = NULL
+ PictureBoxImage.Picture = Null
PictureBoxImage.Resize(1, 1)
- END IF
- IF Exist(tempFile) THEN KILL tempFile
+ End If
+ If Exist(tempFile) Then Kill tempFile
GridViewImages.Rows.Height = ModuleDatabase.ThumbSize
ToolButtonRemove.Enabled = (GridViewImages.Rows.Count > 0)
ToolButtonExport.Enabled = ToolButtonRemove.Enabled
ToolButtonUpdate.Enabled = ToolButtonRemove.Enabled
-END
+End
-PRIVATE SUB ShowImage(Row AS Integer)
- DIM tempFile AS String
- DIM tempPicture AS String
+Private Sub ShowImage(Row As Integer)
+ Dim tempFile As String
+ Dim tempPicture As String
tempFile = Temp() & ".png"
ModuleDatabase.ResultPictures.MoveTo(Row)
TextAreaDescription.Text = ModuleDatabase.ResultPictures["description"]
tempPicture = ModuleDatabase.ResultPictures["image"].Data
- IF tempFile THEN
+ If tempFile Then
File.Save(tempFile, tempPicture)
PictureBoxImage.Picture = Picture.Load(tempFile)
PictureBoxImage.Resize(PictureBoxImage.Picture.Width, PictureBoxImage.Picture.Height)
- ELSE
- PictureBoxImage.Picture = NULL
- END IF
- IF Exist(tempFile) THEN KILL tempFile
-END
+ Else
+ PictureBoxImage.Picture = Null
+ End If
+ If Exist(tempFile) Then Kill tempFile
+End
' Filter for our user file open dialog. All image types supported by Gambas
-PRIVATE FUNCTION FileFilter(OPTIONAL All AS Boolean = FALSE) AS String[]
- DIM filter AS NEW String[]
- IF All THEN
+Private Function FileFilter(Optional All As Boolean = False) As String[]
+ Dim filter As New String[]
+ If All Then
filter.Add("*.png *.jpeg *.jpg *.bmp *.gif *.xpm")
filter.Add("All Graphics")
- END IF
+ End If
filter.Add("*.png")
filter.Add("Portable Network Graphics")
filter.Add("*.jpeg *.jpg")
@@ -217,11 +217,11 @@ PRIVATE FUNCTION FileFilter(OPTIONAL All AS Boolean = FALSE) AS String[]
filter.Add("Graphics Interchange Format")
filter.Add("*.xpm")
filter.Add("X PixMap")
- IF All THEN
+ If All Then
filter.Add("*")
filter.Add("All Files")
- END IF
- RETURN filter
-END
+ End If
+ Return filter
+End
''' End of class FormPictureDatabase '''
diff --git a/examples/examples/Database/PictureDatabase/ModuleDatabase.module b/examples/examples/Database/PictureDatabase/ModuleDatabase.module
index 4d355b3b5..441f0f5e4 100644
--- a/examples/examples/Database/PictureDatabase/ModuleDatabase.module
+++ b/examples/examples/Database/PictureDatabase/ModuleDatabase.module
@@ -86,21 +86,21 @@
'
'''
-PUBLIC CONST ThumbSize AS Integer = 36
-PUBLIC ResultPictures AS Result
+Public Const ThumbSize As Integer = 36
+Public ResultPictures As Result
-PRIVATE databaseConnection AS NEW Connection
-PRIVATE tempFile AS String
+Private databaseConnection As New Connection
+Private tempFile As String
-PUBLIC SUB _init()
+Public Sub _init()
tempFile = Temp() & ".png"
-END
+End
' Opens the pictures database. If the database or table does not
' exist then they are created.
-PUBLIC SUB OpenDatabase(DBType AS String, DBHost AS String, DBName AS String, UserName AS String, UserPassword AS String)
- DIM pictureTable AS Table
- DIM errorMessageHeader AS String
+Public Sub OpenDatabase(DBType As String, DBHost As String, DBName As String, UserName As String, UserPassword As String)
+ Dim pictureTable As Table
+ Dim errorMessageHeader As String
' If you wnat to see the commands sent to the
' database then uncommant this line
' DB.Debug = TRUE
@@ -113,34 +113,34 @@ PUBLIC SUB OpenDatabase(DBType AS String, DBHost AS String, DBName AS String, Us
databaseConnection.Password = UserPassword
databaseConnection.Port = ""
' Open the connection
- TRY databaseConnection.Open()
- IF ERROR THEN
+ Try databaseConnection.Open()
+ If Error Then
errorMessageHeader = "Could not open database connection " & DBHost
Error.Raise(Error.Text)
- END IF
+ End If
' Check if the server connection has a database with the
' required database name.
- IF NOT databaseConnection.Databases.Exist(DBName) THEN
- PRINT "Database not found. Creating new database"
+ If Not databaseConnection.Databases.Exist(DBName) Then
+ Print "Database not found. Creating new database"
' Create a new database
databaseConnection.Databases.Add(DBName)
' I found I needed this with a SQLite database
' (but not with a MySQL database)
- WAIT 0.5
- END IF
+ Wait 0.5
+ End If
' Close the server connection
databaseConnection.Close()
' Open a connection to the database
databaseConnection.Host = DBHost
databaseConnection.Name = DBName
- TRY databaseConnection.Open()
- IF ERROR THEN
+ Try databaseConnection.Open()
+ If Error Then
errorMessageHeader = "Could not open database " & DBName & " on " & DBHost
Error.Raise(Error.Text)
- END IF
+ End If
' Check if the database has a pictures table
- IF NOT databaseConnection.Tables.Exist("pictures") THEN
- PRINT "Database tables not found. Creating new pictures table"
+ If Not databaseConnection.Tables.Exist("pictures") Then
+ Print "Database tables not found. Creating new pictures table"
' Add a picture table to the database
pictureTable = databaseConnection.Tables.Add("pictures")
pictureTable.Fields.Add("id", db.Serial) ' id field as autoinc integer
@@ -149,64 +149,67 @@ PUBLIC SUB OpenDatabase(DBType AS String, DBHost AS String, DBName AS String, Us
pictureTable.Fields.Add("description", db.String, 0) ' description field as unlimited string
pictureTable.PrimaryKey = ["id"]
pictureTable.Update()
- END IF
-CATCH
- IF errorMessageHeader = "" THEN
+ End If
+Catch
+ If errorMessageHeader = "" Then
errorMessageHeader = "Database connection error: " & DBName & " on " & DBHost
- END IF
+ End If
Error.Raise("" & errorMessageHeader & "
Error:
" & DConv(Error.Text))
-END
+End
-PUBLIC SUB Add(ImagePath AS String)
- DIM img AS Image
- DIM newPicture AS Result
- DIM pictureData AS String
- DIM scale AS Float
+Public Sub Add(ImagePath As String)
+ Dim img As Image
+ Dim newPicture As Result
+ Dim pictureData As String
+ Dim scale As Float
+ Dim eTime As Float
newPicture = databaseConnection.Create("pictures")
' Save temp image as png file
img = Image.Load(ImagePath)
img.Save(tempFile)
newPicture["image"] = File.Load(tempFile)
' Create image thumb
- IF img.Width > thumbSize OR img.Height > thumbSize THEN
+ If img.Width > thumbSize Or img.Height > thumbSize Then
' Calc factor to scale isotropic
scale = Min(ThumbSize / img.Width, ThumbSize / img.Height)
- img = img.Stretch(img.Width * scale, img.Height * scale, TRUE)
+ img = img.Stretch(img.Width * scale, img.Height * scale, True)
img.Save(tempFile)
- END IF
+ End If
newPicture["thumb"] = File.Load(tempFile)
' Add description and update
newPicture["description"] = "Image " & File.BaseName(ImagePath) & " added: " & Format(Now, "dddd, dd mmmm yyyy hh:nn:ss")
+ eTime = Timer
newPicture.Update()
- IF Exist(tempFile) THEN KILL tempFile
-CATCH
+ Print "Done in "; Format(Timer - eTime, "#.###"); " s"
+ If Exist(tempFile) Then Kill tempFile
+Catch
Error.Raise("Add database record error
Error:
" & DConv(Error.Text))
-END
+End
-PUBLIC SUB Select()
+Public Sub Select()
ResultPictures = databaseConnection.Edit("pictures")
-CATCH
+Catch
Error.Raise("Select database records error
Error:
" & DConv(Error.Text))
-END
+End
-PUBLIC SUB Update(Row AS Integer, Description AS String)
+Public Sub Update(Row As Integer, Description As String)
ResultPictures.MoveTo(Row)
ResultPictures["description"] = Conv(Description, Desktop.Charset, databaseConnection.Charset)
ResultPictures.Update()
-CATCH
+Catch
Error.Raise("Update database record error
Error:
" & DConv(Error.Text))
-END
+End
-PUBLIC SUB Delete(Row AS Integer)
+Public Sub Delete(Row As Integer)
ResultPictures.MoveTo(Row)
ResultPictures.Delete()
-CATCH
+Catch
Error.Raise("Delete database record error
Error:
" & DConv(Error.Text))
-END
+End
-PUBLIC SUB CloseDatabase()
- TRY databaseConnection.Close()
- IF ERROR THEN PRINT "Error closing database"
-END
+Public Sub CloseDatabase()
+ Try databaseConnection.Close()
+ If Error Then Print "Error closing database"
+End
''' End of ModuleDatabase '''
diff --git a/gb.db.postgresql/src/main.c b/gb.db.postgresql/src/main.c
index d78d122b5..4bad4c425 100644
--- a/gb.db.postgresql/src/main.c
+++ b/gb.db.postgresql/src/main.c
@@ -90,6 +90,9 @@ static void quote_string(const char *data, int len, DB_FORMAT_CALLBACK add)
unsigned char c;
char buffer[8];
+ if (DB.GetCurrentDatabase()->version >= 80200)
+ (*add)("E", 1);
+
(*add)("'", 1);
for (i = 0; i < len; i++)
{
diff --git a/main/gbx/Makefile.am b/main/gbx/Makefile.am
index 8c4317cb5..e59ded8f2 100644
--- a/main/gbx/Makefile.am
+++ b/main/gbx/Makefile.am
@@ -22,7 +22,6 @@ gbx3_SOURCES = \
gb_table.c \
gbx_type.h gbx_type.c \
gbx_value.h gbx_value.c \
- gbx_subst.h gbx_subst.c \
gbx_exec.h gbx_exec.c gbx_exec_push.c gbx_exec_enum.c gbx_exec_pop.c gbx_exec_loop.c \
gbx_class_desc.h gbx_class.h gbx_class_init.c gbx_class.c gbx_class_native.c \
gbx_class_load.c gbx_class_load.h \
diff --git a/main/gbx/gbx_api.c b/main/gbx/gbx_api.c
index 0444c38ba..9d1ea9779 100644
--- a/main/gbx/gbx_api.c
+++ b/main/gbx/gbx_api.c
@@ -159,7 +159,7 @@ void *GAMBAS_Api[] =
(void *)STRING_subst,
(void *)STRING_subst_add,
- (void *)SUBST_add,
+ (void *)STRING_make,
(void *)GB_ConvString,
(void *)STRING_conv_file_name,
(void *)GB_RealFileName,
@@ -247,6 +247,10 @@ void *GAMBAS_Api[] =
(void *)GB_ImageConvert,
(void *)GB_PictureCreate,
(void *)GB_PictureInfo,
+
+ (void *)STRING_start_len,
+ (void *)STRING_end,
+ (void *)STRING_make,
NULL
};
diff --git a/main/gbx/gbx_c_array.c b/main/gbx/gbx_c_array.c
index 99d3afcf3..16510b3a2 100644
--- a/main/gbx/gbx_c_array.c
+++ b/main/gbx/gbx_c_array.c
@@ -766,7 +766,7 @@ BEGIN_METHOD(CARRAY_string_join, GB_STRING sep; GB_STRING esc)
int lsep = 1;
char *esc = "";
int lesc = 0;
- char escl, escr;
+ char escl, NO_WARNING(escr);
int i;
char **data = (char **)THIS->data;
char *p, *p2;
@@ -800,10 +800,10 @@ BEGIN_METHOD(CARRAY_string_join, GB_STRING sep; GB_STRING esc)
if (ARRAY_count(data))
max -= lsep;
- SUBST_init_max(max);
+ STRING_start_len(max);
}
else
- SUBST_init();
+ STRING_start();
for (i = 0; i < ARRAY_count(data); i++)
{
@@ -811,10 +811,10 @@ BEGIN_METHOD(CARRAY_string_join, GB_STRING sep; GB_STRING esc)
l = STRING_length(data[i]);
if (i)
- SUBST_add(sep, lsep);
+ STRING_make(sep, lsep);
if (lesc)
{
- SUBST_add(&escl, 1);
+ STRING_make(&escl, 1);
if (l)
{
for(;;)
@@ -822,29 +822,24 @@ BEGIN_METHOD(CARRAY_string_join, GB_STRING sep; GB_STRING esc)
p2 = index(p, escr);
if (p2)
{
- SUBST_add(p, p2 - p + 1);
- SUBST_add(&escr, 1);
+ STRING_make(p, p2 - p + 1);
+ STRING_make_char(escr);
p = p2 + 1;
}
else
{
- SUBST_add(p, l + data[i] - p);
+ STRING_make(p, l + data[i] - p);
break;
}
}
}
- SUBST_add(&escr, 1);
+ STRING_make_char(escr);
}
else if (l)
- SUBST_add(p, l);
+ STRING_make(p, l);
}
- SUBST_exit();
-
- if (SUBST_buffer)
- GB_ReturnString(SUBST_buffer);
- else
- GB_ReturnNull();
+ GB_ReturnString(STRING_end_temp());
END_METHOD
diff --git a/main/gbx/gbx_string.c b/main/gbx/gbx_string.c
index 315d15a4e..e8200e0b6 100644
--- a/main/gbx/gbx_string.c
+++ b/main/gbx/gbx_string.c
@@ -70,6 +70,9 @@ static const char _char_string[512] =
static int _index = 0;
+STRING_MAKE STRING_make_buffer;
+#define _make STRING_make_buffer
+
//static HASH_TABLE *_intern = NULL;
/****************************************************************************
@@ -81,9 +84,11 @@ static int _index = 0;
#define SIZE_INC 16
#define REAL_SIZE(_len) (((_len) + (SIZE_INC - 1)) & ~(SIZE_INC - 1))
-#define POOL_SIZE 8
+#define POOL_SIZE 16
#define POOL_MAX 32
+#define POOL_MAX_LEN (POOL_SIZE * SIZE_INC)
+
static STRING *_pool[POOL_SIZE] = { 0 };
static int _pool_count[POOL_SIZE] = { 0 };
@@ -156,6 +161,10 @@ static STRING *realloc_string(STRING *str, int new_len)
STRING_free_real(str->data);
return NULL;
}
+ else if (size > POOL_MAX_LEN && new_size > POOL_MAX_LEN)
+ {
+ REALLOC(&str, new_size, "realloc_string");
+ }
else
{
STRING *nstr = alloc_string(new_len);
@@ -228,8 +237,6 @@ void STRING_new(char **ptr, const char *src, int len)
#endif
}
-#define post_free STRING_free_later
-
void STRING_free_later(char *ptr)
{
/*if (NLast >= MAX_LAST_STRING)
@@ -308,7 +315,7 @@ void STRING_extend_end(char **ptr)
if (*ptr)
{
(*ptr)[STRING_length(*ptr)] = 0;
- post_free(*ptr);
+ STRING_free_later(*ptr);
}
}
@@ -440,7 +447,7 @@ void STRING_unref_keep(char **ptr)
if (str->ref > 1)
str->ref--;
else
- post_free(*ptr);
+ STRING_free_later(*ptr);
}
/* The get_param argument index starts at 1, not 0! */
@@ -544,19 +551,6 @@ char *STRING_subst(const char *str, int len, SUBST_FUNC get_param)
lp[np] = strlen(p[np]);
len_subst += lp[np];
}
-
- /*i++;
- d = str[i];
- if (d == '&')
- len_subst--;
- else if (d >= '1' && d <= '9')
- {
- np = d - '1';
- (*get_param)(np + 1, &p[np], &lp[np]);
- if (lp[np] < 0)
- lp[np] = strlen(p[np]);
- len_subst += lp[np] - 2;
- }*/
}
}
@@ -585,35 +579,20 @@ char *STRING_subst(const char *str, int len, SUBST_FUNC get_param)
memcpy(ps, p[np], lp[np]);
ps += lp[np];
}
- /*i++;
- d = str[i];
- if (d == '&')
- *ps++ = '&';
- else if (d >= '1' && d <= '9')
- {
- np = d - '1';
- memcpy(ps, p[np], lp[np]);
- ps += lp[np];
- }
- else
- {
- *ps++ = '&';
- *ps++ = d;
- }*/
}
else
*ps++ = c;
}
*ps = 0;
- post_free(subst);
+ STRING_free_later(subst);
return subst;
}
char *STRING_subst_add(const char *str, int len, SUBST_ADD_FUNC add_param)
{
uint i;
- uchar c;
+ char c;
int np;
if (!str)
@@ -622,7 +601,7 @@ char *STRING_subst_add(const char *str, int len, SUBST_ADD_FUNC add_param)
if (len <= 0)
len = strlen(str);
- SUBST_init();
+ STRING_start_len(len);
for (i = 0; i < len; i++)
{
@@ -633,61 +612,23 @@ char *STRING_subst_add(const char *str, int len, SUBST_ADD_FUNC add_param)
switch (np)
{
case INDEX_AT:
- SUBST_add_char('&');
+ STRING_make_char('&');
break;
case INDEX_IGNORE:
- SUBST_add_char('&');
- SUBST_add_char(str[i]);
+ STRING_make_char('&');
+ STRING_make_char(str[i]);
break;
case INDEX_ERROR:
break;
default:
(*add_param)(np);
}
- /*
- i++;
- d = str[i];
- if (d == '&')
- {
- SUBST_add_char('&');
- }
- else if (d >= '1' && d <= '9')
- {
- np = d - '0';
- (*add_param)(np);
- }
- else if (d == '{')
- {
- np = 0;
- err = FALSE;
- for(;;)
- {
- i++;
- if (i >= len)
- break;
- d = str[i];
- if (d == '}')
- break;
- if (d >= '0' && d <= '9')
- np = np * 10 + d - '0';
- else
- err = TRUE;
- }
- if (!err && np >= 1 && np <= 64)
- (*add_param)(np);
- }
- else
- {
- SUBST_add_char('&');
- SUBST_add_char(d);
- }*/
}
else
- SUBST_add_char(c);
+ STRING_make_char(c);
}
- SUBST_exit();
- return SUBST_buffer;
+ return STRING_end_temp();
}
@@ -892,7 +833,7 @@ char *STRING_conv_file_name(const char *name, int len)
STRING_add(&user, &name[pos], len - pos);
name = user;
len = STRING_length(name);
- post_free(user);
+ STRING_free_later(user);
}
}
@@ -1072,6 +1013,97 @@ __FOUND:
return pos;
}
+void STRING_start_len(int len)
+{
+ _make.inc = 32;
+
+ if (len == 0)
+ len = 32;
+
+ STRING_new(&_make.buffer, NULL, len);
+
+ _make.max = len;
+ _make.len = 0;
+ _make.ptr = _make.buffer;
+ _make.ntemp = 0;
+}
+
+void STRING_make_dump()
+{
+ int n = _make.ntemp;
+ _make.ntemp = 0;
+ STRING_make(_make.temp, n);
+}
+
+// len == 0 est possible ! On peut vouloir ajouter une chaƮne vide.
+
+void STRING_make(const char *src, int len)
+{
+ int pos;
+
+ if (!src)
+ return;
+
+ if (len < 0)
+ len = strlen(src);
+
+ if (len <= 0)
+ return;
+
+ if (_make.ntemp)
+ STRING_make_dump();
+
+ _make.len += len;
+
+ if (_make.len >= _make.max)
+ {
+ pos = (_make.len - _make.max) * 4;
+ if (pos < _make.inc)
+ pos = _make.inc;
+ else
+ {
+ _make.inc = (pos + 31) & ~31;
+ if (_make.inc > 1024)
+ _make.inc = 1024;
+ }
+
+ _make.max += pos;
+
+ //fprintf(stderr, "STRING_extend: %d\n", _max - STRING_length(SUBST_buffer));
+ pos = _make.ptr - _make.buffer;
+ STRING_extend(&_make.buffer, _make.max);
+ _make.ptr = _make.buffer + pos;
+ }
+
+ memcpy(_make.ptr, src, len);
+ _make.ptr += len;
+}
+
+char *STRING_end()
+{
+ if (_make.ntemp)
+ STRING_make_dump();
+
+ if (_make.len)
+ {
+ STRING_extend(&_make.buffer, _make.len);
+ _make.buffer[_make.len] = 0;
+ }
+ else
+ STRING_free(&_make.buffer);
+
+ return _make.buffer;
+}
+
+char *STRING_end_temp()
+{
+ STRING_end();
+
+ if (_make.buffer)
+ STRING_free_later(_make.buffer);
+
+ return _make.buffer;
+}
#include "gb_common_string_temp.h"
diff --git a/main/gbx/gbx_string.h b/main/gbx/gbx_string.h
index abaa49a96..678b05e03 100644
--- a/main/gbx/gbx_string.h
+++ b/main/gbx/gbx_string.h
@@ -26,7 +26,6 @@
#define __STRING_H
#include "gbx_value.h"
-#include "gbx_subst.h"
#include "gbx_debug.h"
#include "gb_common_string.h"
@@ -40,8 +39,33 @@ typedef
PACKED
STRING;
+typedef
+ void (*SUBST_FUNC)(int, char **, int *);
+
+typedef
+ void (*SUBST_ADD_FUNC)(int);
+
+#define STRING_MAKE_TEMP 32
+
+typedef
+ struct
+ {
+ char *buffer;
+ char *ptr;
+ int inc;
+ int len;
+ int max;
+ char temp[STRING_MAKE_TEMP];
+ int ntemp;
+ }
+ STRING_MAKE;
+
#define SC_UNICODE ((char *)-1)
+#ifndef __STRING_C
+extern STRING_MAKE STRING_make_buffer;
+#endif
+
void STRING_init(void);
void STRING_exit(void);
@@ -65,17 +89,12 @@ void STRING_new_constant_value(VALUE *value, const char *src, int len);
void STRING_char_value(VALUE *value, uchar car);
void STRING_void_value(VALUE *value);
-/*int STRING_comp_value(VALUE *str1, VALUE *str2);
-int STRING_comp_value_equality(VALUE *str1, VALUE *str2);
-int STRING_comp_value_ignore_case(VALUE *str1, VALUE *str2);*/
-
char *STRING_subst(const char *str, int len, SUBST_FUNC get_param);
char *STRING_subst_add(const char *str, int len, SUBST_ADD_FUNC add_param);
int STRING_conv(char **result, const char *str, int len, const char *src, const char *dst, bool throw);
char *STRING_conv_file_name(const char *name, int len);
char *STRING_conv_to_UTF8(const char *name, int len);
-
#define STRING_from_ptr(_ptr) ((STRING *)((_ptr) - offsetof(STRING, data)))
#define STRING_length(_ptr) ((_ptr) == NULL ? 0 : STRING_from_ptr(_ptr)->len)
@@ -127,4 +146,18 @@ void STRING_unref_keep(char **ptr);
int STRING_search(const char *ps, int ls, const char *pp, int lp, int is, bool right, bool nocase);
+void STRING_start_len(int len);
+#define STRING_start() STRING_start_len(0)
+char *STRING_end();
+char *STRING_end_temp();
+void STRING_make(const char *src, int len);
+void STRING_make_dump();
+
+#define STRING_make_char(_c) \
+{ \
+ if (STRING_make_buffer.ntemp == STRING_MAKE_TEMP) \
+ STRING_make_dump(); \
+ STRING_make_buffer.temp[STRING_make_buffer.ntemp++] = (_c); \
+}
+
#endif
diff --git a/main/gbx/gbx_subr_string.c b/main/gbx/gbx_subr_string.c
index accc6296f..76c09610b 100644
--- a/main/gbx/gbx_subr_string.c
+++ b/main/gbx/gbx_subr_string.c
@@ -608,10 +608,7 @@ void SUBR_replace(void)
if (NPARAM == 4)
nocase = SUBR_get_integer(&PARAM[3]) == GB_COMP_TEXT;
- if (lp >= lr)
- SUBST_init_max(ls);
- else
- SUBST_init_ext(ls, (lr - lp) * 16);
+ STRING_start_len(ls);
if (ls > 0 && lp > 0)
{
@@ -626,9 +623,9 @@ void SUBR_replace(void)
pos--;
if (pos > 0)
- SUBST_add(ps, pos);
+ STRING_make(ps, pos);
- SUBST_add(pr, lr);
+ STRING_make(pr, lr);
pos += lp;
@@ -639,13 +636,11 @@ void SUBR_replace(void)
break;
}
- SUBST_add(ps, ls);
+ STRING_make(ps, ls);
}
- SUBST_exit();
-
RETURN->type = T_STRING;
- RETURN->_string.addr = SUBST_buffer;
+ RETURN->_string.addr = STRING_end_temp();
RETURN->_string.start = 0;
RETURN->_string.len = STRING_length(RETURN->_string.addr);
diff --git a/main/gbx/gbx_subst.c b/main/gbx/gbx_subst.c
index cc78fc378..78a49ea10 100644
--- a/main/gbx/gbx_subst.c
+++ b/main/gbx/gbx_subst.c
@@ -52,15 +52,15 @@ void SUBST_dump_temp(void)
}
}
-void SUBST_init_ext(int len, int inc)
+void SUBST_init_ext(int len)
{
- if (inc == 0)
- inc = 32;
+ _inc = 32;
+
if (len == 0)
- len = inc;
+ len = _inc;
STRING_new(&SUBST_buffer, NULL, len);
- _inc = inc;
+
_max = len;
_len = 0;
_ptr = SUBST_buffer;
@@ -117,3 +117,12 @@ void SUBST_exit(void)
STRING_extend(&SUBST_buffer, _len);
STRING_extend_end(&SUBST_buffer);
}
+
+char *SUBST_get(void)
+{
+ SUBST_dump_temp();
+ STRING_extend(&SUBST_buffer, _len);
+ if (SUBST_buffer)
+ SUBST_buffer[_len] = 0;
+ return SUBST_buffer;
+}
diff --git a/main/gbx/gbx_subst.h b/main/gbx/gbx_subst.h
deleted file mode 100644
index 8cd885a99..000000000
--- a/main/gbx/gbx_subst.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/***************************************************************************
-
- subst.h
-
- string substitution routines
-
- (c) 2000-2007 Benoit Minisini
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-***************************************************************************/
-
-#ifndef __GBX_SUBST_H
-#define __GBX_SUBST_H
-
-#ifndef __GBX_SUBST_C
-EXTERN char *SUBST_buffer;
-EXTERN char SUBST_temp[];
-EXTERN int SUBST_ntemp;
-#endif
-
-#define SUBST_TEMP_SIZE 256
-
-typedef
- void (*SUBST_FUNC)(int, char **, int *);
-
-typedef
- void (*SUBST_ADD_FUNC)(int);
-
-void SUBST_init(int len, int inc);
-void SUBST_init_ext(int len, int inc);
-void SUBST_add(const char *src, int len);
-void SUBST_exit(void);
-void SUBST_dump_temp(void);
-
-#define SUBST_add_char(_c) \
-{ \
- if (SUBST_ntemp == SUBST_TEMP_SIZE) \
- SUBST_dump_temp(); \
- SUBST_temp[SUBST_ntemp++]= (_c); \
-}
-
-#define SUBST_init() SUBST_init_ext(0, 0)
-#define SUBST_init_max(_max) SUBST_init_ext((_max), 0)
-
-#endif
diff --git a/main/lib/db/main.c b/main/lib/db/main.c
index 04460298d..32fcefdef 100644
--- a/main/lib/db/main.c
+++ b/main/lib/db/main.c
@@ -51,6 +51,11 @@ GB_INTERFACE GB EXPORT;
static DB_DRIVER *_drivers[MAX_DRIVER];
static int _drivers_count = 0;
static char *_query = NULL;
+
+#define TEMP_MAX 64
+static char _temp[TEMP_MAX];
+static int _temp_len;
+
static bool _debug = FALSE;
static const char *_try_another = NULL;
@@ -340,7 +345,7 @@ static void mq_add_param(int index)
if (index < 1 || index > query_narg)
return;
- DB_Format(query_driver, &query_arg[index - 1], (DB_FORMAT_CALLBACK)GB.SubstAdd);
+ DB_Format(query_driver, &query_arg[index - 1], (DB_FORMAT_CALLBACK)GB.SubstAddCallback);
}
char *DB_MakeQuery(DB_DRIVER *driver, const char *pattern, int len, int narg, GB_VALUE *arg)
@@ -370,30 +375,54 @@ void q_init(void)
{
GB.FreeString(&_query);
_query = NULL;
+ _temp_len = 0;
+}
+
+static void q_dump_temp(void)
+{
+ if (!_temp_len)
+ return;
+
+ GB.AddString(&_query, _temp, _temp_len);
+ _temp_len = 0;
+}
+
+void q_add_length(const char *str, int len)
+{
+ if (!str)
+ return;
+
+ if ((_temp_len + len) > TEMP_MAX)
+ q_dump_temp();
+
+ if (len > TEMP_MAX)
+ GB.AddString(&_query, str, len);
+ else
+ {
+ memcpy(&_temp[_temp_len], str, len);
+ _temp_len += len;
+ }
}
void q_add(const char *str)
{
if (str)
- GB.AddString(&_query, str, 0);
-}
-
-void q_add_length(const char *str, int len)
-{
- if (str)
- GB.AddString(&_query, str, len);
+ q_add_length(str, strlen(str));
}
char *q_get(void)
{
- return _query;
+ q_dump_temp();
+ return _query;
}
char *q_steal(void)
{
- char *query = _query;
- _query = NULL;
- return query;
+ char *s;
+ q_dump_temp();
+ s = _query;
+ _query = NULL;
+ return s;
}
int q_length(void)
diff --git a/main/share/gambas.h b/main/share/gambas.h
index 3970cbfc9..c0df64d1c 100644
--- a/main/share/gambas.h
+++ b/main/share/gambas.h
@@ -1,22 +1,22 @@
/***************************************************************************
- gambas.h
+ gambas.h
- Copyright (c) 2000-2007 Benoit Minisini
+ Copyright (c) 2000-2007 Benoit Minisini
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
- any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 1, or (at your option)
+ any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***************************************************************************/
@@ -86,13 +86,13 @@
/* This type represents a Gambas datatype identifier */
typedef
- intptr_t GB_TYPE;
+ intptr_t GB_TYPE;
/* This opaque type represents a Gambas class identifier */
typedef
- void *GB_CLASS;
+ void *GB_CLASS;
/* This structure represents the base of every Gambas object.
@@ -101,183 +101,183 @@ typedef
*/
typedef
- struct {
- GB_CLASS klass;
- intptr_t ref;
- }
- GB_BASE;
+ struct {
+ GB_CLASS klass;
+ intptr_t ref;
+ }
+ GB_BASE;
/* Gambas VARIANT datatype definition */
typedef
- union {
- GB_TYPE type;
+ union {
+ GB_TYPE type;
intptr_t _reserved[3];
- struct { GB_TYPE type; int value; } PACKED _boolean;
- struct { GB_TYPE type; int value; } PACKED _byte;
- struct { GB_TYPE type; int value; } PACKED _short;
- struct { GB_TYPE type; int value; } PACKED _integer;
- struct { GB_TYPE type; int64_t value; } PACKED _long;
- struct { GB_TYPE type; double value; } PACKED _single;
- struct { GB_TYPE type; double value; } PACKED _float;
- struct { GB_TYPE type; int date; int time; } PACKED _date;
- struct { GB_TYPE type; char *value; } PACKED _string;
- struct { GB_TYPE type; void *value; } PACKED _object;
- }
- GB_VARIANT_VALUE;
+ struct { GB_TYPE type; int value; } PACKED _boolean;
+ struct { GB_TYPE type; int value; } PACKED _byte;
+ struct { GB_TYPE type; int value; } PACKED _short;
+ struct { GB_TYPE type; int value; } PACKED _integer;
+ struct { GB_TYPE type; int64_t value; } PACKED _long;
+ struct { GB_TYPE type; double value; } PACKED _single;
+ struct { GB_TYPE type; double value; } PACKED _float;
+ struct { GB_TYPE type; int date; int time; } PACKED _date;
+ struct { GB_TYPE type; char *value; } PACKED _string;
+ struct { GB_TYPE type; void *value; } PACKED _object;
+ }
+ GB_VARIANT_VALUE;
typedef
- struct {
- GB_TYPE type;
- GB_VARIANT_VALUE value;
- }
- GB_VARIANT;
+ struct {
+ GB_TYPE type;
+ GB_VARIANT_VALUE value;
+ }
+ GB_VARIANT;
/* Gambas STRING datatype definition */
typedef
- struct {
- GB_TYPE type;
- struct {
- char *addr;
- int start;
- int len;
- } value;
- #if __WORDSIZE == 64
+ struct {
+ GB_TYPE type;
+ struct {
+ char *addr;
+ int start;
+ int len;
+ } value;
+ #if __WORDSIZE == 64
intptr_t _reserved;
#endif
- }
- PACKED
- GB_STRING;
+ }
+ PACKED
+ GB_STRING;
/* Gambas INTEGER datatype definition */
typedef
- struct {
- GB_TYPE type;
- int value;
- #if __WORDSIZE == 64
- int _pad;
- #endif
+ struct {
+ GB_TYPE type;
+ int value;
+ #if __WORDSIZE == 64
+ int _pad;
+ #endif
intptr_t _reserved[2];
- }
- PACKED
- GB_INTEGER;
+ }
+ PACKED
+ GB_INTEGER;
/* Gambas INTEGER datatype definition */
typedef
- struct {
- GB_TYPE type;
- int64_t value;
- #if __WORDSIZE == 64
- intptr_t _reserved[2];
- #else
- int _reserved;
- #endif
- }
- PACKED
- GB_LONG;
+ struct {
+ GB_TYPE type;
+ int64_t value;
+ #if __WORDSIZE == 64
+ intptr_t _reserved[2];
+ #else
+ int _reserved;
+ #endif
+ }
+ PACKED
+ GB_LONG;
/* Gambas POINTER datatype definition */
typedef
- struct {
- GB_TYPE type;
- intptr_t value;
- intptr_t _reserved[2];
- }
- PACKED
- GB_POINTER;
+ struct {
+ GB_TYPE type;
+ intptr_t value;
+ intptr_t _reserved[2];
+ }
+ PACKED
+ GB_POINTER;
/* Gambas BOOLEAN datatype definition */
typedef
- struct {
- GB_TYPE type;
- int value;
- #if __WORDSIZE == 64
- int _pad;
- #endif
+ struct {
+ GB_TYPE type;
+ int value;
+ #if __WORDSIZE == 64
+ int _pad;
+ #endif
intptr_t _reserved[2];
- }
- PACKED
- GB_BOOLEAN;
+ }
+ PACKED
+ GB_BOOLEAN;
/* Gambas FLOAT datatype definition */
typedef
- struct {
- GB_TYPE type;
- double value;
- #if __WORDSIZE == 64
- intptr_t _reserved[2];
- #else
- int _pad;
- #endif
- }
- PACKED
- GB_FLOAT;
+ struct {
+ GB_TYPE type;
+ double value;
+ #if __WORDSIZE == 64
+ intptr_t _reserved[2];
+ #else
+ int _pad;
+ #endif
+ }
+ PACKED
+ GB_FLOAT;
/* Gambas DATE datatype definition */
typedef
- struct {
- int date;
- int time;
- }
- GB_DATE_VALUE;
+ struct {
+ int date;
+ int time;
+ }
+ GB_DATE_VALUE;
typedef
- struct {
- GB_TYPE type;
- GB_DATE_VALUE value;
- #if __WORDSIZE == 64
- intptr_t _reserved[2];
- #else
- int _reserved;
- #endif
- }
- PACKED
- GB_DATE;
+ struct {
+ GB_TYPE type;
+ GB_DATE_VALUE value;
+ #if __WORDSIZE == 64
+ intptr_t _reserved[2];
+ #else
+ int _reserved;
+ #endif
+ }
+ PACKED
+ GB_DATE;
/* Gambas OBJECT datatype definition */
typedef
- struct {
- GB_TYPE type;
- void *value;
- intptr_t _reserved[2];
- }
- PACKED
- GB_OBJECT;
+ struct {
+ GB_TYPE type;
+ void *value;
+ intptr_t _reserved[2];
+ }
+ PACKED
+ GB_OBJECT;
/* Gambas common value definition */
typedef
- union {
- GB_TYPE type;
- GB_BOOLEAN _boolean;
- GB_INTEGER _integer;
- GB_LONG _long;
- GB_FLOAT _float;
- GB_DATE _date;
- GB_STRING _string;
- GB_OBJECT _object;
- GB_VARIANT _variant;
- }
- GB_VALUE;
+ union {
+ GB_TYPE type;
+ GB_BOOLEAN _boolean;
+ GB_INTEGER _integer;
+ GB_LONG _long;
+ GB_FLOAT _float;
+ GB_DATE _date;
+ GB_STRING _string;
+ GB_OBJECT _object;
+ GB_VARIANT _variant;
+ }
+ GB_VALUE;
/* Predefined errors constants */
@@ -290,7 +290,7 @@ typedef
/* Gambas description start macro */
#define GB_DECLARE(name, size) \
- { name, (intptr_t)GB_VERSION, (intptr_t)size }
+ { name, (intptr_t)GB_VERSION, (intptr_t)size }
/* Gambas description end macro */
@@ -343,54 +343,54 @@ typedef
/* Symbol description macros */
#define GB_CONSTANT(symbol, type, value) \
- { "C" symbol, (intptr_t)type, (intptr_t)value }
+ { "C" symbol, (intptr_t)type, (intptr_t)value }
#define GB_PROPERTY(symbol, type, proc) \
- { "p" symbol, (intptr_t)type, (intptr_t)proc }
+ { "p" symbol, (intptr_t)type, (intptr_t)proc }
#define GB_PROPERTY_READ(symbol, type, proc) \
- { "r" symbol, (intptr_t)type, (intptr_t)proc }
+ { "r" symbol, (intptr_t)type, (intptr_t)proc }
#define GB_PROPERTY_SELF(symbol, type) \
- { "r" symbol, (intptr_t)type, (intptr_t)(-1) }
+ { "r" symbol, (intptr_t)type, (intptr_t)(-1) }
#define GB_METHOD(symbol, type, exec, signature) \
- { "m" symbol, (intptr_t)type, (intptr_t)exec, (intptr_t)signature }
+ { "m" symbol, (intptr_t)type, (intptr_t)exec, (intptr_t)signature }
#define GB_EVENT(symbol, type, signature, id) \
- { "::" symbol, (intptr_t)type, (intptr_t)id, (intptr_t)signature }
+ { "::" symbol, (intptr_t)type, (intptr_t)id, (intptr_t)signature }
#define GB_STATIC_PROPERTY(symbol, type, proc) \
- { "P" symbol, (intptr_t)type, (intptr_t)proc }
+ { "P" symbol, (intptr_t)type, (intptr_t)proc }
#define GB_STATIC_PROPERTY_READ(symbol, type, proc) \
- { "R" symbol, (intptr_t)type, (intptr_t)proc }
+ { "R" symbol, (intptr_t)type, (intptr_t)proc }
#define GB_STATIC_PROPERTY_SELF(symbol, type) \
- { "R" symbol, (intptr_t)type, (-1) }
+ { "R" symbol, (intptr_t)type, (-1) }
#define GB_STATIC_METHOD(symbol, type, exec, signature) \
- { "M" symbol, (intptr_t)type, (intptr_t)exec, (intptr_t)signature }
+ { "M" symbol, (intptr_t)type, (intptr_t)exec, (intptr_t)signature }
#define GB_INHERITS(symbol) \
- { GB_INHERITS_ID, (intptr_t)symbol }
-
+ { GB_INHERITS_ID, (intptr_t)symbol }
+
#define GB_INTERFACE(symbol, pointer) \
- { "C_@" symbol, (intptr_t)"p", (intptr_t)pointer }
+ { "C_@" symbol, (intptr_t)"p", (intptr_t)pointer }
/* Method implementation begin macro */
#define BEGIN_METHOD(_name, par) \
typedef \
- struct { \
- par; \
- } \
- _##_name; \
+ struct { \
+ par; \
+ } \
+ _##_name; \
\
void _name(void *_object, void *_param) \
{ \
- _##_name *_p = (_##_name *)_param;
+_##_name *_p = (_##_name *)_param;
/* Parameter-less Method implementation begin macro */
@@ -487,27 +487,27 @@ void _name(void *_object, void *_param) {
/* Structure used for describing a class */
typedef
- struct {
- const char *name;
- intptr_t val1;
- intptr_t val2;
- intptr_t val3;
- intptr_t val4;
- intptr_t val5;
- }
- GB_DESC;
+ struct {
+ const char *name;
+ intptr_t val1;
+ intptr_t val2;
+ intptr_t val3;
+ intptr_t val4;
+ intptr_t val5;
+ }
+ GB_DESC;
/* Type of a method implementation function */
typedef
- void GB_METHOD_FUNC(void *, void *);
+ void GB_METHOD_FUNC(void *, void *);
/* Type of a property implementation function */
typedef
- void GB_PROPERTY_FUNC(void *, void *);
+ void GB_PROPERTY_FUNC(void *, void *);
/* Macro for declaring a method implementation function */
@@ -553,19 +553,19 @@ typedef
/* Type of a watch callback function */
typedef
- void (*GB_WATCH_CALLBACK)(int, int, intptr_t);
+ void (*GB_WATCH_CALLBACK)(int, int, intptr_t);
/* Type of the GB.SubstString() callback */
typedef
- void (*GB_SUBST_CALLBACK)(int, char **, int *);
+ void (*GB_SUBST_CALLBACK)(int, char **, int *);
/* Type of the GB.SubstStringAdd() callback */
typedef
- void (*GB_SUBST_ADD_CALLBACK)(int);
+ void (*GB_SUBST_ADD_CALLBACK)(int);
/* Type of a posted function */
@@ -577,27 +577,27 @@ typedef
/* A structure for the components of a date */
typedef
- struct {
- short year;
- short month;
- short day;
- short hour;
- short min;
- short sec;
- short weekday;
- short msec;
- }
- GB_DATE_SERIAL;
+ struct {
+ short year;
+ short month;
+ short day;
+ short hour;
+ short min;
+ short sec;
+ short weekday;
+ short msec;
+ }
+ GB_DATE_SERIAL;
/* Opaque type of a Gambas interpreted or native function */
typedef
- struct {
- void *object;
- void *desc;
- }
- GB_FUNCTION;
+ struct {
+ void *object;
+ void *desc;
+ }
+ GB_FUNCTION;
#define GB_FUNCTION_IS_VALID(_func) ((_func)->desc)
@@ -605,19 +605,19 @@ typedef
/* Opaque type of a Gambas Array */
typedef
- void *GB_ARRAY;
+ void *GB_ARRAY;
/* Opaque type of a Gambas Collection */
typedef
- void *GB_COLLECTION;
+ void *GB_COLLECTION;
/* opaque type of an hash table */
typedef
- void *GB_HASHTABLE;
+ void *GB_HASHTABLE;
/* constants used by image data format */
@@ -639,7 +639,7 @@ typedef
/* opaque type of a Gambas image */
typedef
- void *GB_IMAGE;
+ void *GB_IMAGE;
/* information about an image */
@@ -657,7 +657,7 @@ typedef
/* opaque type of a Gambas picture */
typedef
- void *GB_PICTURE;
+ void *GB_PICTURE;
/* information about a picture */
@@ -669,7 +669,7 @@ typedef
/* hash table enumeration function */
typedef
- void (*GB_HASHTABLE_ENUM_FUNC)(void *);
+ void (*GB_HASHTABLE_ENUM_FUNC)(void *);
/* opaque type for a Stream object */
@@ -677,42 +677,42 @@ typedef
struct GB_STREAM;
typedef
- struct {
- int (*open)(struct GB_STREAM *stream, const char *path, int mode, void *data);
- int (*close)(struct GB_STREAM *stream);
- int (*read)(struct GB_STREAM *stream, char *buffer, int len);
- int (*getchar)(struct GB_STREAM *stream, char *buffer);
- int (*write)(struct GB_STREAM *stream, char *buffer, int len);
- int (*seek)(struct GB_STREAM *stream, int64_t pos, int whence);
- int (*tell)(struct GB_STREAM *stream, int64_t *pos);
- int (*flush)(struct GB_STREAM *stream);
- int (*eof)(struct GB_STREAM *stream);
- int (*lof)(struct GB_STREAM *stream, int64_t *len);
- int (*handle)(struct GB_STREAM *stream);
- }
- GB_STREAM_DESC;
+ struct {
+ int (*open)(struct GB_STREAM *stream, const char *path, int mode, void *data);
+ int (*close)(struct GB_STREAM *stream);
+ int (*read)(struct GB_STREAM *stream, char *buffer, int len);
+ int (*getchar)(struct GB_STREAM *stream, char *buffer);
+ int (*write)(struct GB_STREAM *stream, char *buffer, int len);
+ int (*seek)(struct GB_STREAM *stream, int64_t pos, int whence);
+ int (*tell)(struct GB_STREAM *stream, int64_t *pos);
+ int (*flush)(struct GB_STREAM *stream);
+ int (*eof)(struct GB_STREAM *stream);
+ int (*lof)(struct GB_STREAM *stream, int64_t *len);
+ int (*handle)(struct GB_STREAM *stream);
+ }
+ GB_STREAM_DESC;
typedef
- struct {
- GB_STREAM_DESC *desc;
- intptr_t _reserved;
- int64_t _reserved2;
- }
- GB_STREAM_BASE;
+ struct {
+ GB_STREAM_DESC *desc;
+ intptr_t _reserved;
+ int64_t _reserved2;
+ }
+ GB_STREAM_BASE;
typedef
- struct GB_STREAM {
- GB_STREAM_DESC *desc;
- intptr_t _reserved;
- int64_t _reserved2;
- void *tag;
- #if __WORDSIZE == 64
- int _free[4];
- #else
- int _free[5];
- #endif
- }
- GB_STREAM;
+ struct GB_STREAM {
+ GB_STREAM_DESC *desc;
+ intptr_t _reserved;
+ int64_t _reserved2;
+ void *tag;
+ #if __WORDSIZE == 64
+ int _free[4];
+ #else
+ int _free[5];
+ #endif
+ }
+ GB_STREAM;
/* Constants used by the GB.NumberFromString() API function */
@@ -735,268 +735,273 @@ typedef
/* Opaque type for a SubCollection object */
typedef
- void *GB_SUBCOLLECTION;
+ void *GB_SUBCOLLECTION;
/* SubCollection description */
typedef
- struct {
- char *klass;
- void *(*get)(void *, const char *);
- int (*exist)(void *, const char *);
- void (*list)(void *, char ***);
- void (*release)(void *, void *);
- }
- GB_SUBCOLLECTION_DESC;
+ struct {
+ char *klass;
+ void *(*get)(void *, const char *);
+ int (*exist)(void *, const char *);
+ void (*list)(void *, char ***);
+ void (*release)(void *, void *);
+ }
+ GB_SUBCOLLECTION_DESC;
/* Timer object */
typedef
- struct {
- GB_BASE object;
- intptr_t id;
- intptr_t tag;
- int delay;
- }
- GB_TIMER;
+ struct {
+ GB_BASE object;
+ intptr_t id;
+ intptr_t tag;
+ int delay;
+ }
+ GB_TIMER;
/* A macro for preventing gcc from warning about breaks in the
strict aliasing rules */
-
+
#define POINTER(_pointer) (void **)(void *)_pointer
-
/* Gambas Application Programming Interface */
typedef
- struct {
- intptr_t version;
+ struct {
+ intptr_t version;
- int (*GetInterface)(const char *, int, void *);
+ int (*GetInterface)(const char *, int, void *);
- void *(*Hook)(int, void *);
+ void *(*Hook)(int, void *);
- int (*LoadComponent)(const char *);
- int (*ExistComponent)(const char *);
- char *(*CurrentComponent)(void);
- int (*GetComponentInfo)(const char *, void **);
+ int (*LoadComponent)(const char *);
+ int (*ExistComponent)(const char *);
+ char *(*CurrentComponent)(void);
+ int (*GetComponentInfo)(const char *, void **);
- void (*Push)(int, ...);
- int (*GetFunction)(GB_FUNCTION *, void *, const char *, const char *, const char *);
- GB_VALUE *(*Call)(GB_FUNCTION *, int, int);
- void *(*GetClassInterface)(GB_CLASS, const char *);
+ void (*Push)(int, ...);
+ int (*GetFunction)(GB_FUNCTION *, void *, const char *, const char *, const char *);
+ GB_VALUE *(*Call)(GB_FUNCTION *, int, int);
+ void *(*GetClassInterface)(GB_CLASS, const char *);
int (*Loop)(int);
- void (*Post)(void (*)(), intptr_t);
- void (*Post2)(void (*)(), intptr_t, intptr_t);
- int (*Raise)(void *, int, int, ...);
- void (*RaiseLater)(void *, int);
- void (*CheckPost)(void);
- int (*CanRaise)(void *, int);
- int (*GetEvent)(GB_CLASS, const char *);
- char *(*GetLastEventName)();
- void (*RaiseTimer)(void *);
- int (*Stopped)(void);
- void (*Signal)(int, void *);
+ void (*Post)(void (*)(), intptr_t);
+ void (*Post2)(void (*)(), intptr_t, intptr_t);
+ int (*Raise)(void *, int, int, ...);
+ void (*RaiseLater)(void *, int);
+ void (*CheckPost)(void);
+ int (*CanRaise)(void *, int);
+ int (*GetEvent)(GB_CLASS, const char *);
+ char *(*GetLastEventName)();
+ void (*RaiseTimer)(void *);
+ int (*Stopped)(void);
+ void (*Signal)(int, void *);
- int (*NParam)(void);
- int (*Conv)(GB_VALUE *, GB_TYPE);
- char *(*GetUnknown)(void);
- int (*IsProperty)(void);
+ int (*NParam)(void);
+ int (*Conv)(GB_VALUE *, GB_TYPE);
+ char *(*GetUnknown)(void);
+ int (*IsProperty)(void);
- void (*Error)(const char *, ...);
- void (*Propagate)(void);
+ void (*Error)(const char *, ...);
+ void (*Propagate)(void);
- GB_CLASS (*GetClass)(void *);
- char *(*GetClassName)(void *);
- int (*ExistClass)(const char *);
- GB_CLASS (*FindClass)(const char *);
- int (*ExistClassLocal)(const char *);
- GB_CLASS (*FindClassLocal)(const char *);
- int (*Is)(void *, GB_CLASS);
- void (*Ref)(void *);
- void (*Unref)(void **);
- void (*UnrefKeep)(void **, int);
- void (*Detach)(void *);
- void (*Attach)(void *, void *, const char *);
- void *(*Parent)(void *);
- int (*New)(void **, GB_CLASS, char *, void *);
- void *(*AutoCreate)(GB_CLASS, int);
- int (*CheckObject)(void *);
+ GB_CLASS (*GetClass)(void *);
+ char *(*GetClassName)(void *);
+ int (*ExistClass)(const char *);
+ GB_CLASS (*FindClass)(const char *);
+ int (*ExistClassLocal)(const char *);
+ GB_CLASS (*FindClassLocal)(const char *);
+ int (*Is)(void *, GB_CLASS);
+ void (*Ref)(void *);
+ void (*Unref)(void **);
+ void (*UnrefKeep)(void **, int);
+ void (*Detach)(void *);
+ void (*Attach)(void *, void *, const char *);
+ void *(*Parent)(void *);
+ int (*New)(void **, GB_CLASS, char *, void *);
+ void *(*AutoCreate)(GB_CLASS, int);
+ int (*CheckObject)(void *);
- void *(*GetEnum)();
- void (*StopEnum)();
- void (*ListEnum)(void *);
- int (*NextEnum)();
- void (*StopAllEnum)(void *);
+ void *(*GetEnum)();
+ void (*StopEnum)();
+ void (*ListEnum)(void *);
+ int (*NextEnum)();
+ void (*StopAllEnum)(void *);
- void (*Return)(GB_TYPE, ...);
- void (*ReturnInteger)(int);
- void (*ReturnLong)(int64_t);
- void (*ReturnPointer)(void *);
- void (*ReturnBoolean)(int);
- void (*ReturnDate)(GB_DATE *);
- void (*ReturnObject)(void *);
- void (*ReturnNull)(void);
- void (*ReturnFloat)(double);
- void (*ReturnPtr)(GB_TYPE, void *);
- void (*ReturnSelf)(void *);
+ void (*Return)(GB_TYPE, ...);
+ void (*ReturnInteger)(int);
+ void (*ReturnLong)(int64_t);
+ void (*ReturnPointer)(void *);
+ void (*ReturnBoolean)(int);
+ void (*ReturnDate)(GB_DATE *);
+ void (*ReturnObject)(void *);
+ void (*ReturnNull)(void);
+ void (*ReturnFloat)(double);
+ void (*ReturnPtr)(GB_TYPE, void *);
+ void (*ReturnSelf)(void *);
- void (*ReturnString)(char *);
- void (*ReturnConstString)(const char *, int);
- void (*ReturnConstZeroString)(const char *);
- void (*ReturnNewString)(const char *, int);
- void (*ReturnNewZeroString)(const char *);
+ void (*ReturnString)(char *);
+ void (*ReturnConstString)(const char *, int);
+ void (*ReturnConstZeroString)(const char *);
+ void (*ReturnNewString)(const char *, int);
+ void (*ReturnNewZeroString)(const char *);
- void (*NewString)(char **, const char *, int);
- void (*TempString)(char **, const char *, int);
- void (*FreeString)(char **);
- void (*ExtendString)(char **, int);
- void (*AddString)(char **, const char *, int);
- int (*StringLength)(char *);
- char *(*ToZeroString)(GB_STRING *);
- int (*MatchString)(const char *, int, const char *, int);
- int (*NumberFromString)(int, const char *, int, GB_VALUE *);
- int (*NumberToString)(int, double, const char *, char **, int *);
- char *(*Translate)(const char *);
+ void (*NewString)(char **, const char *, int);
+ void (*TempString)(char **, const char *, int);
+ void (*FreeString)(char **);
+ void (*ExtendString)(char **, int);
+ void (*AddString)(char **, const char *, int);
+ int (*StringLength)(char *);
+ char *(*ToZeroString)(GB_STRING *);
+ int (*MatchString)(const char *, int, const char *, int);
+ int (*NumberFromString)(int, const char *, int, GB_VALUE *);
+ int (*NumberToString)(int, double, const char *, char **, int *);
+ char *(*Translate)(const char *);
- char *(*SubstString)(const char *, int, GB_SUBST_CALLBACK);
- char *(*SubstStringAdd)(const char *, int, GB_SUBST_ADD_CALLBACK);
- void (*SubstAdd)(const char *, int);
- int (*ConvString)(char **, const char *, int, const char *, const char *);
- char *(*FileName)(char *, int);
- char *(*RealFileName)(char *, int);
+ char *(*SubstString)(const char *, int, GB_SUBST_CALLBACK);
+ char *(*SubstStringAdd)(const char *, int, GB_SUBST_ADD_CALLBACK);
+ void (*SubstAddCallback)(const char *, int);
+ int (*ConvString)(char **, const char *, int, const char *, const char *);
+ char *(*FileName)(char *, int);
+ char *(*RealFileName)(char *, int);
- int (*LoadFile)(const char *, int, char **, int *);
- void (*ReleaseFile)(char **, int);
- int (*ExistFile)(char *);
- char *(*GetTempDir)(void);
+ int (*LoadFile)(const char *, int, char **, int *);
+ void (*ReleaseFile)(char **, int);
+ int (*ExistFile)(char *);
+ char *(*GetTempDir)(void);
- void (*Store)(GB_TYPE, GB_VALUE *, void *);
- void (*StoreString)(GB_STRING *, char **);
- void (*StoreObject)(GB_OBJECT *, void **);
- void (*StoreVariant)(GB_VARIANT *, void *);
+ void (*Store)(GB_TYPE, GB_VALUE *, void *);
+ void (*StoreString)(GB_STRING *, char **);
+ void (*StoreObject)(GB_OBJECT *, void **);
+ void (*StoreVariant)(GB_VARIANT *, void *);
- GB_DATE_SERIAL *(*SplitDate)(GB_DATE *);
- int (*MakeDate)(GB_DATE_SERIAL *, GB_DATE *);
- void (*MakeDateFromTime)(int, int, GB_DATE *);
- int (*GetTime)(double *, int);
+ GB_DATE_SERIAL *(*SplitDate)(GB_DATE *);
+ int (*MakeDate)(GB_DATE_SERIAL *, GB_DATE *);
+ void (*MakeDateFromTime)(int, int, GB_DATE *);
+ int (*GetTime)(double *, int);
- void (*Watch)(int, int, void *, intptr_t);
+ void (*Watch)(int, int, void *, intptr_t);
- GB_VALUE *(*Eval)(void *, void *);
+ GB_VALUE *(*Eval)(void *, void *);
- void (*Alloc)(void **, int);
- void (*Free)(void **);
- void (*Realloc)(void **, int);
+ void (*Alloc)(void **, int);
+ void (*Free)(void **);
+ void (*Realloc)(void **, int);
- void (*NewArray)(void *, int, int);
- void (*FreeArray)(void *);
- int (*Count)(void *);
- void *(*Add)(void *);
- void *(*Insert)(void *, int, int);
- void (*Remove)(void *, int, int);
+ void (*NewArray)(void *, int, int);
+ void (*FreeArray)(void *);
+ int (*Count)(void *);
+ void *(*Add)(void *);
+ void *(*Insert)(void *, int, int);
+ void (*Remove)(void *, int, int);
- void (*PrintData)(GB_TYPE, void *);
- void (*PrintString)(char *, int);
+ void (*PrintData)(GB_TYPE, void *);
+ void (*PrintString)(char *, int);
- struct {
- void (*New)(GB_SUBCOLLECTION *, GB_SUBCOLLECTION_DESC *, void *);
- void (*Add)(void *, const char *, int, void *);
- void (*Remove)(void *, const char *, int);
- void *(*Get)(void *, const char *, int);
- void *(*Container)(void *);
- }
- SubCollection;
+ struct {
+ void (*New)(GB_SUBCOLLECTION *, GB_SUBCOLLECTION_DESC *, void *);
+ void (*Add)(void *, const char *, int, void *);
+ void (*Remove)(void *, const char *, int);
+ void *(*Get)(void *, const char *, int);
+ void *(*Container)(void *);
+ }
+ SubCollection;
- int (*ToLower)(int);
- int (*ToUpper)(int);
- int (*StrCaseCmp)(const char *, const char *);
- int (*StrNCaseCmp)(const char *, const char *, int);
+ int (*ToLower)(int);
+ int (*ToUpper)(int);
+ int (*StrCaseCmp)(const char *, const char *);
+ int (*StrNCaseCmp)(const char *, const char *, int);
- struct {
- char *(*Name)(void);
- char *(*Title)(void);
- char *(*Version)(void);
- char *(*Path)(void);
- char *(*Startup)(void);
- }
- Application;
+ struct {
+ char *(*Name)(void);
+ char *(*Title)(void);
+ char *(*Version)(void);
+ char *(*Path)(void);
+ char *(*Startup)(void);
+ }
+ Application;
- struct {
- char *(*Charset)(void);
- char *(*Language)(void);
- char *(*DomainName)(void);
- int *(*IsRightToLeft)(void);
- }
- System;
+ struct {
+ char *(*Charset)(void);
+ char *(*Language)(void);
+ char *(*DomainName)(void);
+ int *(*IsRightToLeft)(void);
+ }
+ System;
- struct {
- void (*New)(GB_ARRAY *, GB_TYPE, int);
- int (*Count)(GB_ARRAY);
- void *(*Add)(GB_ARRAY);
- void *(*Get)(GB_ARRAY, int);
- GB_TYPE (*Type)(GB_ARRAY);
- }
- Array;
+ struct {
+ void (*New)(GB_ARRAY *, GB_TYPE, int);
+ int (*Count)(GB_ARRAY);
+ void *(*Add)(GB_ARRAY);
+ void *(*Get)(GB_ARRAY, int);
+ GB_TYPE (*Type)(GB_ARRAY);
+ }
+ Array;
- struct {
- void (*New)(GB_COLLECTION *, int);
- int (*Count)(GB_COLLECTION);
- void (*Set)(GB_COLLECTION, const char *, int, GB_VARIANT *);
- int (*Get)(GB_COLLECTION, const char *, int, GB_VARIANT *);
- }
- Collection;
+ struct {
+ void (*New)(GB_COLLECTION *, int);
+ int (*Count)(GB_COLLECTION);
+ void (*Set)(GB_COLLECTION, const char *, int, GB_VARIANT *);
+ int (*Get)(GB_COLLECTION, const char *, int, GB_VARIANT *);
+ }
+ Collection;
- struct {
- void (*New)(GB_HASHTABLE *, int);
- void (*Free)(GB_HASHTABLE *);
- int (*Count)(GB_HASHTABLE);
- void (*Add)(GB_HASHTABLE, const char *, int, void *);
- void (*Remove)(GB_HASHTABLE, const char *, int);
- int (*Get)(GB_HASHTABLE, const char *, int, void **);
- void (*Enum)(GB_HASHTABLE, GB_HASHTABLE_ENUM_FUNC);
- }
- HashTable;
+ struct {
+ void (*New)(GB_HASHTABLE *, int);
+ void (*Free)(GB_HASHTABLE *);
+ int (*Count)(GB_HASHTABLE);
+ void (*Add)(GB_HASHTABLE, const char *, int, void *);
+ void (*Remove)(GB_HASHTABLE, const char *, int);
+ int (*Get)(GB_HASHTABLE, const char *, int, void **);
+ void (*Enum)(GB_HASHTABLE, GB_HASHTABLE_ENUM_FUNC);
+ }
+ HashTable;
- struct {
- void (*SetBytesRead)(GB_STREAM *stream, int length);
- void (*SetSwapping)(GB_STREAM *stream, int swap);
- int (*Block)(GB_STREAM *stream, int block);
- }
- Stream;
+ struct {
+ void (*SetBytesRead)(GB_STREAM *stream, int length);
+ void (*SetSwapping)(GB_STREAM *stream, int swap);
+ int (*Block)(GB_STREAM *stream, int block);
+ }
+ Stream;
struct {
int (*Create)(GB_IMAGE *image, void *data, int width, int height, int format);
void (*Info)(GB_IMAGE image, GB_IMAGE_INFO *info);
void (*Convert)(void *dst, int dst_format, void *src, int src_format, int w, int h);
- }
+ }
Image;
struct {
int (*Create)(GB_PICTURE *pict, void *data, int width, int height, int format);
void (*Info)(GB_PICTURE pict, GB_PICTURE_INFO *info);
- }
+ }
Picture;
-
- }
- GB_INTERFACE;
+
+ struct {
+ void (*Start)(int length);
+ char *(*End)();
+ void (*Add)(const char *src, int len);
+ }
+ String;
+ }
+ GB_INTERFACE;
/*
Special methods that can be declared in a class
- _get array reading operator
- _put array writing operator
- _new constructor
- _free destructor
- _next next iteration of an enumeration
- _call called when the object or the class is used as a function
- _unknown called when the name of the property or method is unknown
+ _get array reading operator
+ _put array writing operator
+ _new constructor
+ _free destructor
+ _next next iteration of an enumeration
+ _call called when the object or the class is used as a function
+ _unknown called when the name of the property or method is unknown
*/
@@ -1004,24 +1009,25 @@ typedef
Syntax of a method or event signature
- Gambas datatype String representation
+ Gambas datatype String representation
- BOOLEAN b
- INTEGER i
- LONG l
- FLOAT f
- DATE d
- STRING s
- VARIANT v
- OBJECT o
- Any class ClassName;
+ BOOLEAN b
+ INTEGER i
+ LONG l
+ FLOAT f
+ DATE d
+ STRING s
+ VARIANT v
+ OBJECT o
+ Any class ClassName;
*/
#ifndef NO_GAMBAS_CASE_REPLACEMENT
/* Replacements for case unsensitive comparisons.
- They ensure that case comparison does not use current locale
+ They ensure that case comparison does not use current locale,
+ otherwise Turkish speakers will have problems!
*/
#include