]> gcc.gnu.org Git - gcc.git/blame - libgfortran/runtime/select.c
Merge tree-ssa-20020619-branch into mainline.
[gcc.git] / libgfortran / runtime / select.c
CommitLineData
6de9cd9a
DN
1/* Implement the SELECT statement for character variables.
2 Contributed by Andy Vaught
3
4This file is part of the GNU Fortran 95 runtime library (libgfor).
5
6Libgfor is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11Libgfor is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with libgfor; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21#include "libgfortran.h"
22
23typedef struct
24{
25 char *low;
26 int low_len;
27 char *high;
28 int high_len;
29 void *address;
30}
31select_struct;
32
33
34#define select_string prefix(select_string)
35
36
37/* select_string()-- Given a selector string and a table of
38 * select_struct structures, return the address to jump to. */
39
40void *select_string (select_struct *table, int table_len, void *default_jump,
41 const char *selector, int selector_len)
42{
43 select_struct *t;
44 int i, low, high, mid;
45
46 if (table_len == 0)
47 return default_jump;
48
49 /* Record the default address if present */
50
51 if (table->low == NULL && table->high == NULL)
52 {
53 default_jump = table->address;
54
55 table++;
56 table_len--;
57 if (table_len == 0)
58 return default_jump;
59 }
60
61 /* Try the high and low bounds if present. */
62
63 if (table->low == NULL)
64 {
65 if (compare_string (table->high_len, table->high,
66 selector_len, selector) >= 0)
67 return table->address;
68
69 table++;
70 table_len--;
71 if (table_len == 0)
72 return default_jump;
73 }
74
75 t = table + table_len - 1;
76
77 if (t->high == NULL)
78 {
79 if (compare_string (t->low_len, t->low,
80 selector_len, selector) <= 0)
81 return t->address;
82
83 table_len--;
84 if (table_len == 0)
85 return default_jump;
86 }
87
88 /* At this point, the only table entries are bounded entries. Find
89 the right entry with a binary chop. */
90
91 low = -1;
92 high = table_len;
93
94 while (low + 1 < high)
95 {
96 mid = (low + high) / 2;
97
98 t = table + mid;
99 i = compare_string (t->low_len, t->low, selector_len, selector);
100
101 if (i == 0)
102 return t->address;
103
104 if (i < 0)
105 low = mid;
106 else
107 high = mid;
108 }
109
110 /* The string now lies between the low indeces of the now-adjacent
111 high and low entries. Because it is less than the low entry of
112 'high', it can't be that one. If low is still -1, then no
113 entries match. Otherwise, we have to check the high entry of
114 'low'. */
115
116 if (low == -1)
117 return default_jump;
118
119 t = table + low;
120 if (compare_string (selector_len, selector,
121 t->high_len, t->high) <= 0)
122 return t->address;
123
124 return default_jump;
125}
This page took 0.045956 seconds and 5 git commands to generate.