~ubuntu-branches/ubuntu/lucid/9base/lucid

« back to all changes in this revision

Viewing changes to mk/rc.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2006-01-25 15:33:00 UTC
  • Revision ID: james.westby@ubuntu.com-20060125153300-6hh4p9wx8iqqply5
Tags: upstream-2
ImportĀ upstreamĀ versionĀ 2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include        "mk.h"
 
2
 
 
3
/*
 
4
 *      This file contains functions that depend on rc's syntax.  Most
 
5
 *      of the routines extract strings observing rc's escape conventions
 
6
 */
 
7
 
 
8
 
 
9
/*
 
10
 *      skip a token in single quotes.
 
11
 */
 
12
static char *
 
13
squote(char *cp)
 
14
{
 
15
        Rune r;
 
16
        int n;
 
17
 
 
18
        while(*cp){
 
19
                n = chartorune(&r, cp);
 
20
                if(r == '\'') {
 
21
                        n += chartorune(&r, cp+n);
 
22
                        if(r != '\'')
 
23
                                return(cp);
 
24
                }
 
25
                cp += n;
 
26
        }
 
27
        SYNERR(-1);             /* should never occur */
 
28
        fprint(2, "missing closing '\n");
 
29
        return 0;
 
30
}
 
31
 
 
32
/*
 
33
 *      search a string for characters in a pattern set
 
34
 *      characters in quotes and variable generators are escaped
 
35
 */
 
36
char *
 
37
rccharin(char *cp, char *pat)
 
38
{
 
39
        Rune r;
 
40
        int n, vargen;
 
41
 
 
42
        vargen = 0;
 
43
        while(*cp){
 
44
                n = chartorune(&r, cp);
 
45
                switch(r){
 
46
                case '\'':                      /* skip quoted string */
 
47
                        cp = squote(cp+1);      /* n must = 1 */
 
48
                        if(!cp)
 
49
                                return 0;
 
50
                        break;
 
51
                case '$':
 
52
                        if(*(cp+1) == '{')
 
53
                                vargen = 1;
 
54
                        break;
 
55
                case '}':
 
56
                        if(vargen)
 
57
                                vargen = 0;
 
58
                        else if(utfrune(pat, r))
 
59
                                return cp;
 
60
                        break;
 
61
                default:
 
62
                        if(vargen == 0 && utfrune(pat, r))
 
63
                                return cp;
 
64
                        break;
 
65
                }
 
66
                cp += n;
 
67
        }
 
68
        if(vargen){
 
69
                SYNERR(-1);
 
70
                fprint(2, "missing closing } in pattern generator\n");
 
71
        }
 
72
        return 0;
 
73
}
 
74
 
 
75
/*
 
76
 *      extract an escaped token.  Possible escape chars are single-quote,
 
77
 *      double-quote,and backslash.  Only the first is valid for rc. the
 
78
 *      others are just inserted into the receiving buffer.
 
79
 */
 
80
char*
 
81
rcexpandquote(char *s, Rune r, Bufblock *b)
 
82
{
 
83
        if (r != '\'') {
 
84
                rinsert(b, r);
 
85
                return s;
 
86
        }
 
87
 
 
88
        while(*s){
 
89
                s += chartorune(&r, s);
 
90
                if(r == '\'') {
 
91
                        if(*s == '\'')
 
92
                                s++;
 
93
                        else
 
94
                                return s;
 
95
                }
 
96
                rinsert(b, r);
 
97
        }
 
98
        return 0;
 
99
}
 
100
 
 
101
/*
 
102
 *      Input an escaped token.  Possible escape chars are single-quote,
 
103
 *      double-quote and backslash.  Only the first is a valid escape for
 
104
 *      rc; the others are just inserted into the receiving buffer.
 
105
 */
 
106
int
 
107
rcescapetoken(Biobuf *bp, Bufblock *buf, int preserve, int esc)
 
108
{
 
109
        int c, line;
 
110
 
 
111
        if(esc != '\'')
 
112
                return 1;
 
113
 
 
114
        line = mkinline;
 
115
        while((c = nextrune(bp, 0)) > 0){
 
116
                if(c == '\''){
 
117
                        if(preserve)
 
118
                                rinsert(buf, c);
 
119
                        c = Bgetrune(bp);
 
120
                        if (c < 0)
 
121
                                break;
 
122
                        if(c != '\''){
 
123
                                Bungetrune(bp);
 
124
                                return 1;
 
125
                        }
 
126
                }
 
127
                rinsert(buf, c);
 
128
        }
 
129
        SYNERR(line); fprint(2, "missing closing %c\n", esc);
 
130
        return 0;
 
131
}
 
132
 
 
133
/*
 
134
 *      copy a single-quoted string; s points to char after opening quote
 
135
 */
 
136
static char *
 
137
copysingle(char *s, Bufblock *buf)
 
138
{
 
139
        Rune r;
 
140
 
 
141
        while(*s){
 
142
                s += chartorune(&r, s);
 
143
                rinsert(buf, r);
 
144
                if(r == '\'')
 
145
                        break;
 
146
        }
 
147
        return s;
 
148
}
 
149
/*
 
150
 *      check for quoted strings.  backquotes are handled here; single quotes above.
 
151
 *      s points to char after opening quote, q.
 
152
 */
 
153
char *
 
154
rccopyq(char *s, Rune q, Bufblock *buf)
 
155
{
 
156
        if(q == '\'')                           /* copy quoted string */
 
157
                return copysingle(s, buf);
 
158
 
 
159
        if(q != '`')                            /* not quoted */
 
160
                return s;
 
161
 
 
162
        while(*s){                              /* copy backquoted string */
 
163
                s += chartorune(&q, s);
 
164
                rinsert(buf, q);
 
165
                if(q == '}')
 
166
                        break;
 
167
                if(q == '\'')
 
168
                        s = copysingle(s, buf); /* copy quoted string */
 
169
        }
 
170
        return s;
 
171
}
 
172
 
 
173
static int
 
174
rcmatchname(char *name)
 
175
{
 
176
        char *p;
 
177
 
 
178
        if((p = strchr(name, '/')) != nil)
 
179
                name = p+1;
 
180
        if(name[0] == 'r' && name[1] == 'c')
 
181
                return 1;
 
182
        return 0;
 
183
}
 
184
 
 
185
Shell rcshell = {
 
186
        "rc",
 
187
        "'= \t",
 
188
        '\1',
 
189
        rccharin,
 
190
        rcexpandquote,
 
191
        rcescapetoken,
 
192
        rccopyq,
 
193
        rcmatchname,
 
194
};