OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [userland/] [sh/] [sh4.c] - Blame information for rev 199

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
#define Extern extern
2
#include <sys/types.h>
3
#include <sys/stat.h>
4
#include <dirent.h>
5
#include <limits.h>
6
#include <signal.h>
7
#include <stdio.h>
8
 
9
#include <errno.h>
10
#include <setjmp.h>
11
#include "sh.h"
12
 
13
/* -------- eval.c -------- */
14
/* #include "sh.h" */
15
/* #include "word.h" */
16
 
17
/*
18
 * ${}
19
 * `command`
20
 * blank interpretation
21
 * quoting
22
 * glob
23
 */
24
 
25
static int expand (char *cp, struct wdblock **wbp, int f );
26
static char *blank(int f );
27
static int dollar(int quoted );
28
static int grave(int quoted );
29
void globname (char *we, char *pp );
30
static char *generate (char *start1, char *end1, char *middle, char *end );
31
static int anyspcl(struct wdblock *wb );
32
static int xstrcmp (char *p1, char *p2 );
33
void glob0 (char *a0, unsigned int a1, int a2, int (*a3)(char *, char *));
34
void glob1 (char *base, char *lim );
35
void glob2 (char *i, char *j );
36
void glob3 (char *i, char *j, char *k );
37
char *memcopy (char *ato, char *from, int nb );
38
 
39
char ** eval( char **ap, int f)
40
{
41
        struct wdblock *wb;
42
        char **wp;
43
        char **wf;
44
        jmp_buf ev;
45
 
46
        wp = NULL;
47
        wb = NULL;
48
        wf = NULL;
49
        if (newenv(setjmp(errpt = ev)) == 0) {
50
                while (*ap && isassign(*ap))
51
                        expand(*ap++, &wb, f & ~DOGLOB);
52
                if (flag['k']) {
53
                        for (wf = ap; *wf; wf++) {
54
                                if (isassign(*wf))
55
                                        expand(*wf, &wb, f & ~DOGLOB);
56
                        }
57
                }
58
                for (wb = addword((char *)0, wb); *ap; ap++) {
59
                        if (!flag['k'] || !isassign(*ap))
60
                                expand(*ap, &wb, f & ~DOKEY);
61
                }
62
                wb = addword((char *)0, wb);
63
                wp = getwords(wb);
64
                quitenv();
65
        } else
66
                gflg = 1;
67
        return(gflg? (char **)NULL: wp);
68
}
69
 
70
/*
71
 * Make the exported environment from the exported
72
 * names in the dictionary. Keyword assignments
73
 * will already have been done.
74
 */
75
char **
76
makenv()
77
 
78
{
79
        register struct wdblock *wb;
80
        register struct var *vp;
81
 
82
        wb = NULL;
83
        for (vp = vlist; vp; vp = vp->next)
84
                if (vp->status & EXPORT)
85
                        wb = addword(vp->name, wb);
86
        wb = addword((char *)0, wb);
87
        return(getwords(wb));
88
}
89
 
90
char *
91
evalstr(cp, f)
92
register char *cp;
93
int f;
94
{
95
        struct wdblock *wb;
96
 
97
        wb = NULL;
98
        if (expand(cp, &wb, f)) {
99
                if (wb == NULL || wb->w_nword == 0 || (cp = wb->w_words[0]) == NULL)
100
                        cp = "";
101
                DELETE(wb);
102
        } else
103
                cp = NULL;
104
        return(cp);
105
}
106
 
107
static int
108
expand( char *cp, register struct wdblock **wbp, int f)
109
{
110
        jmp_buf ev;
111
 
112
        gflg = 0;
113
        if (cp == NULL)
114
                return(0);
115
        if (!anys("$`'\"", cp) &&
116
            !anys(ifs->value, cp) &&
117
            ((f&DOGLOB)==0 || !anys("[*?", cp))) {
118
                cp = strsave(cp, areanum);
119
                if (f & DOTRIM)
120
                        unquote(cp);
121
                *wbp = addword(cp, *wbp);
122
                return(1);
123
        }
124
        if (newenv(setjmp(errpt = ev)) == 0) {
125
                PUSHIO(aword, cp, strchar);
126
                e.iobase = e.iop;
127
                while ((cp = blank(f)) && gflg == 0) {
128
                        e.linep = cp;
129
                        cp = strsave(cp, areanum);
130
                        if ((f&DOGLOB) == 0) {
131
                                if (f & DOTRIM)
132
                                        unquote(cp);
133
                                *wbp = addword(cp, *wbp);
134
                        } else
135
                                *wbp = glob(cp, *wbp);
136
                }
137
                quitenv();
138
        } else
139
                gflg = 1;
140
        return(gflg == 0);
141
}
142
 
143
/*
144
 * Blank interpretation and quoting
145
 */
146
static char *
147
blank(f)
148
int f;
149
{
150
        register int c, c1;
151
        register char *sp;
152
        int scanequals, foundequals;
153
 
154
        sp = e.linep;
155
        scanequals = f & DOKEY;
156
        foundequals = 0;
157
 
158
loop:
159
        switch (c = subgetc('"', foundequals)) {
160
        case 0:
161
                if (sp == e.linep)
162
                        return(0);
163
                *e.linep++ = 0;
164
                return(sp);
165
 
166
        default:
167
                if (f & DOBLANK && any(c, ifs->value))
168
                        goto loop;
169
                break;
170
 
171
        case '"':
172
        case '\'':
173
                scanequals = 0;
174
                if (INSUB())
175
                        break;
176
                for (c1 = c; (c = subgetc(c1, 1)) != c1;) {
177
                        if (c == 0)
178
                                break;
179
                        if (c == '\'' || !any(c, "$`\""))
180
                                c |= QUOTE;
181
                        *e.linep++ = c;
182
                }
183
                c = 0;
184
        }
185
        unget(c);
186
        if (!letter(c))
187
                scanequals = 0;
188
        for (;;) {
189
                c = subgetc('"', foundequals);
190
                if (c == 0 ||
191
                    f & (DOBLANK && any(c, ifs->value)) ||
192
                    (!INSUB() && any(c, "\"'"))) {
193
                        scanequals = 0;
194
                        unget(c);
195
                        if (any(c, "\"'"))
196
                                goto loop;
197
                        break;
198
                }
199
                if (scanequals) {
200
                        if (c == '=') {
201
                                foundequals = 1;
202
                                scanequals  = 0;
203
                        }
204
                        else if (!letnum(c))
205
                                scanequals = 0;
206
                }
207
                *e.linep++ = c;
208
        }
209
        *e.linep++ = 0;
210
        return(sp);
211
}
212
 
213
/*
214
 * Get characters, substituting for ` and $
215
 */
216
int
217
subgetc(ec, quoted)
218
register int ec;
219
int quoted;
220
{
221
        register char c;
222
 
223
again:
224
        c = my_getc(ec);
225
        if (!INSUB() && ec != '\'') {
226
                if (c == '`') {
227
                        if (grave(quoted) == 0)
228
                                return(0);
229
                        e.iop->task = XGRAVE;
230
                        goto again;
231
                }
232
                if (c == '$' && (c = dollar(quoted)) == 0) {
233
                        e.iop->task = XDOLL;
234
                        goto again;
235
                }
236
        }
237
        return(c);
238
}
239
 
240
/*
241
 * Prepare to generate the string returned by ${} substitution.
242
 */
243
static int
244
dollar(quoted)
245
int quoted;
246
{
247
        int otask;
248
        struct io *oiop;
249
        char *dolp;
250
        register char *s, c, *cp=NULL;
251
        struct var *vp;
252
 
253
        c = readc();
254
        s = e.linep;
255
        if (c != '{') {
256
                *e.linep++ = c;
257
                if (letter(c)) {
258
                        while ((c = readc())!=0 && letnum(c))
259
                                if (e.linep < elinep)
260
                                        *e.linep++ = c;
261
                        unget(c);
262
                }
263
                c = 0;
264
        } else {
265
                oiop = e.iop;
266
                otask = e.iop->task;
267
                e.iop->task = XOTHER;
268
                while ((c = subgetc('"', 0))!=0 && c!='}' && c!='\n')
269
                        if (e.linep < elinep)
270
                                *e.linep++ = c;
271
                if (oiop == e.iop)
272
                        e.iop->task = otask;
273
                if (c != '}') {
274
                        err("unclosed ${");
275
                        gflg++;
276
                        return(c);
277
                }
278
        }
279
        if (e.linep >= elinep) {
280
                err("string in ${} too long");
281
                gflg++;
282
                e.linep -= 10;
283
        }
284
        *e.linep = 0;
285
        if (*s)
286
                for (cp = s+1; *cp; cp++)
287
                        if (any(*cp, "=-+?")) {
288
                                c = *cp;
289
                                *cp++ = 0;
290
                                break;
291
                        }
292
        if (s[1] == 0 && (*s == '*' || *s == '@')) {
293
                if (dolc > 1) {
294
                        /* currently this does not distinguish $* and $@ */
295
                        /* should check dollar */
296
                        e.linep = s;
297
                        PUSHIO(awordlist, dolv+1, dolchar);
298
                        return(0);
299
                } else {        /* trap the nasty ${=} */
300
                        s[0] = '1';
301
                        s[1] = 0;
302
                }
303
        }
304
        vp = lookup(s);
305
        if ((dolp = vp->value) == null) {
306
                switch (c) {
307
                case '=':
308
                        if (digit(*s)) {
309
                                err("cannot use ${...=...} with $n");
310
                                gflg++;
311
                                break;
312
                        }
313
                        setval(vp, cp);
314
                        dolp = vp->value;
315
                        break;
316
 
317
                case '-':
318
                        dolp = strsave(cp, areanum);
319
                        break;
320
 
321
                case '?':
322
                        if (*cp == 0) {
323
                                prs("missing value for ");
324
                                err(s);
325
                        } else
326
                                err(cp);
327
                        gflg++;
328
                        break;
329
                }
330
        } else if (c == '+')
331
                dolp = strsave(cp, areanum);
332
        if (flag['u'] && dolp == null) {
333
                prs("unset variable: ");
334
                err(s);
335
                gflg++;
336
        }
337
        e.linep = s;
338
        PUSHIO(aword, dolp, quoted ? qstrchar : strchar);
339
        return(0);
340
}
341
 
342
/*
343
 * Run the command in `...` and read its output.
344
 */
345
static int
346
grave(quoted)
347
int quoted;
348
{
349
        register char *cp;
350
        register int i;
351
        int pf[2];
352
 
353
        for (cp = e.iop->argp->aword; *cp != '`'; cp++)
354
                if (*cp == 0) {
355
                        err("no closing `");
356
                        return(0);
357
                }
358
        if (openpipe(pf) < 0)
359
                return(0);
360
        if ((i = vfork()) == -1) {
361
                closepipe(pf);
362
                err("try again");
363
                return(0);
364
        }
365
        if (i != 0) {
366
                e.iop->argp->aword = ++cp;
367
                close(pf[1]);
368
                PUSHIO(afile, remap(pf[0]), quoted? qgravechar: gravechar);
369
                return(1);
370
        }
371
        *cp = 0;
372
        /* allow trapped signals */
373
        for (i=0; i<=_NSIG; i++)
374
                if (ourtrap[i] && signal(i, SIG_IGN) != SIG_IGN)
375
                        signal(i, SIG_DFL);
376
        dup2(pf[1], 1);
377
        closepipe(pf);
378
        flag['e'] = 0;
379
        flag['v'] = 0;
380
        flag['n'] = 0;
381
        cp = strsave(e.iop->argp->aword, 0);
382
        areanum = 1;
383
        freehere(areanum);
384
        freearea(areanum);      /* free old space */
385
        e.oenv = NULL;
386
        e.iop = (e.iobase = iostack) - 1;
387
        unquote(cp);
388
        talking = 0;
389
        PUSHIO(aword, cp, nlchar);
390
        onecommand();
391
        exit(1);
392
}
393
 
394
char *
395
unquote(as)
396
register char *as;
397
{
398
        register char *s;
399
 
400
        if ((s = as) != NULL)
401
                while (*s)
402
                        *s++ &= ~QUOTE;
403
        return(as);
404
}
405
 
406
/* -------- glob.c -------- */
407
/* #include "sh.h" */
408
 
409
/*
410
 * glob
411
 */
412
 
413
#define scopy(x) strsave((x), areanum)
414
#define BLKSIZ  512
415
#define NDENT   ((BLKSIZ+sizeof(struct dirent)-1)/sizeof(struct dirent))
416
 
417
static  struct wdblock  *cl, *nl;
418
static  char    spcl[] = "[?*";
419
 
420
struct wdblock *
421
glob(cp, wb)
422
char *cp;
423
struct wdblock *wb;
424
{
425
        register int i;
426
        register char *pp;
427
 
428
        if (cp == 0)
429
                return(wb);
430
        i = 0;
431
        for (pp = cp; *pp; pp++)
432
                if (any(*pp, spcl))
433
                        i++;
434
                else if (!any(*pp & ~QUOTE, spcl))
435
                        *pp &= ~QUOTE;
436
        if (i != 0) {
437
                for (cl = addword(scopy(cp), (struct wdblock *)0); anyspcl(cl); cl = nl) {
438
                        nl = newword(cl->w_nword*2);
439
                        for(i=0; i<cl->w_nword; i++) { /* for each argument */
440
                                for (pp = cl->w_words[i]; *pp; pp++)
441
                                        if (any(*pp, spcl)) {
442
                                                globname(cl->w_words[i], pp);
443
                                                break;
444
                                        }
445
                                if (*pp == '\0')
446
                                        nl = addword(scopy(cl->w_words[i]), nl);
447
                        }
448
                        for(i=0; i<cl->w_nword; i++)
449
                                DELETE(cl->w_words[i]);
450
                        DELETE(cl);
451
                }
452
                for(i=0; i<cl->w_nword; i++)
453
                        unquote(cl->w_words[i]);
454
                glob0((char *)cl->w_words, cl->w_nword, sizeof(char *), xstrcmp);
455
                if (cl->w_nword) {
456
                        for (i=0; i<cl->w_nword; i++)
457
                                wb = addword(cl->w_words[i], wb);
458
                        DELETE(cl);
459
                        return(wb);
460
                }
461
        }
462
        wb = addword(unquote(cp), wb);
463
        return(wb);
464
}
465
 
466
void
467
globname(we, pp)
468
char *we;
469
register char *pp;
470
{
471
        register char *np, *cp;
472
        char *name, *gp, *dp;
473
        int k;
474
        DIR *dirp;
475
        struct dirent *de;
476
        char dname[NAME_MAX+1];
477
        struct stat dbuf;
478
 
479
        for (np = we; np != pp; pp--)
480
                if (pp[-1] == '/')
481
                        break;
482
        for (dp = cp = space((int)(pp-np)+3); np < pp;)
483
                *cp++ = *np++;
484
        *cp++ = '.';
485
        *cp = '\0';
486
        for (gp = cp = space(strlen(pp)+1); *np && *np != '/';)
487
                *cp++ = *np++;
488
        *cp = '\0';
489
        dirp = opendir(dp);
490
        if (dirp == 0) {
491
                DELETE(dp);
492
                DELETE(gp);
493
                return;
494
        }
495
        dname[NAME_MAX] = '\0';
496
        while ((de=readdir(dirp))!=NULL) {
497
                /* XXX Hmmm... What this could be? (abial) */
498
                /*
499
                if (ent[j].d_ino == 0)
500
                        continue;
501
                */
502
                strncpy(dname, de->d_name, NAME_MAX);
503
                        if (dname[0] == '.')
504
                                if (*gp != '.')
505
                                        continue;
506
                        for(k=0; k<NAME_MAX; k++)
507
                                if (any(dname[k], spcl))
508
                                        dname[k] |= QUOTE;
509
                        if (gmatch(dname, gp)) {
510
                                name = generate(we, pp, dname, np);
511
                                if (*np && !anys(np, spcl)) {
512
                                        if (stat(name,&dbuf)) {
513
                                                DELETE(name);
514
                                                continue;
515
                                        }
516
                                }
517
                                nl = addword(name, nl);
518
                        }
519
        }
520
        closedir(dirp);
521
        DELETE(dp);
522
        DELETE(gp);
523
}
524
 
525
/*
526
 * generate a pathname as below.
527
 * start..end1 / middle end
528
 * the slashes come for free
529
 */
530
static char *
531
generate(start1, end1, middle, end)
532
char *start1;
533
register char *end1;
534
char *middle, *end;
535
{
536
        char *p;
537
        register char *op, *xp;
538
 
539
        p = op = space((int)(end1-start1)+strlen(middle)+strlen(end)+2);
540
        for (xp = start1; xp != end1;)
541
                *op++ = *xp++;
542
        for (xp = middle; (*op++ = *xp++) != '\0';)
543
                ;
544
        op--;
545
        for (xp = end; (*op++ = *xp++) != '\0';)
546
                ;
547
        return(p);
548
}
549
 
550
static int
551
anyspcl(wb)
552
register struct wdblock *wb;
553
{
554
        register int i;
555
        register char **wd;
556
 
557
        wd = wb->w_words;
558
        for (i=0; i<wb->w_nword; i++)
559
                if (anys(spcl, *wd++))
560
                        return(1);
561
        return(0);
562
}
563
 
564
static int
565
xstrcmp(p1, p2)
566
char *p1, *p2;
567
{
568
        return(strcmp(*(char **)p1, *(char **)p2));
569
}
570
 
571
/* -------- word.c -------- */
572
/* #include "sh.h" */
573
/* #include "word.h" */
574
 
575
#define NSTART  16      /* default number of words to allow for initially */
576
 
577
struct wdblock *
578
newword(nw)
579
register int nw;
580
{
581
        register struct wdblock *wb;
582
 
583
        wb = (struct wdblock *) space(sizeof(*wb) + nw*sizeof(char *));
584
        wb->w_bsize = nw;
585
        wb->w_nword = 0;
586
        return(wb);
587
}
588
 
589
struct wdblock *
590
addword(wd, wb)
591
char *wd;
592
register struct wdblock *wb;
593
{
594
        register struct wdblock *wb2;
595
        register int nw;
596
 
597
        if (wb == NULL)
598
                wb = newword(NSTART);
599
        if ((nw = wb->w_nword) >= wb->w_bsize) {
600
                wb2 = newword(nw * 2);
601
                memcopy((char *)wb2->w_words, (char *)wb->w_words, nw*sizeof(char *));
602
                wb2->w_nword = nw;
603
                DELETE(wb);
604
                wb = wb2;
605
        }
606
        wb->w_words[wb->w_nword++] = wd;
607
        return(wb);
608
}
609
 
610
char **
611
getwords(wb)
612
register struct wdblock *wb;
613
{
614
        register char **wd;
615
        register int nb;
616
 
617
        if (wb == NULL)
618
                return((char **)NULL);
619
        if (wb->w_nword == 0) {
620
                DELETE(wb);
621
                return((char **)NULL);
622
        }
623
        wd = (char **) space(nb = sizeof(*wd) * wb->w_nword);
624
        memcopy((char *)wd, (char *)wb->w_words, nb);
625
        DELETE(wb);     /* perhaps should done by caller */
626
        return(wd);
627
}
628
 
629
int (*func)(char *, char *);
630
int     globv;
631
 
632
void
633
glob0(a0, a1, a2, a3)
634
char *a0;
635
unsigned a1;
636
int a2;
637
int (*a3) (char *, char *);
638
{
639
        func = a3;
640
        globv = a2;
641
        glob1(a0, a0 + a1 * a2);
642
}
643
 
644
void
645
glob1(base, lim)
646
char *base, *lim;
647
{
648
        register char *i, *j;
649
        int v2;
650
        char *lptr, *hptr;
651
        int c;
652
        unsigned n;
653
 
654
 
655
        v2 = globv;
656
 
657
top:
658
        if ((n=(int)(lim-base)) <= v2)
659
                return;
660
        n = v2 * (n / (2*v2));
661
        hptr = lptr = base+n;
662
        i = base;
663
        j = lim-v2;
664
        for(;;) {
665
                if (i < lptr) {
666
                        if ((c = (*func)(i, lptr)) == 0) {
667
                                glob2(i, lptr -= v2);
668
                                continue;
669
                        }
670
                        if (c < 0) {
671
                                i += v2;
672
                                continue;
673
                        }
674
                }
675
 
676
begin:
677
                if (j > hptr) {
678
                        if ((c = (*func)(hptr, j)) == 0) {
679
                                glob2(hptr += v2, j);
680
                                goto begin;
681
                        }
682
                        if (c > 0) {
683
                                if (i == lptr) {
684
                                        glob3(i, hptr += v2, j);
685
                                        i = lptr += v2;
686
                                        goto begin;
687
                                }
688
                                glob2(i, j);
689
                                j -= v2;
690
                                i += v2;
691
                                continue;
692
                        }
693
                        j -= v2;
694
                        goto begin;
695
                }
696
 
697
 
698
                if (i == lptr) {
699
                        if (lptr-base >= lim-hptr) {
700
                                glob1(hptr+v2, lim);
701
                                lim = lptr;
702
                        } else {
703
                                glob1(base, lptr);
704
                                base = hptr+v2;
705
                        }
706
                        goto top;
707
                }
708
 
709
 
710
                glob3(j, lptr -= v2, i);
711
                j = hptr -= v2;
712
        }
713
}
714
 
715
void
716
glob2(i, j)
717
char *i, *j;
718
{
719
        register char *index1, *index2, c;
720
        int m;
721
 
722
        m = globv;
723
        index1 = i;
724
        index2 = j;
725
        do {
726
                c = *index1;
727
                *index1++ = *index2;
728
                *index2++ = c;
729
        } while(--m);
730
}
731
 
732
void
733
glob3(i, j, k)
734
char *i, *j, *k;
735
{
736
        register char *index1, *index2, *index3;
737
        int c;
738
        int m;
739
 
740
        m = globv;
741
        index1 = i;
742
        index2 = j;
743
        index3 = k;
744
        do {
745
                c = *index1;
746
                *index1++ = *index3;
747
                *index3++ = *index2;
748
                *index2++ = c;
749
        } while(--m);
750
}
751
 
752
char *
753
memcopy(ato, from, nb)
754
register char *ato, *from;
755
register int nb;
756
{
757
        register char *to;
758
 
759
        to = ato;
760
        while (--nb >= 0)
761
                *to++ = *from++;
762
        return(ato);
763
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.