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