~ubuntu-branches/ubuntu/trusty/mysql-workbench/trusty

« back to all changes in this revision

Viewing changes to ext/scintilla/lexers/LexBash.cxx

  • Committer: Package Import Robot
  • Author(s): Dmitry Smirnov
  • Date: 2013-06-05 09:13:55 UTC
  • mfrom: (5.1.5 experimental)
  • Revision ID: package-import@ubuntu.com-20130605091355-lz0oqppmlovk587y
Tags: 5.2.47+dfsg-1
* Upload to unstable.
* New patch to get libpython flags using `python-config`
  (Closes: #710627).
* Build-Depends:
  - python-all-dev
  + python-dev (provides `python-config`)
  - libboost-dev
  + libboost1.53-dev | libboost-dev (needed to avoid FTBFS since
    libmysqlcppconn depends on boost1.53 which conflicts with older
    boost that is pulled by libboost-dev).
* rules: added "-v" to `mv` command (more build-time verbosity).
* rules: get-orig-source improvements.
* Dropped unused lintian-overrides

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
/** @file LexBash.cxx
3
3
 ** Lexer for Bash.
4
4
 **/
5
 
// Copyright 2004-2010 by Neil Hodgson <neilh@scintilla.org>
 
5
// Copyright 2004-2012 by Neil Hodgson <neilh@scintilla.org>
6
6
// Adapted from LexPerl by Kein-Hong Man 2004
7
7
// The License.txt file describes the conditions under which this software may be distributed.
8
8
 
49
49
#define BASH_CMD_ARITH                  4
50
50
#define BASH_CMD_DELIM                  5
51
51
 
 
52
// state constants for nested delimiter pairs, used by
 
53
// SCE_SH_STRING and SCE_SH_BACKTICKS processing
 
54
#define BASH_DELIM_LITERAL              0
 
55
#define BASH_DELIM_STRING               1
 
56
#define BASH_DELIM_CSTRING              2
 
57
#define BASH_DELIM_LSTRING              3
 
58
#define BASH_DELIM_COMMAND              4
 
59
#define BASH_DELIM_BACKTICK             5
 
60
 
 
61
#define BASH_DELIM_STACK_MAX    7
 
62
 
52
63
static inline int translateBashDigit(int ch) {
53
64
        if (ch >= '0' && ch <= '9') {
54
65
                return ch - '0';
154
165
        };
155
166
        QuoteCls Quote;
156
167
 
 
168
        class QuoteStackCls {   // Class to manage quote pairs that nest
 
169
                public:
 
170
                int Count;
 
171
                int Up, Down;
 
172
                int Style;
 
173
                int Depth;                      // levels pushed
 
174
                int *CountStack;
 
175
                int *UpStack;
 
176
                int *StyleStack;
 
177
                QuoteStackCls() {
 
178
                        Count = 0;
 
179
                        Up    = '\0';
 
180
                        Down  = '\0';
 
181
                        Style = 0;
 
182
                        Depth = 0;
 
183
                        CountStack = new int[BASH_DELIM_STACK_MAX];
 
184
                        UpStack    = new int[BASH_DELIM_STACK_MAX];
 
185
                        StyleStack = new int[BASH_DELIM_STACK_MAX];
 
186
                }
 
187
                void Start(int u, int s) {
 
188
                        Count = 1;
 
189
                        Up    = u;
 
190
                        Down  = opposite(Up);
 
191
                        Style = s;
 
192
                }
 
193
                void Push(int u, int s) {
 
194
                        if (Depth >= BASH_DELIM_STACK_MAX)
 
195
                                return;
 
196
                        CountStack[Depth] = Count;
 
197
                        UpStack   [Depth] = Up;
 
198
                        StyleStack[Depth] = Style;
 
199
                        Depth++;
 
200
                        Count = 1;
 
201
                        Up    = u;
 
202
                        Down  = opposite(Up);
 
203
                        Style = s;
 
204
                }
 
205
                void Pop(void) {
 
206
                        if (Depth <= 0)
 
207
                                return;
 
208
                        Depth--;
 
209
                        Count = CountStack[Depth];
 
210
                        Up    = UpStack   [Depth];
 
211
                        Style = StyleStack[Depth];
 
212
                        Down  = opposite(Up);
 
213
                }
 
214
                ~QuoteStackCls() {
 
215
                        delete []CountStack;
 
216
                        delete []UpStack;
 
217
                        delete []StyleStack;
 
218
                }
 
219
        };
 
220
        QuoteStackCls QuoteStack;
 
221
 
157
222
        int numBase = 0;
158
223
        int digit;
159
224
        unsigned int endPos = startPos + length;
163
228
        // Always backtracks to the start of a line that is not a continuation
164
229
        // of the previous line (i.e. start of a bash command segment)
165
230
        int ln = styler.GetLine(startPos);
 
231
        if (ln > 0 && startPos == static_cast<unsigned int>(styler.LineStart(ln)))
 
232
                ln--;
166
233
        for (;;) {
167
234
                startPos = styler.LineStart(ln);
168
235
                if (ln == 0 || styler.GetLineState(ln) == BASH_CMD_START)
376
443
                                                sc.ForwardSetState(SCE_SH_DEFAULT);
377
444
                                        } else if (sc.ch == '\\') {
378
445
                                                // skip escape prefix
379
 
                                        } else {
 
446
                                        } else if (!HereDoc.Quoted) {
380
447
                                                sc.SetState(SCE_SH_DEFAULT);
381
448
                                        }
382
449
                                        if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) {    // force blowup
401
468
                                        }
402
469
                                        char s[HERE_DELIM_MAX];
403
470
                                        sc.GetCurrent(s, sizeof(s));
404
 
                                        if (sc.LengthCurrent() == 0)
 
471
                                        if (sc.LengthCurrent() == 0) {  // '' or "" delimiters
 
472
                                                if (prefixws == 0 && HereDoc.Quoted && HereDoc.DelimiterLength == 0)
 
473
                                                        sc.SetState(SCE_SH_DEFAULT);
405
474
                                                break;
 
475
                                        }
406
476
                                        if (s[strlen(s) - 1] == '\r')
407
477
                                                s[strlen(s) - 1] = '\0';
408
478
                                        if (strcmp(HereDoc.Delimiter, s) == 0) {
424
494
                                        }
425
495
                                }
426
496
                                break;
427
 
                        case SCE_SH_STRING:     // delimited styles
428
 
                        case SCE_SH_CHARACTER:
 
497
                        case SCE_SH_STRING:     // delimited styles, can nest
429
498
                        case SCE_SH_BACKTICKS:
430
 
                        case SCE_SH_PARAM:
 
499
                                if (sc.ch == '\\' && QuoteStack.Up != '\\') {
 
500
                                        if (QuoteStack.Style != BASH_DELIM_LITERAL)
 
501
                                                sc.Forward();
 
502
                                } else if (sc.ch == QuoteStack.Down) {
 
503
                                        QuoteStack.Count--;
 
504
                                        if (QuoteStack.Count == 0) {
 
505
                                                if (QuoteStack.Depth > 0) {
 
506
                                                        QuoteStack.Pop();
 
507
                                                } else
 
508
                                                        sc.ForwardSetState(SCE_SH_DEFAULT);
 
509
                                        }
 
510
                                } else if (sc.ch == QuoteStack.Up) {
 
511
                                        QuoteStack.Count++;
 
512
                                } else {
 
513
                                        if (QuoteStack.Style == BASH_DELIM_STRING ||
 
514
                                                QuoteStack.Style == BASH_DELIM_LSTRING
 
515
                                        ) {     // do nesting for "string", $"locale-string"
 
516
                                                if (sc.ch == '`') {
 
517
                                                        QuoteStack.Push(sc.ch, BASH_DELIM_BACKTICK);
 
518
                                                } else if (sc.ch == '$' && sc.chNext == '(') {
 
519
                                                        sc.Forward();
 
520
                                                        QuoteStack.Push(sc.ch, BASH_DELIM_COMMAND);
 
521
                                                }
 
522
                                        } else if (QuoteStack.Style == BASH_DELIM_COMMAND ||
 
523
                                                           QuoteStack.Style == BASH_DELIM_BACKTICK
 
524
                                        ) {     // do nesting for $(command), `command`
 
525
                                                if (sc.ch == '\'') {
 
526
                                                        QuoteStack.Push(sc.ch, BASH_DELIM_LITERAL);
 
527
                                                } else if (sc.ch == '\"') {
 
528
                                                        QuoteStack.Push(sc.ch, BASH_DELIM_STRING);
 
529
                                                } else if (sc.ch == '`') {
 
530
                                                        QuoteStack.Push(sc.ch, BASH_DELIM_BACKTICK);
 
531
                                                } else if (sc.ch == '$') {
 
532
                                                        if (sc.chNext == '\'') {
 
533
                                                                sc.Forward();
 
534
                                                                QuoteStack.Push(sc.ch, BASH_DELIM_CSTRING);
 
535
                                                        } else if (sc.chNext == '\"') {
 
536
                                                                sc.Forward();
 
537
                                                                QuoteStack.Push(sc.ch, BASH_DELIM_LSTRING);
 
538
                                                        } else if (sc.chNext == '(') {
 
539
                                                                sc.Forward();
 
540
                                                                QuoteStack.Push(sc.ch, BASH_DELIM_COMMAND);
 
541
                                                        }
 
542
                                                }
 
543
                                        }
 
544
                                }
 
545
                                break;
 
546
                        case SCE_SH_PARAM: // ${parameter}
431
547
                                if (sc.ch == '\\' && Quote.Up != '\\') {
432
548
                                        sc.Forward();
433
549
                                } else if (sc.ch == Quote.Down) {
439
555
                                        Quote.Count++;
440
556
                                }
441
557
                                break;
 
558
                        case SCE_SH_CHARACTER: // singly-quoted strings
 
559
                                if (sc.ch == Quote.Down) {
 
560
                                        Quote.Count--;
 
561
                                        if (Quote.Count == 0) {
 
562
                                                sc.ForwardSetState(SCE_SH_DEFAULT);
 
563
                                        }
 
564
                                }
 
565
                                break;
442
566
                }
443
567
 
444
568
                // Must check end of HereDoc state 1 before default state is handled
454
578
                                        sc.ChangeState(SCE_SH_ERROR);
455
579
                                }
456
580
                                // HereDoc.Quote always == '\''
 
581
                                sc.SetState(SCE_SH_HERE_Q);
 
582
                        } else if (HereDoc.DelimiterLength == 0) {
 
583
                                // no delimiter, illegal (but '' and "" are legal)
 
584
                                sc.ChangeState(SCE_SH_ERROR);
 
585
                                sc.SetState(SCE_SH_DEFAULT);
 
586
                        } else {
 
587
                                sc.SetState(SCE_SH_HERE_Q);
457
588
                        }
458
 
                        sc.SetState(SCE_SH_HERE_Q);
459
589
                }
460
590
 
461
591
                // update cmdState about the current command segment
490
620
                                sc.SetState(SCE_SH_COMMENTLINE);
491
621
                        } else if (sc.ch == '\"') {
492
622
                                sc.SetState(SCE_SH_STRING);
493
 
                                Quote.Start(sc.ch);
 
623
                                QuoteStack.Start(sc.ch, BASH_DELIM_STRING);
494
624
                        } else if (sc.ch == '\'') {
495
625
                                sc.SetState(SCE_SH_CHARACTER);
496
626
                                Quote.Start(sc.ch);
497
627
                        } else if (sc.ch == '`') {
498
628
                                sc.SetState(SCE_SH_BACKTICKS);
499
 
                                Quote.Start(sc.ch);
 
629
                                QuoteStack.Start(sc.ch, BASH_DELIM_BACKTICK);
500
630
                        } else if (sc.ch == '$') {
501
631
                                if (sc.Match("$((")) {
502
632
                                        sc.SetState(SCE_SH_OPERATOR);   // handle '((' later
506
636
                                sc.Forward();
507
637
                                if (sc.ch == '{') {
508
638
                                        sc.ChangeState(SCE_SH_PARAM);
 
639
                                        Quote.Start(sc.ch);
509
640
                                } else if (sc.ch == '\'') {
510
 
                                        sc.ChangeState(SCE_SH_CHARACTER);
 
641
                                        sc.ChangeState(SCE_SH_STRING);
 
642
                                        QuoteStack.Start(sc.ch, BASH_DELIM_CSTRING);
511
643
                                } else if (sc.ch == '"') {
512
644
                                        sc.ChangeState(SCE_SH_STRING);
513
 
                                } else if (sc.ch == '(' || sc.ch == '`') {
514
 
                                        sc.ChangeState(SCE_SH_BACKTICKS);
 
645
                                        QuoteStack.Start(sc.ch, BASH_DELIM_LSTRING);
 
646
                                } else if (sc.ch == '(') {
 
647
                                        sc.ChangeState(SCE_SH_BACKTICKS);
 
648
                                        QuoteStack.Start(sc.ch, BASH_DELIM_COMMAND);
 
649
                                } else if (sc.ch == '`') {      // $` seen in a configure script, valid?
 
650
                                        sc.ChangeState(SCE_SH_BACKTICKS);
 
651
                                        QuoteStack.Start(sc.ch, BASH_DELIM_BACKTICK);
515
652
                                } else {
516
653
                                        continue;       // scalar has no delimiter pair
517
654
                                }
518
 
                                // fallthrough, open delim for $[{'"(`]
519
 
                                Quote.Start(sc.ch);
520
655
                        } else if (sc.Match('<', '<')) {
521
656
                                sc.SetState(SCE_SH_HERE_DELIM);
522
657
                                HereDoc.State = 0;
590
725
                }// sc.state
591
726
        }
592
727
        sc.Complete();
 
728
        if (sc.state == SCE_SH_HERE_Q) {
 
729
                styler.ChangeLexerState(sc.currentPos, styler.Length());
 
730
        }
 
731
        sc.Complete();
593
732
}
594
733
 
595
734
static bool IsCommentLine(int line, Accessor &styler) {
644
783
                        if (ch == '<' && chNext == '<') {
645
784
                                levelCurrent++;
646
785
                        }
647
 
                } else if (style == SCE_SH_HERE_Q && styler.StyleAt(i+1) == SCE_PL_DEFAULT) {
 
786
                } else if (style == SCE_SH_HERE_Q && styler.StyleAt(i+1) == SCE_SH_DEFAULT) {
648
787
                        levelCurrent--;
649
788
                }
650
789
                if (atEOL) {