1/* The contents of this file are subject to the Netscape Public
2 * License Version 1.1 (the "License"); you may not use this file
3 * except in compliance with the License. You may obtain a copy of
4 * the License at http://www.mozilla.org/NPL/
5 *
6 * Software distributed under the License is distributed on an "AS
7 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
8 * implied. See the License for the specific language governing
9 * rights and limitations under the License.
10 *
11 * The Original Code is Mozilla Communicator client code, released March
12 * 31, 1998.
13 *
14 * The Initial Developer of the Original Code is Netscape Communications
15 * Corporation. Portions created by Netscape are
16 * Copyright (C) 1998 Netscape Communications Corporation. All
17 * Rights Reserved.
18 *
19 * Contributor(s):
20 *
21 */
22/**
23    File Name:          15.5.4.7-3.js
24    ECMA Section:       15.5.4.7 String.prototype.lastIndexOf( searchString, pos)
25    Description:
26
27    If the given searchString appears as a substring of the result of
28    converting this object to a string, at one or more positions that are
29    at or to the left of the specified position, then the index of the
30    rightmost such position is returned; otherwise -1 is returned. If position
31    is undefined or not supplied, the length of this string value is assumed,
32    so as to search all of the string.
33
34    When the lastIndexOf method is called with two arguments searchString and
35    position, the following steps are taken:
36
37   1.Call ToString, giving it the this value as its argument.
38   2.Call ToString(searchString).
39   3.Call ToNumber(position). (If position is undefined or not supplied, this step produces the value NaN).
40   4.If Result(3) is NaN, use +; otherwise, call ToInteger(Result(3)).
41   5.Compute the number of characters in Result(1).
42   6.Compute min(max(Result(4), 0), Result(5)).
43   7.Compute the number of characters in the string that is Result(2).
44   8.Compute the largest possible integer k not larger than Result(6) such that k+Result(7) is not greater
45      than Result(5), and for all nonnegative integers j less than Result(7), the character at position k+j of
46      Result(1) is the same as the character at position j of Result(2); but if there is no such integer k, then
47      compute the value -1.
48
49   1.Return Result(8).
50
51    Note that the lastIndexOf function is intentionally generic; it does not require that its this value be a
52    String object. Therefore it can be transferred to other kinds of objects for use as a method.
53
54    Author:             christine@netscape.com
55    Date:               2 october 1997
56*/
57    var SECTION = "15.5.4.7-3";
58    var VERSION = "ECMA_2";
59    startTest();
60    var TITLE   = "String.protoype.lastIndexOf";
61
62    writeHeaderToLog( SECTION + " "+ TITLE);
63
64    var testcases = getTestCases();
65    test();
66
67
68function getTestCases() {
69    var array = new Array();
70    var item = 0;
71
72    array[item++] = new TestCase(   SECTION,
73                                    "var b = true; b.__proto__.lastIndexOf = String.prototype.lastIndexOf; b.lastIndexOf('r', 0 )",
74                                    -1,
75                                    eval("var b = true; b.__proto__.lastIndexOf = String.prototype.lastIndexOf; b.lastIndexOf('r', 0 )") );
76
77    array[item++] = new TestCase(   SECTION,
78                                    "var b = true; b.__proto__.lastIndexOf = String.prototype.lastIndexOf; b.lastIndexOf('r', 1 )",
79                                    1,
80                                    eval("var b = true; b.__proto__.lastIndexOf = String.prototype.lastIndexOf; b.lastIndexOf('r', 1 )") );
81
82    array[item++] = new TestCase(   SECTION,
83                                    "var b = true; b.__proto__.lastIndexOf = String.prototype.lastIndexOf; b.lastIndexOf('r', 2 )",
84                                    1,
85                                    eval("var b = true; b.__proto__.lastIndexOf = String.prototype.lastIndexOf; b.lastIndexOf('r', 2 )") );
86
87    array[item++] = new TestCase(   SECTION,
88                                    "var b = true; b.__proto__.lastIndexOf = String.prototype.lastIndexOf; b.lastIndexOf('r', 10 )",
89                                    1,
90                                    eval("var b = true; b.__proto__.lastIndexOf = String.prototype.lastIndexOf; b.lastIndexOf('r', 10 )") );
91
92    array[item++] = new TestCase(   SECTION,
93                                    "var b = true; b.__proto__.lastIndexOf = String.prototype.lastIndexOf; b.lastIndexOf('r' )",
94                                    1,
95                                    eval("var b = true; b.__proto__.lastIndexOf = String.prototype.lastIndexOf; b.lastIndexOf('r' )") );
96
97    return array;
98}
99
100function test() {
101    for ( tc = 0; tc < testcases.length; tc++ ) {
102
103        testcases[tc].passed = writeTestCaseResult(
104                    testcases[tc].expect,
105                    testcases[tc].actual,
106                    testcases[tc].description +" = "+ testcases[tc].actual );
107
108        testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value "
109    }
110    stopTest();
111
112    return ( testcases );
113}
114
115function LastIndexOf( string, search, position ) {
116    string = String( string );
117    search = String( search );
118
119    position = Number( position )
120
121    if ( isNaN( position ) ) {
122        position = Infinity;
123    } else {
124        position = ToInteger( position );
125    }
126
127    result5= string.length;
128    result6 = Math.min(Math.max(position, 0), result5);
129    result7 = search.length;
130
131    if (result7 == 0) {
132        return Math.min(position, result5);
133    }
134
135    result8 = -1;
136
137    for ( k = 0; k <= result6; k++ ) {
138        if ( k+ result7 > result5 ) {
139            break;
140        }
141        for ( j = 0; j < result7; j++ ) {
142            if ( string.charAt(k+j) != search.charAt(j) ){
143                break;
144            }   else  {
145                if ( j == result7 -1 ) {
146                    result8 = k;
147                }
148            }
149        }
150    }
151
152    return result8;
153}
154function ToInteger( n ) {
155    n = Number( n );
156    if ( isNaN(n) ) {
157        return 0;
158    }
159    if ( Math.abs(n) == 0 || Math.abs(n) == Infinity ) {
160        return n;
161    }
162
163    var sign = ( n < 0 ) ? -1 : 1;
164
165    return ( sign * Math.floor(Math.abs(n)) );
166}