(?p{}) has been deprecated for a long time.
[p5sagit/p5-mst-13.2.git] / perly.c
1 /*    perly.c
2  *
3  *    Copyright (c) 2004, 2005, 2006, 2007, by Larry Wall and others
4  *
5  *    You may distribute under the terms of either the GNU General Public
6  *    License or the Artistic License, as specified in the README file.
7  * 
8  *    Note that this file was originally generated as an output from
9  *    GNU bison version 1.875, but now the code is statically maintained
10  *    and edited; the bits that are dependent on perly.y are now
11  *    #included from the files perly.tab and perly.act.
12  *
13  *    Here is an important copyright statement from the original, generated
14  *    file:
15  *
16  *      As a special exception, when this file is copied by Bison into a
17  *      Bison output file, you may use that output file without
18  *      restriction.  This special exception was added by the Free
19  *      Software Foundation in version 1.24 of Bison.
20  *
21  * Note that this file is also #included in madly.c, to allow compilation
22  * of a second parser, Perl_madparse, that is identical to Perl_yyparse,
23  * but which includes extra code for dumping the parse tree.
24  * This is controlled by the PERL_IN_MADLY_C define.
25  */
26
27 #include "EXTERN.h"
28 #define PERL_IN_PERLY_C
29 #include "perl.h"
30
31 typedef unsigned char yytype_uint8;
32 typedef signed char yytype_int8;
33 typedef unsigned short int yytype_uint16;
34 typedef short int yytype_int16;
35 typedef signed char yysigned_char;
36
37 #ifdef DEBUGGING
38 #  define YYDEBUG 1
39 #else
40 #  define YYDEBUG 0
41 #endif
42
43 /* contains all the parser state tables; auto-generated from perly.y */
44 #include "perly.tab"
45
46 # define YYSIZE_T size_t
47
48 #define YYEOF           0
49 #define YYTERROR        1
50
51 #define YYACCEPT        goto yyacceptlab
52 #define YYABORT         goto yyabortlab
53 #define YYERROR         goto yyerrlab1
54
55 /* Enable debugging if requested.  */
56 #ifdef DEBUGGING
57
58 #  define yydebug (DEBUG_p_TEST)
59
60 #  define YYFPRINTF PerlIO_printf
61
62 #  define YYDPRINTF(Args)                       \
63 do {                                            \
64     if (yydebug)                                \
65         YYFPRINTF Args;                         \
66 } while (0)
67
68 #  define YYDSYMPRINTF(Title, Token, Value)                     \
69 do {                                                            \
70     if (yydebug) {                                              \
71         YYFPRINTF (Perl_debug_log, "%s ", Title);               \
72         yysymprint (aTHX_ Perl_debug_log,  Token, Value);       \
73         YYFPRINTF (Perl_debug_log, "\n");                       \
74     }                                                           \
75 } while (0)
76
77 /*--------------------------------.
78 | Print this symbol on YYOUTPUT.  |
79 `--------------------------------*/
80
81 static void
82 yysymprint(pTHX_ PerlIO * const yyoutput, int yytype, const YYSTYPE * const yyvaluep)
83 {
84     if (yytype < YYNTOKENS) {
85         YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
86 #   ifdef YYPRINT
87         YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
88 #   else
89         YYFPRINTF (yyoutput, "0x%"UVxf, (UV)yyvaluep->ival);
90 #   endif
91     }
92     else
93         YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
94
95     YYFPRINTF (yyoutput, ")");
96 }
97
98
99 /*  yy_stack_print()
100  *  print the top 8 items on the parse stack.
101  */
102
103 static void
104 yy_stack_print (pTHX_ const yy_parser *parser)
105 {
106     const yy_stack_frame *ps, *min;
107
108     min = parser->ps - 8 + 1;
109     if (min <= parser->stack)
110         min = parser->stack + 1;
111
112     PerlIO_printf(Perl_debug_log, "\nindex:");
113     for (ps = min; ps <= parser->ps; ps++)
114         PerlIO_printf(Perl_debug_log, " %8d", (int)(ps - parser->stack));
115
116     PerlIO_printf(Perl_debug_log, "\nstate:");
117     for (ps = min; ps <= parser->ps; ps++)
118         PerlIO_printf(Perl_debug_log, " %8d", ps->state);
119
120     PerlIO_printf(Perl_debug_log, "\ntoken:");
121     for (ps = min; ps <= parser->ps; ps++)
122         PerlIO_printf(Perl_debug_log, " %8.8s", ps->name);
123
124     PerlIO_printf(Perl_debug_log, "\nvalue:");
125     for (ps = min; ps <= parser->ps; ps++) {
126         switch (yy_type_tab[yystos[ps->state]]) {
127         case toketype_opval:
128             PerlIO_printf(Perl_debug_log, " %8.8s",
129                   ps->val.opval
130                     ? PL_op_name[ps->val.opval->op_type]
131                     : "(Nullop)"
132             );
133             break;
134 #ifndef PERL_IN_MADLY_C
135         case toketype_p_tkval:
136             PerlIO_printf(Perl_debug_log, " %8.8s",
137                   ps->val.pval ? ps->val.pval : "(NULL)");
138             break;
139
140         case toketype_i_tkval:
141 #endif
142         case toketype_ival:
143             PerlIO_printf(Perl_debug_log, " %8"IVdf, (IV)ps->val.ival);
144             break;
145         default:
146             PerlIO_printf(Perl_debug_log, " %8"UVxf, (UV)ps->val.ival);
147         }
148     }
149     PerlIO_printf(Perl_debug_log, "\n\n");
150 }
151
152 #  define YY_STACK_PRINT(parser)        \
153 do {                                    \
154     if (yydebug && DEBUG_v_TEST)        \
155         yy_stack_print (aTHX_ parser);  \
156 } while (0)
157
158
159 /*------------------------------------------------.
160 | Report that the YYRULE is going to be reduced.  |
161 `------------------------------------------------*/
162
163 static void
164 yy_reduce_print (pTHX_ int yyrule)
165 {
166     int yyi;
167     const unsigned int yylineno = yyrline[yyrule];
168     YYFPRINTF (Perl_debug_log, "Reducing stack by rule %d (line %u), ",
169                           yyrule - 1, yylineno);
170     /* Print the symbols being reduced, and their result.  */
171     for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
172         YYFPRINTF (Perl_debug_log, "%s ", yytname [yyrhs[yyi]]);
173     YYFPRINTF (Perl_debug_log, "-> %s\n", yytname [yyr1[yyrule]]);
174 }
175
176 #  define YY_REDUCE_PRINT(Rule)         \
177 do {                                    \
178     if (yydebug)                        \
179         yy_reduce_print (aTHX_ Rule);           \
180 } while (0)
181
182 #else /* !DEBUGGING */
183 #  define YYDPRINTF(Args)
184 #  define YYDSYMPRINTF(Title, Token, Value)
185 #  define YY_STACK_PRINT(parser)
186 #  define YY_REDUCE_PRINT(Rule)
187 #endif /* !DEBUGGING */
188
189 /* called during cleanup (via SAVEDESTRUCTOR_X) to free any items on the
190  * parse stack, thus avoiding leaks if we die  */
191
192 static void
193 S_clear_yystack(pTHX_  const yy_parser *parser)
194 {
195     yy_stack_frame *ps     = parser->ps;
196     int i;
197
198     if (!parser->stack || ps == parser->stack)
199         return;
200
201     YYDPRINTF ((Perl_debug_log, "clearing the parse stack\n"));
202
203     /* Freeing ops on the stack, and the op_latefree / op_latefreed /
204      * op_attached flags:
205      *
206      * When we pop tokens off the stack during error recovery, or when
207      * we pop all the tokens off the stack after a die during a shift or
208      * reduce (i.e. Perl_croak somewhere in yylex() or in one of the
209      * newFOO() functions), then it's possible that some of these tokens are
210      * of type opval, pointing to an OP. All these ops are orphans; each is
211      * its own miniature subtree that has not yet been attached to a
212      * larger tree. In this case, we should clearly free the op (making
213      * sure, for each op we free that we have PL_comppad pointing to the
214      * right place for freeing any SVs attached to the op in threaded
215      * builds.
216      *
217      * However, there is a particular problem if we die in newFOO() called
218      * by a reducing action; e.g.
219      *
220      *    foo : bar baz boz
221      *        { $$ = newFOO($1,$2,$3) }
222      *
223      * where
224      *  OP *newFOO { ....; if (...) croak; .... }
225      *
226      * In this case, when we come to clean bar baz and boz off the stack,
227      * we don't know whether newFOO() has already:
228      *    * freed them
229      *    * left them as is
230      *    * attached them to part of a larger tree
231      *    * attached them to PL_compcv
232      *    * attached them to PL_compcv then freed it (as in BEGIN {die } )
233      *
234      * To get round this problem, we set the flag op_latefree on every op
235      * that gets pushed onto the parser stack. If op_free() sees this
236      * flag, it clears the op and frees any children,, but *doesn't* free
237      * the op itself; instead it sets the op_latefreed flag. This means
238      * that we can safely call op_free() multiple times on each stack op.
239      * So, when clearing the stack, we first, for each op that was being
240      * reduced, call op_free with op_latefree=1. This ensures that all ops
241      * hanging off these op are freed, but the reducing ops themselces are
242      * just undefed. Then we set op_latefreed=0 on *all* ops on the stack
243      * and free them. A little thought should convince you that this
244      * two-part approach to the reducing ops should handle the first three
245      * cases above safely.
246      *
247      * In the case of attaching to PL_compcv (currently just newATTRSUB
248      * does this), then  we set the op_attached flag on the op that has
249      * been so attached, then avoid doing the final op_free during
250      * cleanup, on the assumption that it will happen (or has already
251      * happened) when PL_compcv is freed.
252      *
253      * Note this is fairly fragile mechanism. A more robust approach
254      * would be to use two of these flag bits as 2-bit reference count
255      * field for each op, indicating whether it is pointed to from:
256      *   * a parent op
257      *   * the parser stack
258      *   * a CV
259      * but this would involve reworking all code (core and external) that
260      * manipulate op trees.
261      *
262      * XXX DAPM 17/1/07 I've decided its too fragile for now, and so have
263      * disabled it */
264
265 #define DISABLE_STACK_FREE
266
267
268 #ifdef DISABLE_STACK_FREE
269     ps -= parser->yylen;
270     PERL_UNUSED_VAR(i);
271 #else
272     /* clear any reducing ops (1st pass) */
273
274     for (i=0; i< parser->yylen; i++) {
275         if (yy_type_tab[yystos[ps[-i].state]] == toketype_opval
276             && ps[-i].val.opval) {
277             if ( ! (ps[-i].val.opval->op_attached
278                     && !ps[-i].val.opval->op_latefreed))
279             {
280                 if (ps[-i].comppad != PL_comppad) {
281                     PAD_RESTORE_LOCAL(ps[-i].comppad);
282                 }
283                 op_free(ps[-i].val.opval);
284             }
285         }
286     }
287 #endif
288
289     /* now free whole the stack, including the just-reduced ops */
290
291     while (ps > parser->stack) {
292         if (yy_type_tab[yystos[ps->state]] == toketype_opval
293             && ps->val.opval)
294         {
295             if (ps->comppad != PL_comppad) {
296                 PAD_RESTORE_LOCAL(ps->comppad);
297             }
298             YYDPRINTF ((Perl_debug_log, "(freeing op)\n"));
299 #ifndef DISABLE_STACK_FREE
300             ps->val.opval->op_latefree  = 0;
301             if (!(ps->val.opval->op_attached && !ps->val.opval->op_latefreed))
302 #endif
303                 op_free(ps->val.opval);
304         }
305         ps--;
306     }
307 }
308
309 /* delete a parser object */
310
311 #ifndef PERL_IN_MADLY_C
312 void
313 Perl_parser_free(pTHX_  const yy_parser *parser)
314 {
315     S_clear_yystack(aTHX_ parser);
316     Safefree(parser->stack);
317     Safefree(parser->lex_brackstack);
318     Safefree(parser->lex_casestack);
319     PL_parser = parser->old_parser;
320     Safefree(parser);
321 }
322 #endif
323
324 /*----------.
325 | yyparse.  |
326 `----------*/
327
328 int
329 #ifdef PERL_IN_MADLY_C
330 Perl_madparse (pTHX)
331 #else
332 Perl_yyparse (pTHX)
333 #endif
334 {
335     dVAR;
336     register int yystate;
337     register int yyn;
338     int yyresult;
339
340     /* Lookahead token as an internal (translated) token number.  */
341     int yytoken = 0;
342
343     register yy_parser *parser;     /* the parser object */
344     register yy_stack_frame  *ps;   /* current parser stack frame */
345
346 #define YYPOPSTACK   parser->ps = --ps
347 #define YYPUSHSTACK  parser->ps = ++ps
348
349     /* The variable used to return semantic value and location from the
350           action routines: ie $$.  */
351     YYSTYPE yyval;
352
353 #ifndef PERL_IN_MADLY_C
354 #  ifdef PERL_MAD
355     if (PL_madskills)
356         return madparse();
357 #  endif
358 #endif
359
360     YYDPRINTF ((Perl_debug_log, "Starting parse\n"));
361
362     parser = PL_parser;
363     ps = parser->ps;
364
365     ENTER;  /* force parser free before we return */
366     SAVEPARSER(parser);
367
368 /*------------------------------------------------------------.
369 | yynewstate -- Push a new state, which is found in yystate.  |
370 `------------------------------------------------------------*/
371   yynewstate:
372
373     yystate = ps->state;
374
375     YYDPRINTF ((Perl_debug_log, "Entering state %d\n", yystate));
376
377 #ifndef DISABLE_STACK_FREE
378     if (yy_type_tab[yystos[yystate]] == toketype_opval && ps->val.opval) {
379         ps->val.opval->op_latefree  = 1;
380         ps->val.opval->op_latefreed = 0;
381     }
382 #endif
383
384     parser->yylen = 0;
385
386     {
387         size_t size = ps - parser->stack + 1;
388
389         /* grow the stack? We always leave 1 spare slot,
390          * in case of a '' -> 'foo' reduction */
391
392         if (size >= (size_t)parser->stack_size - 1) {
393             /* this will croak on insufficient memory */
394             parser->stack_size *= 2;
395             Renew(parser->stack, parser->stack_size, yy_stack_frame);
396             ps = parser->ps = parser->stack + size -1;
397
398             YYDPRINTF((Perl_debug_log,
399                             "parser stack size increased to %lu frames\n",
400                             (unsigned long int)parser->stack_size));
401         }
402     }
403
404 /* Do appropriate processing given the current state.  */
405 /* Read a lookahead token if we need one and don't already have one.  */
406
407     /* First try to decide what to do without reference to lookahead token.  */
408
409     yyn = yypact[yystate];
410     if (yyn == YYPACT_NINF)
411         goto yydefault;
412
413     /* Not known => get a lookahead token if don't already have one.  */
414
415     /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
416     if (parser->yychar == YYEMPTY) {
417         YYDPRINTF ((Perl_debug_log, "Reading a token: "));
418 #ifdef PERL_IN_MADLY_C
419         parser->yychar = PL_madskills ? madlex() : yylex();
420 #else
421         parser->yychar = yylex();
422 #endif
423
424 #  ifdef EBCDIC
425         if (parser->yychar >= 0 && parser->yychar < 255) {
426             parser->yychar = NATIVE_TO_ASCII(parser->yychar);
427         }
428 #  endif
429     }
430
431     if (parser->yychar <= YYEOF) {
432         parser->yychar = yytoken = YYEOF;
433         YYDPRINTF ((Perl_debug_log, "Now at end of input.\n"));
434     }
435     else {
436         yytoken = YYTRANSLATE (parser->yychar);
437         YYDSYMPRINTF ("Next token is", yytoken, &parser->yylval);
438     }
439
440     /* If the proper action on seeing token YYTOKEN is to reduce or to
441           detect an error, take that action.  */
442     yyn += yytoken;
443     if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
444         goto yydefault;
445     yyn = yytable[yyn];
446     if (yyn <= 0) {
447         if (yyn == 0 || yyn == YYTABLE_NINF)
448             goto yyerrlab;
449         yyn = -yyn;
450         goto yyreduce;
451     }
452
453     if (yyn == YYFINAL)
454         YYACCEPT;
455
456     /* Shift the lookahead token.  */
457     YYDPRINTF ((Perl_debug_log, "Shifting token %s, ", yytname[yytoken]));
458
459     /* Discard the token being shifted unless it is eof.  */
460     if (parser->yychar != YYEOF)
461         parser->yychar = YYEMPTY;
462
463     YYPUSHSTACK;
464     ps->state   = yyn;
465     ps->val     = parser->yylval;
466     ps->comppad = PL_comppad;
467 #ifdef DEBUGGING
468     ps->name    = (const char *)(yytname[yytoken]);
469 #endif
470
471     /* Count tokens shifted since error; after three, turn off error
472           status.  */
473     if (parser->yyerrstatus)
474         parser->yyerrstatus--;
475
476     goto yynewstate;
477
478
479   /*-----------------------------------------------------------.
480   | yydefault -- do the default action for the current state.  |
481   `-----------------------------------------------------------*/
482   yydefault:
483     yyn = yydefact[yystate];
484     if (yyn == 0)
485         goto yyerrlab;
486     goto yyreduce;
487
488
489   /*-----------------------------.
490   | yyreduce -- Do a reduction.  |
491   `-----------------------------*/
492   yyreduce:
493     /* yyn is the number of a rule to reduce with.  */
494     parser->yylen = yyr2[yyn];
495
496     /* If YYLEN is nonzero, implement the default value of the action:
497       "$$ = $1".
498
499       Otherwise, the following line sets YYVAL to garbage.
500       This behavior is undocumented and Bison
501       users should not rely upon it.  Assigning to YYVAL
502       unconditionally makes the parser a bit smaller, and it avoids a
503       GCC warning that YYVAL may be used uninitialized.  */
504     yyval = ps[1-parser->yylen].val;
505
506     YY_STACK_PRINT(parser);
507     YY_REDUCE_PRINT (yyn);
508
509     switch (yyn) {
510
511
512 #define dep() deprecate("\"do\" to call subroutines")
513
514 #ifdef PERL_IN_MADLY_C
515 #  define IVAL(i) (i)->tk_lval.ival
516 #  define PVAL(p) (p)->tk_lval.pval
517 #  define TOKEN_GETMAD(a,b,c) token_getmad((a),(b),(c))
518 #  define TOKEN_FREE(a) token_free(a)
519 #  define OP_GETMAD(a,b,c) op_getmad((a),(b),(c))
520 #  define IF_MAD(a,b) (a)
521 #  define DO_MAD(a) a
522 #  define MAD
523 #else
524 #  define IVAL(i) (i)
525 #  define PVAL(p) (p)
526 #  define TOKEN_GETMAD(a,b,c)
527 #  define TOKEN_FREE(a)
528 #  define OP_GETMAD(a,b,c)
529 #  define IF_MAD(a,b) (b)
530 #  define DO_MAD(a)
531 #  undef MAD
532 #endif
533
534 /* contains all the rule actions; auto-generated from perly.y */
535 #include "perly.act"
536
537     }
538
539 #ifndef DISABLE_STACK_FREE
540     /* any just-reduced ops with the op_latefreed flag cleared need to be
541      * freed; the rest need the flag resetting */
542     {
543         int i;
544         for (i=0; i< parser->yylen; i++) {
545             if (yy_type_tab[yystos[ps[-i].state]] == toketype_opval
546                 && ps[-i].val.opval)
547             {
548                 ps[-i].val.opval->op_latefree = 0;
549                 if (ps[-i].val.opval->op_latefreed)
550                     op_free(ps[-i].val.opval);
551             }
552         }
553     }
554 #endif
555
556     parser->ps = ps -= (parser->yylen-1);
557
558     /* Now shift the result of the reduction.  Determine what state
559           that goes to, based on the state we popped back to and the rule
560           number reduced by.  */
561
562     ps->val     = yyval;
563     ps->comppad = PL_comppad;
564 #ifdef DEBUGGING
565     ps->name    = (const char *)(yytname [yyr1[yyn]]);
566 #endif
567
568     yyn = yyr1[yyn];
569
570     yystate = yypgoto[yyn - YYNTOKENS] + ps[-1].state;
571     if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == ps[-1].state)
572         yystate = yytable[yystate];
573     else
574         yystate = yydefgoto[yyn - YYNTOKENS];
575     ps->state = yystate;
576
577     goto yynewstate;
578
579
580   /*------------------------------------.
581   | yyerrlab -- here on detecting error |
582   `------------------------------------*/
583   yyerrlab:
584     /* If not already recovering from an error, report this error.  */
585     if (!parser->yyerrstatus) {
586         yyerror ("syntax error");
587     }
588
589
590     if (parser->yyerrstatus == 3) {
591         /* If just tried and failed to reuse lookahead token after an
592               error, discard it.  */
593
594         /* Return failure if at end of input.  */
595         if (parser->yychar == YYEOF) {
596             /* Pop the error token.  */
597             YYPOPSTACK;
598             /* Pop the rest of the stack.  */
599             while (ps > parser->stack) {
600                 YYDSYMPRINTF ("Error: popping", yystos[ps->state], &ps->val);
601                 if (yy_type_tab[yystos[ps->state]] == toketype_opval
602                         && ps->val.opval)
603                 {
604                     YYDPRINTF ((Perl_debug_log, "(freeing op)\n"));
605                     if (ps->comppad != PL_comppad) {
606                         PAD_RESTORE_LOCAL(ps->comppad);
607                     }
608                     ps->val.opval->op_latefree  = 0;
609                     op_free(ps->val.opval);
610                 }
611                 YYPOPSTACK;
612             }
613             YYABORT;
614         }
615
616         YYDSYMPRINTF ("Error: discarding", yytoken, &parser->yylval);
617         parser->yychar = YYEMPTY;
618
619     }
620
621     /* Else will try to reuse lookahead token after shifting the error
622           token.  */
623     goto yyerrlab1;
624
625
626   /*----------------------------------------------------.
627   | yyerrlab1 -- error raised explicitly by an action.  |
628   `----------------------------------------------------*/
629   yyerrlab1:
630     parser->yyerrstatus = 3;    /* Each real token shifted decrements this.  */
631
632     for (;;) {
633         yyn = yypact[yystate];
634         if (yyn != YYPACT_NINF) {
635             yyn += YYTERROR;
636             if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) {
637                 yyn = yytable[yyn];
638                 if (0 < yyn)
639                     break;
640             }
641         }
642
643         /* Pop the current state because it cannot handle the error token.  */
644         if (ps == parser->stack)
645             YYABORT;
646
647         YYDSYMPRINTF ("Error: popping", yystos[ps->state], &ps->val);
648         if (yy_type_tab[yystos[ps->state]] == toketype_opval && ps->val.opval) {
649             YYDPRINTF ((Perl_debug_log, "(freeing op)\n"));
650             if (ps->comppad != PL_comppad) {
651                 PAD_RESTORE_LOCAL(ps->comppad);
652             }
653             ps->val.opval->op_latefree  = 0;
654             op_free(ps->val.opval);
655         }
656         YYPOPSTACK;
657         yystate = ps->state;
658
659         YY_STACK_PRINT(parser);
660     }
661
662     if (yyn == YYFINAL)
663         YYACCEPT;
664
665     YYDPRINTF ((Perl_debug_log, "Shifting error token, "));
666
667     YYPUSHSTACK;
668     ps->state   = yyn;
669     ps->val     = parser->yylval;
670     ps->comppad = PL_comppad;
671 #ifdef DEBUGGING
672     ps->name    ="<err>";
673 #endif
674
675     goto yynewstate;
676
677
678   /*-------------------------------------.
679   | yyacceptlab -- YYACCEPT comes here.  |
680   `-------------------------------------*/
681   yyacceptlab:
682     yyresult = 0;
683     parser->ps = parser->stack; /* disable cleanup */
684     goto yyreturn;
685
686   /*-----------------------------------.
687   | yyabortlab -- YYABORT comes here.  |
688   `-----------------------------------*/
689   yyabortlab:
690     yyresult = 1;
691     goto yyreturn;
692
693   yyreturn:
694     LEAVE;                      /* force parser free before we return */
695     return yyresult;
696 }
697
698 /*
699  * Local variables:
700  * c-indentation-style: bsd
701  * c-basic-offset: 4
702  * indent-tabs-mode: t
703  * End:
704  *
705  * ex: set ts=8 sts=4 sw=4 noet:
706  */