1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
3
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
5
* The contents of this file are subject to the Netscape Public License
6
* Version 1.1 (the "License"); you may not use this file except in
7
* compliance with the License. You may obtain a copy of the License at
8
* http://www.mozilla.org/NPL/
10
* Software distributed under the License is distributed on an "AS IS" basis,
11
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
* for the specific language governing rights and limitations under the
15
* The Original Code is mozilla.org code.
17
* The Initial Developer of the Original Code is
18
* Netscape Communications Corporation.
19
* Portions created by the Initial Developer are Copyright (C) 1998
20
* the Initial Developer. All Rights Reserved.
24
* Alternatively, the contents of this file may be used under the terms of
25
* either the GNU General Public License Version 2 or later (the "GPL"), or
26
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27
* in which case the provisions of the GPL or the LGPL are applicable instead
28
* of those above. If you wish to allow use of your version of this file only
29
* under the terms of either the GPL or the LGPL, and not to allow others to
30
* use your version of this file under the terms of the NPL, indicate your
31
* decision by deleting the provisions above and replace them with the notice
32
* and other provisions required by the GPL or the LGPL. If you do not delete
33
* the provisions above, a recipient may use your version of this file under
34
* the terms of any one of the NPL, the GPL or the LGPL.
36
* ***** END LICENSE BLOCK ***** */
39
* JavaScript Debugging support - Source Text functions
46
void JSD_ASSERT_VALID_SOURCE_TEXT(JSDSourceText* jsdsrc)
49
JS_ASSERT(jsdsrc->url);
53
/***************************************************************************/
54
/* XXX add notification */
57
_clearText(JSDContext* jsdc, JSDSourceText* jsdsrc)
62
jsdsrc->textLength = 0;
63
jsdsrc->textSpace = 0;
64
jsdsrc->status = JSD_SOURCE_CLEARED;
65
jsdsrc->dirty = JS_TRUE;
66
jsdsrc->alterCount = jsdc->sourceAlterCount++ ;
67
jsdsrc->doingEval = JS_FALSE;
71
_appendText(JSDContext* jsdc, JSDSourceText* jsdsrc,
72
const char* text, size_t length)
74
#define MEMBUF_GROW 1000
76
uintN neededSize = jsdsrc->textLength + length;
78
if( neededSize > jsdsrc->textSpace )
83
/* if this is the first alloc, the req might be all that's needed*/
84
if( ! jsdsrc->textSpace )
87
iNewSize = (neededSize * 5 / 4) + MEMBUF_GROW;
89
newBuf = (char*) realloc(jsdsrc->text, iNewSize);
92
/* try again with the minimal size really asked for */
93
iNewSize = neededSize;
94
newBuf = (char*) realloc(jsdsrc->text, iNewSize);
98
_clearText( jsdc, jsdsrc );
99
jsdsrc->status = JSD_SOURCE_FAILED;
104
jsdsrc->text = newBuf;
105
jsdsrc->textSpace = iNewSize;
108
memcpy(jsdsrc->text + jsdsrc->textLength, text, length);
109
jsdsrc->textLength += length;
113
static JSDSourceText*
114
_newSource(JSDContext* jsdc, const char* url)
116
JSDSourceText* jsdsrc = (JSDSourceText*)calloc(1,sizeof(JSDSourceText));
120
jsdsrc->url = (char*) url; /* already a copy */
121
jsdsrc->status = JSD_SOURCE_INITED;
122
jsdsrc->dirty = JS_TRUE;
123
jsdsrc->alterCount = jsdc->sourceAlterCount++ ;
129
_destroySource(JSDContext* jsdc, JSDSourceText* jsdsrc)
131
JS_ASSERT(NULL == jsdsrc->text); /* must _clearText() first */
137
_removeSource(JSDContext* jsdc, JSDSourceText* jsdsrc)
139
JS_REMOVE_LINK(&jsdsrc->links);
140
_clearText(jsdc, jsdsrc);
141
_destroySource(jsdc, jsdsrc);
144
static JSDSourceText*
145
_addSource(JSDContext* jsdc, const char* url)
147
JSDSourceText* jsdsrc = _newSource(jsdc, url);
150
JS_INSERT_LINK(&jsdsrc->links, &jsdc->sources);
155
_moveSourceToFront(JSDContext* jsdc, JSDSourceText* jsdsrc)
157
JS_REMOVE_LINK(&jsdsrc->links);
158
JS_INSERT_LINK(&jsdsrc->links, &jsdc->sources);
162
_moveSourceToRemovedList(JSDContext* jsdc, JSDSourceText* jsdsrc)
164
_clearText(jsdc, jsdsrc);
165
JS_REMOVE_LINK(&jsdsrc->links);
166
JS_INSERT_LINK(&jsdsrc->links, &jsdc->removedSources);
170
_removeSourceFromRemovedList( JSDContext* jsdc, JSDSourceText* jsdsrc )
172
JS_REMOVE_LINK(&jsdsrc->links);
173
_destroySource( jsdc, jsdsrc );
177
_isSourceInSourceList(JSDContext* jsdc, JSDSourceText* jsdsrcToFind)
179
JSDSourceText *jsdsrc;
181
for( jsdsrc = (JSDSourceText*)jsdc->sources.next;
182
jsdsrc != (JSDSourceText*)&jsdc->sources;
183
jsdsrc = (JSDSourceText*)jsdsrc->links.next )
185
if( jsdsrc == jsdsrcToFind )
191
/* compare strings in a case insensitive manner with a length limit
195
strncasecomp (const char* one, const char * two, int n)
200
for(pA=one, pB=two;; pA++, pB++)
207
tmp = tolower(*pA) - tolower(*pB);
213
static char file_url_prefix[] = "file:";
214
#define FILE_URL_PREFIX_LEN (sizeof file_url_prefix - 1)
217
jsd_BuildNormalizedURL( const char* url_string )
219
char *new_url_string;
224
if (!strncasecomp(url_string, file_url_prefix, FILE_URL_PREFIX_LEN) &&
225
url_string[FILE_URL_PREFIX_LEN + 0] == '/' &&
226
url_string[FILE_URL_PREFIX_LEN + 1] == '/') {
227
new_url_string = JS_smprintf("%s%s",
229
url_string + FILE_URL_PREFIX_LEN + 2);
231
new_url_string = strdup(url_string);
233
return new_url_string;
236
/***************************************************************************/
239
jsd_DestroyAllSources( JSDContext* jsdc )
241
JSDSourceText *jsdsrc;
244
for( jsdsrc = (JSDSourceText*)jsdc->sources.next;
245
jsdsrc != (JSDSourceText*)&jsdc->sources;
248
next = (JSDSourceText*)jsdsrc->links.next;
249
_removeSource( jsdc, jsdsrc );
252
for( jsdsrc = (JSDSourceText*)jsdc->removedSources.next;
253
jsdsrc != (JSDSourceText*)&jsdc->removedSources;
256
next = (JSDSourceText*)jsdsrc->links.next;
257
_removeSourceFromRemovedList( jsdc, jsdsrc );
263
jsd_IterateSources(JSDContext* jsdc, JSDSourceText **iterp)
265
JSDSourceText *jsdsrc = *iterp;
268
jsdsrc = (JSDSourceText *)jsdc->sources.next;
269
if( jsdsrc == (JSDSourceText *)&jsdc->sources )
271
*iterp = (JSDSourceText *)jsdsrc->links.next;
276
jsd_FindSourceForURL(JSDContext* jsdc, const char* url)
278
JSDSourceText *jsdsrc;
280
for( jsdsrc = (JSDSourceText *)jsdc->sources.next;
281
jsdsrc != (JSDSourceText *)&jsdc->sources;
282
jsdsrc = (JSDSourceText *)jsdsrc->links.next )
284
if( 0 == strcmp(jsdsrc->url, url) )
291
jsd_GetSourceURL(JSDContext* jsdc, JSDSourceText* jsdsrc)
297
jsd_GetSourceText(JSDContext* jsdc, JSDSourceText* jsdsrc,
298
const char** ppBuf, intN* pLen )
300
*ppBuf = jsdsrc->text;
301
*pLen = jsdsrc->textLength;
306
jsd_ClearSourceText(JSDContext* jsdc, JSDSourceText* jsdsrc)
308
if( JSD_SOURCE_INITED != jsdsrc->status &&
309
JSD_SOURCE_PARTIAL != jsdsrc->status )
311
_clearText(jsdc, jsdsrc);
316
jsd_GetSourceStatus(JSDContext* jsdc, JSDSourceText* jsdsrc)
318
return jsdsrc->status;
322
jsd_IsSourceDirty(JSDContext* jsdc, JSDSourceText* jsdsrc)
324
return jsdsrc->dirty;
328
jsd_SetSourceDirty(JSDContext* jsdc, JSDSourceText* jsdsrc, JSBool dirty)
330
jsdsrc->dirty = dirty;
334
jsd_GetSourceAlterCount(JSDContext* jsdc, JSDSourceText* jsdsrc)
336
return jsdsrc->alterCount;
340
jsd_IncrementSourceAlterCount(JSDContext* jsdc, JSDSourceText* jsdsrc)
342
return jsdsrc->alterCount = jsdc->sourceAlterCount++;
345
/***************************************************************************/
347
#if defined(DEBUG) && 0
348
void DEBUG_ITERATE_SOURCES( JSDContext* jsdc )
350
JSDSourceText* iterp = NULL;
351
JSDSourceText* jsdsrc = NULL;
354
while( NULL != (jsdsrc = jsd_IterateSources(jsdc, &iterp)) )
360
JSDStreamStatus status;
363
url = JSD_GetSourceURL(jsdc, jsdsrc);
364
dirty = JSD_IsSourceDirty(jsdc, jsdsrc);
365
status = JSD_GetSourceStatus(jsdc, jsdsrc);
366
gotSrc = JSD_GetSourceText(jsdc, jsdsrc, &text, &len );
368
dummy = 0; /* gives us a line to set breakpoint... */
372
#define DEBUG_ITERATE_SOURCES(x) ((void)x)
375
/***************************************************************************/
378
jsd_NewSourceText(JSDContext* jsdc, const char* url)
380
JSDSourceText* jsdsrc;
381
const char* new_url_string;
383
JSD_LOCK_SOURCE_TEXT(jsdc);
386
new_url_string = url; /* we take ownership of alloc'd string */
388
new_url_string = jsd_BuildNormalizedURL(url);
390
if( ! new_url_string )
393
jsdsrc = jsd_FindSourceForURL(jsdc, new_url_string);
397
if( jsdsrc->doingEval )
400
free((char*)new_url_string);
402
JSD_UNLOCK_SOURCE_TEXT(jsdc);
406
_moveSourceToRemovedList(jsdc, jsdsrc);
409
jsdsrc = _addSource( jsdc, new_url_string );
411
JSD_UNLOCK_SOURCE_TEXT(jsdc);
417
jsd_AppendSourceText(JSDContext* jsdc,
418
JSDSourceText* jsdsrc,
419
const char* text, /* *not* zero terminated */
421
JSDSourceStatus status)
423
JSD_LOCK_SOURCE_TEXT(jsdc);
425
if( jsdsrc->doingEval )
427
JSD_UNLOCK_SOURCE_TEXT(jsdc);
431
if( ! _isSourceInSourceList( jsdc, jsdsrc ) )
433
_removeSourceFromRemovedList( jsdc, jsdsrc );
434
JSD_UNLOCK_SOURCE_TEXT(jsdc);
438
if( text && length && ! _appendText( jsdc, jsdsrc, text, length ) )
440
jsdsrc->dirty = JS_TRUE;
441
jsdsrc->alterCount = jsdc->sourceAlterCount++ ;
442
jsdsrc->status = JSD_SOURCE_FAILED;
443
_moveSourceToRemovedList(jsdc, jsdsrc);
444
JSD_UNLOCK_SOURCE_TEXT(jsdc);
448
jsdsrc->dirty = JS_TRUE;
449
jsdsrc->alterCount = jsdc->sourceAlterCount++ ;
450
jsdsrc->status = status;
451
DEBUG_ITERATE_SOURCES(jsdc);
452
JSD_UNLOCK_SOURCE_TEXT(jsdc);
457
jsd_AppendUCSourceText(JSDContext* jsdc,
458
JSDSourceText* jsdsrc,
459
const jschar* text, /* *not* zero terminated */
461
JSDSourceStatus status)
463
#define UNICODE_TRUNCATE_BUF_SIZE 1024
464
static char* buf = NULL;
465
int remaining = length;
468
return jsd_AppendSourceText(jsdc, jsdsrc, NULL, 0, status);
470
JSD_LOCK_SOURCE_TEXT(jsdc);
473
buf = malloc(UNICODE_TRUNCATE_BUF_SIZE);
476
JSD_UNLOCK_SOURCE_TEXT(jsdc);
480
while(remaining && jsdsrc) {
481
int bytes = JS_MIN(remaining, UNICODE_TRUNCATE_BUF_SIZE);
483
for(i = 0; i < bytes; i++)
484
buf[i] = (const char) *(text++);
485
jsdsrc = jsd_AppendSourceText(jsdc,jsdsrc,
490
if(jsdsrc && status != JSD_SOURCE_PARTIAL)
491
jsdsrc = jsd_AppendSourceText(jsdc, jsdsrc, NULL, 0, status);
493
JSD_UNLOCK_SOURCE_TEXT(jsdc);
497
/* convienence function for adding complete source of url in one call */
499
jsd_AddFullSourceText(JSDContext* jsdc,
500
const char* text, /* *not* zero terminated */
504
JSDSourceText* jsdsrc;
506
JSD_LOCK_SOURCE_TEXT(jsdc);
508
jsdsrc = jsd_NewSourceText(jsdc, url);
510
jsdsrc = jsd_AppendSourceText(jsdc, jsdsrc,
511
text, length, JSD_SOURCE_PARTIAL );
513
jsdsrc = jsd_AppendSourceText(jsdc, jsdsrc,
514
NULL, 0, JSD_SOURCE_COMPLETED );
516
JSD_UNLOCK_SOURCE_TEXT(jsdc);
518
return jsdsrc ? JS_TRUE : JS_FALSE;
521
/***************************************************************************/
524
jsd_StartingEvalUsingFilename(JSDContext* jsdc, const char* url)
526
JSDSourceText* jsdsrc;
528
/* NOTE: We leave it locked! */
529
JSD_LOCK_SOURCE_TEXT(jsdc);
531
jsdsrc = jsd_FindSourceForURL(jsdc, url);
535
#ifndef JSD_LOWLEVEL_SOURCE
536
JS_ASSERT(! jsdsrc->doingEval);
539
jsdsrc->doingEval = JS_TRUE;
544
jsd_FinishedEvalUsingFilename(JSDContext* jsdc, const char* url)
546
JSDSourceText* jsdsrc;
548
/* NOTE: We ASSUME it is locked! */
550
jsdsrc = jsd_FindSourceForURL(jsdc, url);
554
#ifndef JSD_LOWLEVEL_SOURCE
556
* when using this low level source addition, this jsdsrc might
557
* not have existed before the eval, but does exist now (without
560
JS_ASSERT(jsdsrc->doingEval);
563
jsdsrc->doingEval = JS_FALSE;
566
JSD_UNLOCK_SOURCE_TEXT(jsdc);