SF.net SVN: geany:[3184] trunk
eht16 at users.sourceforge.net
eht16 at xxxxx
Fri Nov 7 14:37:17 UTC 2008
Revision: 3184
http://geany.svn.sourceforge.net/geany/?rev=3184&view=rev
Author: eht16
Date: 2008-11-07 14:37:17 +0000 (Fri, 07 Nov 2008)
Log Message:
-----------
Add support for updating tags from a memory buffer (code merged from Anjuta).
This still doesn't work and is currently disabled. It would only work for a few filetypes like C, Fortran and JavaScript.
The current implementation is still buggy, e.g. function signature parsing is broken.
Modified Paths:
--------------
trunk/src/document.c
trunk/tagmanager/c.c
trunk/tagmanager/entry.c
trunk/tagmanager/entry.h
trunk/tagmanager/fortran.c
trunk/tagmanager/get.c
trunk/tagmanager/get.h
trunk/tagmanager/include/tm_project.h
trunk/tagmanager/js.c
trunk/tagmanager/read.c
trunk/tagmanager/read.h
trunk/tagmanager/sql.c
trunk/tagmanager/tm_source_file.c
trunk/tagmanager/tm_tag.c
Modified: trunk/src/document.c
===================================================================
--- trunk/src/document.c 2008-11-07 05:20:43 UTC (rev 3183)
+++ trunk/src/document.c 2008-11-07 14:37:17 UTC (rev 3184)
@@ -99,6 +99,7 @@
static void document_undo_clear(GeanyDocument *doc);
static void document_redo_add(GeanyDocument *doc, guint type, gpointer data);
+static gboolean update_tags_from_buffer(GeanyDocument *doc);
/* ignore the case of filenames and paths under WIN32, causes errors if not */
@@ -975,6 +976,25 @@
}
+#if 0
+static gboolean auto_update_tag_list(gpointer data)
+{
+ GeanyDocument *doc = data;
+
+ if (! doc || ! doc->is_valid || doc->tm_file == NULL)
+ return FALSE;
+
+ if (gtk_window_get_focus(GTK_WINDOW(main_widgets.window)) != GTK_WIDGET(doc->editor->sci))
+ return TRUE;
+
+ if (update_tags_from_buffer(doc))
+ treeviews_update_tag_list(doc, TRUE);
+
+ return TRUE;
+}
+#endif
+
+
/* To open a new file, set doc to NULL; filename should be locale encoded.
* To reload a file, set the doc for the document to be reloaded; filename should be NULL.
* pos is the cursor position, which can be overridden by --line and --column.
@@ -990,10 +1010,6 @@
GeanyFiletype *use_ft;
FileData filedata;
- /*struct timeval tv, tv1;*/
- /*struct timezone tz;*/
- /*gettimeofday(&tv, &tz);*/
-
if (reload)
{
utf8_filename = g_strdup(doc->file_name);
@@ -1123,9 +1139,11 @@
g_free(utf8_filename);
g_free(locale_filename);
- /*gettimeofday(&tv1, &tz);*/
- /*geany_debug("%s: %d", filename, (gint)(tv1.tv_usec - tv.tv_usec)); */
+ /* TODO This could be used to automatically update the symbol list,
+ * based on a configurable interval */
+ /*g_timeout_add(10000, auto_update_tag_list, doc);*/
+
return doc;
}
@@ -1532,10 +1550,10 @@
document_set_filetype(doc, doc->file_type);
tm_workspace_update(TM_WORK_OBJECT(app->tm_workspace), TRUE, TRUE, FALSE);
- {
- gtk_label_set_text(GTK_LABEL(doc->priv->tab_label), base_name);
- gtk_label_set_text(GTK_LABEL(doc->priv->tabmenu_label), base_name);
- }
+
+ gtk_label_set_text(GTK_LABEL(doc->priv->tab_label), base_name);
+ gtk_label_set_text(GTK_LABEL(doc->priv->tabmenu_label), base_name);
+
msgwin_status_add(_("File %s saved."), doc->file_name);
ui_update_statusbar(doc, -1);
g_free(base_name);
@@ -1972,6 +1990,26 @@
}
+static gboolean update_tags_from_buffer(GeanyDocument *doc)
+{
+ gboolean result;
+#if 1
+ /* old code */
+ result = tm_source_file_update(doc->tm_file, TRUE, FALSE, TRUE);
+#else
+ gsize len = sci_get_length(doc->editor->sci) + 1;
+ gchar *text = g_malloc(len);
+
+ /* we copy the whole text into memory instead using a direct char pointer from
+ * Scintilla because tm_source_file_buffer_update() does modify the string slightly */
+ sci_get_text(doc->editor->sci, len, text);
+ result = tm_source_file_buffer_update(doc->tm_file, (guchar*) text, len, TRUE);
+ g_free(text);
+#endif
+ return result;
+}
+
+
void document_update_tag_list(GeanyDocument *doc, gboolean update)
{
/* We must call treeviews_update_tag_list() before returning,
@@ -2006,14 +2044,14 @@
else
{
if (update)
- tm_source_file_update(doc->tm_file, TRUE, FALSE, TRUE);
+ update_tags_from_buffer(doc);
success = TRUE;
}
}
}
else
{
- success = tm_source_file_update(doc->tm_file, TRUE, FALSE, TRUE);
+ success = update_tags_from_buffer(doc);
if (! success)
geany_debug("tag list updating failed");
}
Modified: trunk/tagmanager/c.c
===================================================================
--- trunk/tagmanager/c.c 2008-11-07 05:20:43 UTC (rev 3183)
+++ trunk/tagmanager/c.c 2008-11-07 14:37:17 UTC (rev 3184)
@@ -169,6 +169,7 @@
vString* name; /* the name of the token */
unsigned long lineNumber; /* line number of tag */
fpos_t filePosition; /* file position of line containing name */
+ int bufferPosition; /* buffer position of line containing name */
} tokenInfo;
typedef enum eImplementation {
@@ -506,7 +507,10 @@
token->type = TOKEN_NONE;
token->keyword = KEYWORD_NONE;
token->lineNumber = getSourceLineNumber ();
- token->filePosition = getInputFilePosition ();
+ if (useFile())
+ token->filePosition = getInputFilePosition ();
+ else
+ token->bufferPosition = getInputBufferPosition ();
vStringClear (token->name);
}
@@ -1057,8 +1061,16 @@
tag->extensionFields.access = accessField (st);
}
if ((TRUE == st->gotArgs) && (TRUE == Option.extensionFields.argList) &&
- ((TAG_FUNCTION == type) || (TAG_METHOD == type) || (TAG_PROTOTYPE == type))) {
- tag->extensionFields.arglist = getArglistFromPos(tag->filePosition, tag->name);
+ ((TAG_FUNCTION == type) || (TAG_METHOD == type) || (TAG_PROTOTYPE == type)))
+ {
+ if (useFile()) {
+ tag->extensionFields.arglist = getArglistFromFilePos(
+ tag->filePosition, tag->name);
+ }
+ else {
+ tag->extensionFields.arglist = getArglistFromBufferPos(
+ tag->bufferPosition, tag->name);
+ }
}
break;
}
@@ -1233,8 +1245,11 @@
initTagEntry (&e, vStringValue (token->name));
e.lineNumber = token->lineNumber;
- e.filePosition = token->filePosition;
- e.isFileScope = isFileScope;
+ if (useFile())
+ e.filePosition = token->filePosition;
+ else
+ e.bufferPosition = token->bufferPosition;
+ e.isFileScope = isFileScope;
e.kindName = tagName (type);
e.kind = tagLetter (type);
e.type = type;
@@ -1688,7 +1703,10 @@
{
dest->type = src->type;
dest->keyword = src->keyword;
- dest->filePosition = src->filePosition;
+ if (useFile())
+ dest->filePosition = src->filePosition;
+ else
+ dest->bufferPosition = src->bufferPosition;
dest->lineNumber = src->lineNumber;
vStringCopy (dest->name, src->name);
}
@@ -2199,7 +2217,14 @@
--depth;
}
if (st->argEndPosition == 0)
- st->argEndPosition = ftell(File.fp);
+ {
+ if (useFile())
+ st->argEndPosition = ftell(File.fp);
+ else
+ /* FIXME File.fpBufferPosition is wrong here, this breaks function signatures and
+ * so Geany's calltips */
+ st->argEndPosition = File.fpBufferPosition;
+ }
if (! info->isNameCandidate)
initToken (token);
Modified: trunk/tagmanager/entry.c
===================================================================
--- trunk/tagmanager/entry.c 2008-11-07 05:20:43 UTC (rev 3183)
+++ trunk/tagmanager/entry.c 2008-11-07 14:37:17 UTC (rev 3184)
@@ -403,6 +403,7 @@
e->lineNumber = getSourceLineNumber ();
e->language = getSourceLanguageName ();
e->filePosition = getInputFilePosition ();
+ e->bufferPosition = getInputBufferPosition ();
e->sourceFileName = getSourceFileTagPath ();
e->name = name;
}
Modified: trunk/tagmanager/entry.h
===================================================================
--- trunk/tagmanager/entry.h 2008-11-07 05:20:43 UTC (rev 3183)
+++ trunk/tagmanager/entry.h 2008-11-07 14:37:17 UTC (rev 3184)
@@ -56,6 +56,7 @@
boolean lineNumberEntry;/* pattern or line number entry */
unsigned long lineNumber; /* line number of tag */
fpos_t filePosition; /* file position of line containing tag */
+ int bufferPosition; /* buffer position of line containing tag */
const char* language; /* language of source file */
boolean isFileScope; /* is tag visibile only within source file? */
boolean isFileEntry; /* is this just an entry for a file name? */
Modified: trunk/tagmanager/fortran.c
===================================================================
--- trunk/tagmanager/fortran.c 2008-11-07 05:20:43 UTC (rev 3183)
+++ trunk/tagmanager/fortran.c 2008-11-07 14:37:17 UTC (rev 3184)
@@ -155,6 +155,7 @@
vString* string;
unsigned long lineNumber;
fpos_t filePosition;
+ int bufferPosition; /* buffer position of line containing name */
} tokenInfo;
/*
@@ -350,7 +351,10 @@
e.lineNumberEntry = (boolean) (Option.locate != EX_PATTERN);
e.lineNumber = token->lineNumber;
- e.filePosition = token->filePosition;
+ if (useFile())
+ e.filePosition = token->filePosition;
+ else
+ e.bufferPosition = token->bufferPosition;
e.isFileScope = isFileScope (token->tag);
e.kindName = FortranKinds [token->tag].name;
e.kind = FortranKinds [token->tag].letter;
@@ -390,7 +394,10 @@
token.tag = TAG_LABEL;
token.string = label;
token.lineNumber = getSourceLineNumber ();
- token.filePosition = getInputFilePosition ();
+ if (useFile())
+ token.filePosition = getInputFilePosition ();
+ else
+ token.bufferPosition = getInputBufferPosition ();
makeFortranTag (&token, TAG_LABEL);
}
@@ -728,7 +735,10 @@
token->tag = TAG_UNDEFINED;
token->string = vStringNew ();
token->lineNumber = getSourceLineNumber ();
- token->filePosition = getInputFilePosition ();
+ if (useFile())
+ token->filePosition = getInputFilePosition ();
+ else
+ token->bufferPosition = getInputBufferPosition ();
return token;
}
@@ -797,7 +807,10 @@
getNextChar:
token->lineNumber = getSourceLineNumber ();
- token->filePosition = getInputFilePosition ();
+ if (useFile())
+ token->filePosition = getInputFilePosition ();
+ else
+ token->bufferPosition = getInputBufferPosition ();
c = getChar ();
Modified: trunk/tagmanager/get.c
===================================================================
--- trunk/tagmanager/get.c 2008-11-07 05:20:43 UTC (rev 3183)
+++ trunk/tagmanager/get.c 2008-11-07 14:37:17 UTC (rev 3184)
@@ -313,8 +313,16 @@
e.kindName = "macro";
e.kind = 'd';
if (parameterized)
- e.extensionFields.arglist = getArglistFromPos(getInputFilePosition()
- , e.name);
+ {
+ if (useFile()) {
+ e.extensionFields.arglist = getArglistFromFilePos(getInputFilePosition()
+ , e.name);
+ }
+ else {
+ e.extensionFields.arglist = getArglistFromBufferPos(getInputBufferPosition()
+ , e.name);
+ }
+ }
makeTagEntry (&e);
if (parameterized)
free((char *) e.extensionFields.arglist);
@@ -676,16 +684,52 @@
return c;
}
-extern char *getArglistFromPos(fpos_t startPosition, const char *tokenName)
+extern char *getArglistFromBufferPos(int startPosition, const char *tokenName)
{
+ int bufferOriginalPosition;
+ char *result = NULL;
+ char *arglist = NULL;
+ long pos1, pos2;
+
+ /* FIXME startPosition as well as getBufPos() are mostly wrong here */
+ pos2 = getBufPos();
+
+ if (!useFile()) {
+ bufferOriginalPosition = getBufPos ();
+ setBufPos(startPosition);
+ pos1 = File.fpBufferPosition;
+ }
+ else
+ return NULL;
+
+ if (pos2 > pos1)
+ {
+ result = (char *) g_malloc(sizeof(char ) * (pos2 - pos1 + 2));
+ if (result != NULL)
+ {
+ memcpy(result, &File.fpBuffer[getBufPos()], pos2 - pos1 + 1);
+ result[pos2-pos1+1] = '\0';
+ arglist = getArglistFromStr(result, tokenName);
+ free(result);
+ }
+ }
+ setBufPos (bufferOriginalPosition);
+ return arglist;
+}
+
+extern char *getArglistFromFilePos(fpos_t startPosition, const char *tokenName)
+{
fpos_t originalPosition;
char *result = NULL;
char *arglist = NULL;
- long pos1, pos2 = ftell(File.fp);
+ long pos1, pos2;
+ pos2 = ftell(File.fp);
+
fgetpos(File.fp, &originalPosition);
fsetpos(File.fp, &startPosition);
pos1 = ftell(File.fp);
+
if (pos2 > pos1)
{
result = (char *) g_malloc(sizeof(char ) * (pos2 - pos1 + 2));
Modified: trunk/tagmanager/get.h
===================================================================
--- trunk/tagmanager/get.h 2008-11-07 05:20:43 UTC (rev 3183)
+++ trunk/tagmanager/get.h 2008-11-07 14:37:17 UTC (rev 3184)
@@ -44,7 +44,8 @@
extern void cppUngetc (const int c);
extern int cppGetc (void);
extern int skipOverCComment (void);
-extern char *getArglistFromPos(fpos_t startPosition, const char *tokenName);
+extern char *getArglistFromFilePos(fpos_t startPosition, const char *tokenName);
+extern char *getArglistFromBufferPos(int startPosition, const char *tokenName);
extern char *getArglistFromStr(char *buf, const char *name);
#endif /* _GET_H */
Modified: trunk/tagmanager/include/tm_project.h
===================================================================
--- trunk/tagmanager/include/tm_project.h 2008-11-07 05:20:43 UTC (rev 3183)
+++ trunk/tagmanager/include/tm_project.h 2008-11-07 14:37:17 UTC (rev 3184)
@@ -13,6 +13,7 @@
#include <glib.h>
#include "tm_work_object.h"
+
/*! \file
The TMProject structure and associated functions can be used to group together
related source files in a "project". The update, open and save functions take
@@ -142,6 +143,13 @@
*/
gboolean tm_project_remove_object(TMProject *project, TMWorkObject *w);
+/*! Removes only the project-tags associated with the object. Then resort the project's tags.
+ \param project The project from which the file's tags are to be removed.
+ \param w The member work object (source file) to remove the tags.
+ \return TRUE on success, FALSE on failure
+*/
+gboolean tm_project_remove_tags_from_list(TMProject *project, TMWorkObject *w);
+
/*! Updates the project database and all the source files contained in the
project. All sorting and deduping is lost and should be redone.
\param work_object The project to update.
Modified: trunk/tagmanager/js.c
===================================================================
--- trunk/tagmanager/js.c 2008-11-07 05:20:43 UTC (rev 3183)
+++ trunk/tagmanager/js.c 2008-11-07 14:37:17 UTC (rev 3184)
@@ -110,6 +110,7 @@
fpos_t filePosition;
int nestLevel;
boolean ignoreTag;
+ int bufferPosition; /* buffer position of line containing name */
} tokenInfo;
/*
@@ -197,7 +198,10 @@
token->nestLevel = 0;
token->ignoreTag = FALSE;
token->lineNumber = getSourceLineNumber ();
- token->filePosition = getInputFilePosition ();
+ if (useFile())
+ token->filePosition = getInputFilePosition ();
+ else
+ token->bufferPosition = getInputBufferPosition ();
return token;
}
@@ -353,8 +357,11 @@
{
c = fileGetc ();
token->lineNumber = getSourceLineNumber ();
- token->filePosition = getInputFilePosition ();
- }
+ if (useFile())
+ token->filePosition = getInputFilePosition ();
+ else
+ token->bufferPosition = getInputBufferPosition ();
+ }
while (c == '\t' || c == ' ' || c == '\n');
switch (c)
@@ -377,7 +384,10 @@
token->type = TOKEN_STRING;
parseString (token->string, c);
token->lineNumber = getSourceLineNumber ();
- token->filePosition = getInputFilePosition ();
+ if (useFile())
+ token->filePosition = getInputFilePosition ();
+ else
+ token->bufferPosition = getInputBufferPosition ();
break;
case '\\':
@@ -386,7 +396,10 @@
fileUngetc (c);
token->type = TOKEN_CHARACTER;
token->lineNumber = getSourceLineNumber ();
- token->filePosition = getInputFilePosition ();
+ if (useFile())
+ token->filePosition = getInputFilePosition ();
+ else
+ token->bufferPosition = getInputBufferPosition ();
break;
case '/':
@@ -429,7 +442,10 @@
{
parseIdentifier (token->string, c);
token->lineNumber = getSourceLineNumber ();
- token->filePosition = getInputFilePosition ();
+ if (useFile())
+ token->filePosition = getInputFilePosition ();
+ else
+ token->bufferPosition = getInputBufferPosition ();
token->keyword = analyzeToken (token->string);
if (isKeyword (token, KEYWORD_NONE))
token->type = TOKEN_IDENTIFIER;
@@ -444,7 +460,10 @@
{
dest->nestLevel = src->nestLevel;
dest->lineNumber = src->lineNumber;
- dest->filePosition = src->filePosition;
+ if (useFile())
+ dest->filePosition = src->filePosition;
+ else
+ dest->bufferPosition = src->bufferPosition;
dest->type = src->type;
dest->keyword = src->keyword;
vStringCopy(dest->string, src->string);
Modified: trunk/tagmanager/read.c
===================================================================
--- trunk/tagmanager/read.c 2008-11-07 05:20:43 UTC (rev 3183)
+++ trunk/tagmanager/read.c 2008-11-07 14:37:17 UTC (rev 3184)
@@ -29,7 +29,12 @@
*/
inputFile File; /* globally read through macros */
static fpos_t StartOfLine; /* holds deferred position of start of line */
+static int bufferStartOfLine; /* the same as StartOfLine but for buffer */
+
+static int readNextChar (void);
+static int pushBackChar (int c);
+
/*
* FUNCTION DEFINITIONS
*/
@@ -115,7 +120,7 @@
{
int c;
do
- c = getc (File.fp);
+ c = readNextChar ();
while (c == ' ' || c == '\t');
return c;
}
@@ -127,9 +132,9 @@
while (c != EOF && isdigit (c))
{
lNum = (lNum * 10) + (c - '0');
- c = getc (File.fp);
+ c = readNextChar ();
}
- ungetc (c, File.fp);
+ pushBackChar (c);
if (c != ' ' && c != '\t')
lNum = 0;
@@ -152,17 +157,17 @@
if (c == '"')
{
- c = getc (File.fp); /* skip double-quote */
+ c = readNextChar (); /* skip double-quote */
quoteDelimited = TRUE;
}
while (c != EOF && c != '\n' &&
(quoteDelimited ? (c != '"') : (c != ' ' && c != '\t')))
{
vStringPut (fileName, c);
- c = getc (File.fp);
+ c = readNextChar ();
}
if (c == '\n')
- ungetc (c, File.fp);
+ pushBackChar (c);
vStringPut (fileName, '\0');
return fileName;
@@ -176,13 +181,13 @@
if (isdigit (c))
{
- ungetc (c, File.fp);
+ pushBackChar (c);
result = TRUE;
}
- else if (c == 'l' && getc (File.fp) == 'i' &&
- getc (File.fp) == 'n' && getc (File.fp) == 'e')
+ else if (c == 'l' && readNextChar () == 'i' &&
+ readNextChar () == 'n' && readNextChar () == 'e')
{
- c = getc (File.fp);
+ c = readNextChar ();
if (c == ' ' || c == '\t')
{
DebugStatement ( lineStr = "line"; )
@@ -283,6 +288,60 @@
return opened;
}
+/* The user should take care of allocate and free the buffer param.
+ * This func is NOT THREAD SAFE.
+ * The user should not tamper with the buffer while this func is executing.
+ */
+extern boolean bufferOpen (unsigned char *buffer, int buffer_size,
+ const char *const fileName, const langType language )
+{
+ boolean opened = FALSE;
+
+ /* Check whether a file of a buffer were already open, then close them.
+ */
+ if (File.fp != NULL) {
+ fclose (File.fp); /* close any open source file */
+ File.fp = NULL;
+ }
+
+ if (File.fpBuffer != NULL) {
+ error(PERROR, "An unallocated buffer was found. Please check you called \
+ correctly bufferClose ()\n");
+ File.fpBuffer = NULL;
+ }
+
+ /* check if we got a good buffer */
+ if (buffer == NULL || buffer_size == 0) {
+ opened = FALSE;
+ return opened;
+ }
+
+ opened = TRUE;
+
+ File.fpBuffer = buffer;
+ setInputFileName (fileName);
+ bufferStartOfLine = 0;
+ File.fpBufferPosition = 0;
+ File.fpBufferSize = buffer_size;
+ File.currentLine = NULL;
+ File.language = language;
+ File.lineNumber = 0L;
+ File.eof = FALSE;
+ File.newLine = TRUE;
+
+ if (File.line != NULL)
+ vStringClear (File.line);
+
+ setSourceFileParameters (vStringNewInit (fileName), language);
+ File.source.lineNumber = 0L;
+
+ verbose ("OPENING %s as %s language %sfile\n", fileName,
+ getLanguageName (language),
+ File.source.isHeader ? "include " : "");
+
+ return opened;
+}
+
extern void fileClose (void)
{
if (File.fp != NULL)
@@ -299,6 +358,14 @@
}
}
+/* user should take care of freeing the buffer */
+extern void bufferClose (void)
+{
+ if (File.fpBuffer != NULL) {
+ File.fpBuffer = NULL;
+ }
+}
+
extern boolean fileEOF (void)
{
return File.eof;
@@ -323,7 +390,7 @@
{
int c;
readnext:
- c = getc (File.fp);
+ c = readNextChar ();
/* If previous character was a newline, then we're starting a line.
*/
@@ -336,8 +403,13 @@
goto readnext;
else
{
- fsetpos (File.fp, &StartOfLine);
- c = getc (File.fp);
+ /* FIXME: find out a better way to do this check */
+ if (File.fp != NULL)
+ fsetpos (File.fp, &StartOfLine);
+ else
+ File.fpBufferPosition = bufferStartOfLine;
+
+ c = readNextChar ();
}
}
}
@@ -346,8 +418,10 @@
File.eof = TRUE;
else if (c == NEWLINE)
{
- File.newLine = TRUE;
- fgetpos (File.fp, &StartOfLine);
+ if (File.fp != NULL) /* we have a file */
+ fgetpos (File.fp, &StartOfLine);
+ else /* it's a buffer */
+ bufferStartOfLine = File.fpBufferPosition;
}
else if (c == CRETURN)
{
@@ -355,14 +429,17 @@
* used forms if line breaks: LF (UNIX), CR (MacIntosh), and
* CR-LF (MS-DOS) are converted into a generic newline.
*/
- const int next = getc (File.fp); /* is CR followed by LF? */
+ const int next = readNextChar (); /* is CR followed by LF? */
if (next != NEWLINE)
- ungetc (next, File.fp);
+ pushBackChar (next);
c = NEWLINE; /* convert CR into newline */
File.newLine = TRUE;
- fgetpos (File.fp, &StartOfLine);
+ if (File.fp != NULL)
+ fgetpos (File.fp, &StartOfLine);
+ else
+ bufferStartOfLine = File.fpBufferPosition;
}
DebugStatement ( debugPutc (DEBUG_RAW, c); )
return c;
@@ -457,8 +534,67 @@
return result;
}
+/* Read a character choosing automatically between file or buffer, depending
+ * on which mode we are.
+ */
+static int readNextChar(void)
+{
+ if (File.fp != NULL) {
+ return getc(File.fp);
+ }
+ else {
+ int c;
+ if (File.fpBufferPosition >= File.fpBufferSize)
+ return EOF;
+
+ c = File.fpBuffer[File.fpBufferPosition];
+ File.fpBufferPosition++;
+
+ return c;
+ }
+}
+
+/* Replaces ungetc() for file. In case of buffer we'll perform the same action:
+ * fpBufferPosition-- and write of the param char into the buf.
+ */
+static int pushBackChar (int c)
+{
+ if (File.fp != NULL) {
+ return ungetc (c, File.fp);
+ }
+ else {
+ File.fpBufferPosition--;
+ if (File.fpBufferPosition < 0)
+ return EOF;
+ File.fpBuffer[File.fpBufferPosition] = c;
+ return File.fpBuffer[File.fpBufferPosition];
+ }
+}
+
+
+/* replacement for fsetpos, applied to a buffer */
+extern void setBufPos (int new_position)
+{
+ File.fpBufferPosition = new_position;
+}
+
+/* replacement for fgetpos, applied to a buffer */
+extern int getBufPos (void)
+{
+ return File.fpBufferPosition;
+}
+
+extern boolean useFile (void)
+{
+ if (File.fp != NULL)
+ return TRUE;
+ else
+ return FALSE;
+}
+
/*
* Source file line reading with automatic buffer sizing
+ * Does not perform file/buffer checks. Only file is supported.
*/
extern char *readLine (vString *const vLine, FILE *const fp)
{
Modified: trunk/tagmanager/read.h
===================================================================
--- trunk/tagmanager/read.h 2008-11-07 05:20:43 UTC (rev 3183)
+++ trunk/tagmanager/read.h 2008-11-07 14:37:17 UTC (rev 3184)
@@ -33,6 +33,7 @@
#define getInputLineNumber() File.lineNumber
#define getInputFileName() vStringValue (File.source.name)
#define getInputFilePosition() File.filePosition
+#define getInputBufferPosition() File.fpBufferPosition
#define getSourceFileName() vStringValue (File.source.name)
#define getSourceFileTagPath() File.source.tagPath
#define getSourceLanguage() File.source.language
@@ -73,6 +74,10 @@
vString *line; /* last line read from file */
const unsigned char* currentLine; /* current line being worked on */
FILE *fp; /* stream used for reading the file */
+ unsigned char* fpBuffer; /* buffer which contains the text to be parsed.
+ This is optional to the use of a file-descriptor */
+ int fpBufferSize; /* size of the fpBuffer */
+ int fpBufferPosition; /* pointer to the current position in buffer */
unsigned long lineNumber; /* line number in the input file */
fpos_t filePosition; /* file position of current line */
int ungetch; /* a single character that was ungotten */
@@ -116,6 +121,13 @@
extern char *readLine (vString *const vLine, FILE *const fp);
extern char *readSourceLine (vString *const vLine, fpos_t location, long *const pSeekValue);
+extern boolean bufferOpen (unsigned char *buffer, int buffer_size,
+ const char *const fileName, const langType language );
+extern void bufferClose (void);
+extern void setBufPos (int new_position);
+extern int getBufPos ();
+extern boolean useFile ();
+
#endif /* _READ_H */
/* vi:set tabstop=8 shiftwidth=4: */
Modified: trunk/tagmanager/sql.c
===================================================================
--- trunk/tagmanager/sql.c 2008-11-07 05:20:43 UTC (rev 3183)
+++ trunk/tagmanager/sql.c 2008-11-07 14:37:17 UTC (rev 3184)
@@ -138,6 +138,7 @@
vString * scope;
unsigned long lineNumber;
fpos_t filePosition;
+ int bufferPosition; /* buffer position of line containing name */
} tokenInfo;
/*
@@ -274,30 +275,30 @@
{
if ( isType(token, TOKEN_IDENTIFIER) || isType(token, TOKEN_STRING) )
{
- printf( "\n%s: token string t:%s s:%s l:%lu p:%ld\n"
+ printf( "\n%s: token string t:%s s:%s l:%lu p:%d\n"
, location
, vStringValue(token->string)
, vStringValue(token->scope)
, token->lineNumber
- , token->filePosition
+ , token->bufferPosition
);
} else {
- printf( "\n%s: token t:%d s:%s l:%lu p:%lu\n"
+ printf( "\n%s: token t:%d s:%s l:%lu p:%d\n"
, location
, token->type
, vStringValue(token->scope)
, token->lineNumber
- , token->filePosition
+ , token->bufferPosition
);
}
} else {
- printf( "\n%s: keyword:%s k:%d s:%s l:%lu p:%ld\n"
+ printf( "\n%s: keyword:%s k:%d s:%s l:%lu p:%d\n"
, location
, vStringValue(token->string)
, token->keyword
, vStringValue(token->scope)
, token->lineNumber
- , token->filePosition
+ , token->bufferPosition
);
}
#endif
@@ -391,7 +392,10 @@
initTagEntry (&e, name);
e.lineNumber = token->lineNumber;
- e.filePosition = token->filePosition;
+ if (useFile())
+ e.filePosition = token->filePosition;
+ else
+ e.bufferPosition = token->bufferPosition;
e.kindName = SqlKinds [kind].name;
e.kind = SqlKinds [kind].letter;
@@ -491,7 +495,10 @@
token->type = TOKEN_STRING;
parseString (token->string, c);
token->lineNumber = getSourceLineNumber ();
- token->filePosition = getInputFilePosition ();
+ if (useFile())
+ token->filePosition = getInputFilePosition ();
+ else
+ token->bufferPosition = getInputBufferPosition ();
break;
case '-':
@@ -557,7 +564,10 @@
{
parseIdentifier (token->string, c);
token->lineNumber = getSourceLineNumber ();
- token->filePosition = getInputFilePosition ();
+ if (useFile())
+ token->filePosition = getInputFilePosition ();
+ else
+ token->bufferPosition = getInputBufferPosition ();
token->keyword = analyzeToken (token->string);
if (isKeyword (token, KEYWORD_rem))
{
Modified: trunk/tagmanager/tm_source_file.c
===================================================================
--- trunk/tagmanager/tm_source_file.c 2008-11-07 05:20:43 UTC (rev 3183)
+++ trunk/tagmanager/tm_source_file.c 2008-11-07 14:37:17 UTC (rev 3184)
@@ -29,6 +29,7 @@
#include "tm_source_file.h"
#include "tm_tag.h"
+
guint source_file_class_id = 0;
static TMSourceFile *current_source_file = NULL;
@@ -154,6 +155,76 @@
return status;
}
+gboolean tm_source_file_buffer_parse(TMSourceFile *source_file, guchar* text_buf, gint buf_size)
+{
+ const char *file_name;
+ gboolean status = TRUE;
+
+ if ((NULL == source_file) || (NULL == source_file->work_object.file_name))
+ {
+ g_warning("Attempt to parse NULL file");
+ return FALSE;
+ }
+
+ if ((NULL == text_buf) || (0 == buf_size))
+ {
+ g_warning("Attempt to parse a NULL text buffer");
+ }
+
+ file_name = source_file->work_object.file_name;
+ if (NULL == LanguageTable)
+ {
+ initializeParsing();
+ installLanguageMapDefaults();
+ if (NULL == TagEntryFunction)
+ TagEntryFunction = tm_source_file_tags;
+ }
+ current_source_file = source_file;
+ if (LANG_AUTO == source_file->lang)
+ source_file->lang = getFileLanguage (file_name);
+ if (source_file->lang == LANG_IGNORE)
+ {
+#ifdef TM_DEBUG
+ g_warning("ignoring %s (unknown language)\n", file_name);
+#endif
+ }
+ else if (! LanguageTable [source_file->lang]->enabled)
+ {
+#ifdef TM_DEBUG
+ g_warning("ignoring %s (language disabled)\n", file_name);
+#endif
+ }
+ else
+ {
+ int passCount = 0;
+ while ((TRUE == status) && (passCount < 3))
+ {
+ if (source_file->work_object.tags_array)
+ tm_tags_array_free(source_file->work_object.tags_array, FALSE);
+ if (bufferOpen (text_buf, buf_size, file_name, source_file->lang))
+ {
+ if (LanguageTable [source_file->lang]->parser != NULL)
+ {
+ LanguageTable [source_file->lang]->parser ();
+ bufferClose ();
+ break;
+ }
+ else if (LanguageTable [source_file->lang]->parser2 != NULL)
+ status = LanguageTable [source_file->lang]->parser2 (passCount);
+ bufferClose ();
+ }
+ else
+ {
+ g_warning("Unable to open %s", file_name);
+ return FALSE;
+ }
+ ++ passCount;
+ }
+ return TRUE;
+ }
+ return status;
+}
+
int tm_source_file_tags(const tagEntryInfo *tag)
{
if (NULL == current_source_file)
@@ -179,10 +250,42 @@
}
return TRUE;
}
- else
+ else {
+#ifdef TM_DEBUG
+ g_message ("no parsing of %s has been done", source_file->file_name);
+#endif
return FALSE;
+ }
}
+
+gboolean tm_source_file_buffer_update(TMWorkObject *source_file, guchar* text_buf,
+ gint buf_size, gboolean update_parent)
+{
+#ifdef TM_DEBUG
+ g_message("Buffer updating based on source file %s", source_file->file_name);
+#endif
+
+ tm_source_file_buffer_parse (TM_SOURCE_FILE(source_file), text_buf, buf_size);
+ tm_tags_sort(source_file->tags_array, NULL, FALSE);
+ source_file->analyze_time = time(NULL);
+ if ((source_file->parent) && update_parent)
+ {
+#ifdef TM_DEBUG
+ g_message("Updating parent [project] from buffer..");
+#endif
+ tm_work_object_update(source_file->parent, TRUE, FALSE, TRUE);
+ }
+#ifdef TM_DEBUG
+ else
+ g_message("Skipping parent update because parent is %s and update_parent is %s"
+ , source_file->parent?"NOT NULL":"NULL", update_parent?"TRUE":"FALSE");
+
+#endif
+ return TRUE;
+}
+
+
gboolean tm_source_file_write(TMWorkObject *source_file, FILE *fp, guint attrs)
{
TMTag *tag;
Modified: trunk/tagmanager/tm_tag.c
===================================================================
--- trunk/tagmanager/tm_tag.c 2008-11-07 05:20:43 UTC (rev 3183)
+++ trunk/tagmanager/tm_tag.c 2008-11-07 14:37:17 UTC (rev 3184)
@@ -631,7 +631,7 @@
s_partial = partial;
result = (TMTag **) bsearch(&tag, sorted_tags_array->pdata, sorted_tags_array->len
, sizeof(gpointer), tm_tag_compare);
- /* there can be matches on both sides of result */
+ /* There can be matches on both sides of result */
if (result)
{
TMTag **last = (TMTag **) &sorted_tags_array->pdata[sorted_tags_array->len - 1];
@@ -640,7 +640,7 @@
/* First look for any matches after result */
adv = result;
adv++;
- for (; *adv && adv <= last; ++ adv)
+ for (; adv <= last && *adv; ++ adv)
{
if (0 != tm_tag_compare(&tag, adv))
break;
@@ -654,7 +654,7 @@
++tagMatches;
}
*tagCount=tagMatches;
- ++ result; /* correct address for the last successful match */
+ ++ result; /* Correct address for the last successful match */
}
s_partial = FALSE;
return (TMTag **) result;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Commits
mailing list