--
Greetings Flexoids,

I'm trying to debug a flex scanner segfault issue in a very old program (not
mine) about which I know essentially nothing of its internals, just trying to
build it. To add to the fun, I know very little about flex.

The good news is that the scanner builds and works just fine when built and
run a 32b i686 box. The segfaults occurs only when it is built and run on an
x86_64.  

The segfault occurs at the scanner line "*yy_cp = (yy_hold_char);".  Goolging
suggests that this is a common point of failure, related (I think?) to
overrunning a buffer which is expected to be null-terminated but isn't.
However, I was unable to make any further headway in determining more than
this (and not even sure the above is correct.)

Also googled for complaints about similar 32b/64b flex issues in general, i.e.
anything that might give a hint as to why a particular scanner might work for
32b but not 64b.  No joy on that either.

Could someone here perhaps cast an expert eye at it, suggest some things to
try in order to narrow down the issue? Any help would be greatly appreciated.

Attached are three relevant files:

  spewage.txt: Scanner build lines (flex, and subsequent gcc), and the output
  from a gdb session in which it segfaults. 

  xtpanel_scan.l: Scanner definition

  test.xt: The scanner input file on which the segfault occurs.

If anything else would be useful, just let me know.

TIA,

Glenn
#########################################################################
# Commands executed (by Makefile) to build lex.yy.c:
#########################################################################

flex -X -v -T xtpanel_scan.l
gcc -g -fno-strength-reduce -I/usr/include/X11  -Dlinux \
        -D_POSIX_C_SOURCE=199309L -D_POSIX_SOURCE -D_XOPEN_SOURCE \
        -D_BSD_SOURCE -D_SVID_SOURCE -DFUNCPROTO=15 -DNARROWPROTO \
        -DSYS_XTPANELDIR=\"/usr/local/xtpanel\" -DXPM lex.yy.c
mv lex.yy.o xtpanel_scan.o



#########################################################################
# Output from flex -T during above build:
#########################################################################

%s'FOUNDTAG'%%
1       <'FOUNDTAG'>('([^']*'')*[^']*['])
2       <'FOUNDTAG'>(`([^`]*``)*[^`]*[`])
3       <'FOUNDTAG'>(\"([^\"]*\"\")*[^\"]*[\"])
4       <'FOUNDTAG'>[^'\"]([^ \011\012\{\}])*
5       (([A-Za-z])([A-Za-z0-9_\-])*=\{)
6       ([ \011])(([A-Za-z])([A-Za-z0-9_\-])*=\{)
7       (([A-Za-z])([A-Za-z0-9_\-])*=)/[^ \011\012\{\}]
8       (([A-Za-z])([A-Za-z0-9_\-])*=)([ \011\012])
9       (\})
10      (\{)
11      ([ \011\012])+
12      ^![^\012]*
13      ![^\012]*
14      .
15      End Marker


********** beginning dump of nfa with start state 135
state #    1    257:     0,    0
state #    2    257:     0,    0
state #    3    257:     0,    0
state #    4    257:     0,    0
state #    5     39:    14,    0
state #    6     -1:     7,    0
state #    7    257:     6,    8
state #    8    257:    10,    0
state #    9    257:     6,    8
state #   10     39:    11,    0
state #   11     39:    12,    0
state #   12    257:     9,   13
state #   13    257:    18,    0
state #   14    257:     9,   13
state #   15     -2:    16,    0
state #   16    257:    15,   17
state #   17    257:    19,    0
state #   18    257:    15,   17
state #   19     -3:    20,    0
state #   20    257:     0,    0  [1]
state #   21    257:     3,    5
state #   22     96:    31,    0
state #   23     -4:    24,    0
state #   24    257:    23,   25
state #   25    257:    27,    0
state #   26    257:    23,   25
state #   27     96:    28,    0
state #   28     96:    29,    0
state #   29    257:    26,   30
state #   30    257:    35,    0
state #   31    257:    26,   30
state #   32     -5:    33,    0
state #   33    257:    32,   34
state #   34    257:    36,    0
state #   35    257:    32,   34
state #   36     -6:    37,    0
state #   37    257:     0,    0  [2]
state #   38    257:    21,   22
state #   39     34:    48,    0
state #   40     -7:    41,    0
state #   41    257:    40,   42
state #   42    257:    44,    0
state #   43    257:    40,   42
state #   44     34:    45,    0
state #   45     34:    46,    0
state #   46    257:    43,   47
state #   47    257:    52,    0
state #   48    257:    43,   47
state #   49     -8:    50,    0
state #   50    257:    49,   51
state #   51    257:    53,    0
state #   52    257:    49,   51
state #   53     -9:    54,    0
state #   54    257:     0,    0  [3]
state #   55    257:    38,   39
state #   56    -10:    60,    0
state #   57    -11:    58,    0
state #   58    257:    57,   59
state #   59    257:     0,    0  [4]
state #   60    257:    57,   59
state #   61    257:    55,   56
state #   62    -12:    66,    0
state #   63    -13:    64,    0
state #   64    257:    63,   65
state #   65    257:    67,    0
state #   66    257:    63,   65
state #   67     61:    68,    0
state #   68    123:    69,    0
state #   69    257:     0,    0  [5]
state #   70    257:     1,   62
state #   71    257:    61,   62
state #   72    -14:    73,    0
state #   73    -15:    77,    0
state #   74    -16:    75,    0
state #   75    257:    74,   76
state #   76    257:    78,    0
state #   77    257:    74,   76
state #   78     61:    79,    0
state #   79    123:    80,    0
state #   80    257:     0,    0  [6]
state #   81    257:    70,   72
state #   82    257:    71,   72
state #   83    -17:    87,    0
state #   84    -18:    85,    0
state #   85    257:    84,   86
state #   86    257:    88,    0
state #   87    257:    84,   86
state #   88     61:    89,    0
state #   89    -19:    90,    0
state #   90    257:     0,    0  [7]
state #   91    257:    81,   83
state #   92    257:    82,   83
state #   93    -20:    97,    0
state #   94    -21:    95,    0
state #   95    257:    94,   96
state #   96    257:    98,    0
state #   97    257:    94,   96
state #   98     61:    99,    0
state #   99    -22:   100,    0
state #  100    257:     0,    0  [8]
state #  101    257:    91,   93
state #  102    257:    92,   93
state #  103    125:   104,    0
state #  104    257:     0,    0  [9]
state #  105    257:   101,  103
state #  106    257:   102,  103
state #  107    123:   108,    0
state #  108    257:     0,    0  [10]
state #  109    257:   105,  107
state #  110    257:   106,  107
state #  111    -23:   112,    0
state #  112    257:   111,    0  [11]
state #  113    257:   109,  111
state #  114    257:   110,  111
state #  115     33:   119,    0
state #  116    -24:   117,    0
state #  117    257:   116,  118
state #  118    257:     0,    0  [12]
state #  119    257:   116,  118
state #  120    257:     2,  115
state #  121    257:     4,  115
state #  122     33:   126,    0
state #  123    -25:   124,    0
state #  124    257:   123,  125
state #  125    257:     0,    0  [13]
state #  126    257:   123,  125
state #  127    257:   113,  122
state #  128    257:   114,  122
state #  129    -26:   130,    0
state #  130    257:     0,    0  [14]
state #  131    257:   127,  129
state #  132    257:   128,  129
state #  133    -28:   134,    0
state #  134    257:     0,    0  [15]
state #  135    257:   131,  133
state #  136    257:   132,  133
********** end of dump


DFA Dump:

state # 1:
        1       6
        2       7
        3       8
        4       9
        5       6
        6       6
        7       6
        8       6
        9       10
        10      6
        11      11
        12      12
state # 2:
        1       6
        2       7
        3       8
        4       13
        5       6
        6       6
        7       6
        8       6
        9       10
        10      6
        11      11
        12      12
state # 3:
        1       14
        2       15
        3       16
        4       17
        5       18
        6       19
        7       14
        8       14
        9       20
        10      21
        11      22
        12      23
state # 4:
        1       14
        2       15
        3       16
        4       24
        5       18
        6       19
        7       14
        8       14
        9       20
        10      21
        11      22
        12      23
state # 5:
state # 6:
state # 7:
        2       25
        3       25
        9       26
state # 8:
        2       25
        3       25
state # 9:
        1       27
        2       27
        4       27
        5       27
        6       27
        7       27
        8       27
        9       27
        10      27
        11      27
        12      27
state # 10:
        7       28
        8       29
        9       28
state # 11:
state # 12:
state # 13:
        1       30
        2       30
        4       30
        5       30
        6       30
        7       30
        8       30
        9       30
        10      30
        11      30
        12      30
state # 14:
        1       31
        4       31
        5       31
        6       31
        7       31
        8       31
        9       31
        10      31
state # 15:
        1       31
        2       25
        3       25
        4       31
        5       31
        6       31
        7       31
        8       31
        9       32
        10      31
state # 16:
        1       31
        2       25
        3       25
        4       31
        5       31
        6       31
        7       31
        8       31
        9       31
        10      31
state # 17:
        1       33
        2       27
        4       33
        5       33
        6       33
        7       33
        8       33
        9       33
        10      33
        11      27
        12      27
state # 18:
        1       34
        2       34
        3       34
        4       34
        5       35
        6       34
        7       34
        8       34
        9       34
        10      34
        11      34
        12      34
state # 19:
        1       36
        2       36
        3       36
        4       36
        5       36
        6       37
        7       36
        8       36
        9       36
        10      36
        11      36
        12      36
state # 20:
        1       31
        4       31
        5       31
        6       31
        7       38
        8       39
        9       38
        10      31
state # 21:
        1       40
        2       41
        3       41
        4       40
        5       40
        6       40
        7       40
        8       40
        9       40
        10      42
        11      41
        12      41
state # 22:
        1       31
        4       31
        5       31
        6       31
        7       31
        8       31
        9       31
        10      31
state # 23:
        1       31
        4       31
        5       31
        6       31
        7       31
        8       31
        9       31
        10      31
state # 24:
        1       43
        2       30
        4       43
        5       43
        6       43
        7       43
        8       43
        9       43
        10      43
        11      30
        12      30
state # 25:
        2       25
        3       25
state # 26:
        7       44
        8       45
        9       44
state # 27:
        1       27
        2       27
        4       27
        5       27
        6       27
        7       27
        8       27
        9       27
        10      27
        11      27
        12      27
state # 28:
        7       28
        8       29
        9       28
state # 29:
        1       46
        2       47
        3       47
        4       46
        5       46
        6       46
        7       46
        8       46
        9       46
        10      46
        11      48
state # 30:
        1       30
        2       30
        4       30
        5       30
        6       30
        7       30
        8       30
        9       30
        10      30
        11      30
        12      30
state # 31:
        1       31
        4       31
        5       31
        6       31
        7       31
        8       31
        9       31
        10      31
state # 32:
        1       31
        4       31
        5       31
        6       31
        7       49
        8       50
        9       49
        10      31
state # 33:
        1       33
        2       27
        4       33
        5       33
        6       33
        7       33
        8       33
        9       33
        10      33
        11      27
        12      27
state # 34:
        1       34
        2       34
        3       34
        4       34
        5       35
        6       34
        7       34
        8       34
        9       34
        10      34
        11      34
        12      34
state # 35:
        5       51
state # 36:
        1       36
        2       36
        3       36
        4       36
        5       36
        6       37
        7       36
        8       36
        9       36
        10      36
        11      36
        12      36
state # 37:
        6       52
state # 38:
        1       31
        4       31
        5       31
        6       31
        7       38
        8       39
        9       38
        10      31
state # 39:
        1       53
        2       47
        3       47
        4       53
        5       53
        6       53
        7       53
        8       53
        9       53
        10      53
        11      48
state # 40:
        1       40
        2       41
        3       41
        4       40
        5       40
        6       40
        7       40
        8       40
        9       40
        10      42
        11      41
        12      41
state # 41:
        1       41
        2       41
        3       41
        4       41
        5       41
        6       41
        7       41
        8       41
        9       41
        10      54
        11      41
        12      41
state # 42:
        1       31
        4       31
        5       31
        6       31
        7       31
        8       31
        9       31
        10      55
state # 43:
        1       43
        2       30
        4       43
        5       43
        6       43
        7       43
        8       43
        9       43
        10      43
        11      30
        12      30
state # 44:
        7       44
        8       45
        9       44
state # 45:
        11      56
state # 46:
state # 47:
state # 48:
state # 49:
        1       31
        4       31
        5       31
        6       31
        7       49
        8       50
        9       49
        10      31
state # 50:
        1       31
        4       31
        5       31
        6       31
        7       31
        8       31
        9       31
        10      31
        11      56
state # 51:
        1       34
        2       34
        3       34
        4       34
        5       35
        6       34
        7       34
        8       34
        9       34
        10      34
        11      34
        12      34
state # 52:
        1       36
        2       36
        3       36
        4       36
        5       36
        6       37
        7       36
        8       36
        9       36
        10      36
        11      36
        12      36
state # 53:
        1       31
        4       31
        5       31
        6       31
        7       31
        8       31
        9       31
        10      31
state # 54:
        10      57
state # 55:
        1       40
        2       41
        3       41
        4       40
        5       40
        6       40
        7       40
        8       40
        9       40
        10      42
        11      41
        12      41
state # 56:
state # 57:
        1       41
        2       41
        3       41
        4       41
        5       41
        6       41
        7       41
        8       41
        9       41
        10      54
        11      41
        12      41
state # 5 accepts: [16]
state # 6 accepts: [14]
state # 7 accepts: [11]
state # 8 accepts: [11]
state # 9 accepts: [13]
state # 10 accepts: [14]
state # 11 accepts: [10]
state # 12 accepts: [9]
state # 13 accepts: [12]
state # 14 accepts: [4]
state # 15 accepts: [4]
state # 16 accepts: [4]
state # 17 accepts: [4]
state # 18 accepts: [14]
state # 19 accepts: [14]
state # 20 accepts: [4]
state # 21 accepts: [4]
state # 22 accepts: [4]
state # 23 accepts: [4]
state # 24 accepts: [4]
state # 25 accepts: [11]
state # 27 accepts: [13]
state # 30 accepts: [12]
state # 31 accepts: [4]
state # 32 accepts: [4]
state # 33 accepts: [4]
state # 35 accepts: [3]
state # 37 accepts: [1]
state # 38 accepts: [4]
state # 39 accepts: [4]
state # 40 accepts: [4]
state # 42 accepts: [2]
state # 43 accepts: [4]
state # 46 accepts: [7]
state # 47 accepts: [8]
state # 48 accepts: [5]
state # 49 accepts: [4]
state # 50 accepts: [4]
state # 53 accepts: [4]
state # 54 accepts: [2]
state # 55 accepts: [4]
state # 56 accepts: [6]


Equivalence Classes:

\000 = -1  ' ' = 2     @ = 1     ` = 10 \200 = 1  \240 = 1  \300 = 1  \340 = 1  
\001 = 1     ! = 4     A = 9     a = 9  \201 = 1  \241 = 1  \301 = 1  \341 = 1  
\002 = 1     " = 5     B = 9     b = 9  \202 = 1  \242 = 1  \302 = 1  \342 = 1  
\003 = 1     # = 1     C = 9     c = 9  \203 = 1  \243 = 1  \303 = 1  \343 = 1  
\004 = 1     $ = 1     D = 9     d = 9  \204 = 1  \244 = 1  \304 = 1  \344 = 1  
\005 = 1     % = 1     E = 9     e = 9  \205 = 1  \245 = 1  \305 = 1  \345 = 1  
\006 = 1     & = 1     F = 9     f = 9  \206 = 1  \246 = 1  \306 = 1  \346 = 1  
  \a = 1     ' = 6     G = 9     g = 9  \207 = 1  \247 = 1  \307 = 1  \347 = 1  
  \b = 1     ( = 1     H = 9     h = 9  \210 = 1  \250 = 1  \310 = 1  \350 = 1  
  \t = 2     ) = 1     I = 9     i = 9  \211 = 1  \251 = 1  \311 = 1  \351 = 1  
  \n = 3     * = 1     J = 9     j = 9  \212 = 1  \252 = 1  \312 = 1  \352 = 1  
  \v = 1     + = 1     K = 9     k = 9  \213 = 1  \253 = 1  \313 = 1  \353 = 1  
  \f = 1     , = 1     L = 9     l = 9  \214 = 1  \254 = 1  \314 = 1  \354 = 1  
  \r = 1     - = 7     M = 9     m = 9  \215 = 1  \255 = 1  \315 = 1  \355 = 1  
\016 = 1     . = 1     N = 9     n = 9  \216 = 1  \256 = 1  \316 = 1  \356 = 1  
\017 = 1     / = 1     O = 9     o = 9  \217 = 1  \257 = 1  \317 = 1  \357 = 1  
\020 = 1     0 = 7     P = 9     p = 9  \220 = 1  \260 = 1  \320 = 1  \360 = 1  
\021 = 1     1 = 7     Q = 9     q = 9  \221 = 1  \261 = 1  \321 = 1  \361 = 1  
\022 = 1     2 = 7     R = 9     r = 9  \222 = 1  \262 = 1  \322 = 1  \362 = 1  
\023 = 1     3 = 7     S = 9     s = 9  \223 = 1  \263 = 1  \323 = 1  \363 = 1  
\024 = 1     4 = 7     T = 9     t = 9  \224 = 1  \264 = 1  \324 = 1  \364 = 1  
\025 = 1     5 = 7     U = 9     u = 9  \225 = 1  \265 = 1  \325 = 1  \365 = 1  
\026 = 1     6 = 7     V = 9     v = 9  \226 = 1  \266 = 1  \326 = 1  \366 = 1  
\027 = 1     7 = 7     W = 9     w = 9  \227 = 1  \267 = 1  \327 = 1  \367 = 1  
\030 = 1     8 = 7     X = 9     x = 9  \230 = 1  \270 = 1  \330 = 1  \370 = 1  
\031 = 1     9 = 7     Y = 9     y = 9  \231 = 1  \271 = 1  \331 = 1  \371 = 1  
\032 = 1     : = 1     Z = 9     z = 9  \232 = 1  \272 = 1  \332 = 1  \372 = 1  
\033 = 1     ; = 1     [ = 1     { = 11 \233 = 1  \273 = 1  \333 = 1  \373 = 1  
\034 = 1     < = 1     \ = 1     | = 1  \234 = 1  \274 = 1  \334 = 1  \374 = 1  
\035 = 1     = = 8     ] = 1     } = 12 \235 = 1  \275 = 1  \335 = 1  \375 = 1  
\036 = 1     > = 1     ^ = 1     ~ = 1  \236 = 1  \276 = 1  \336 = 1  \376 = 1  
\037 = 1     ? = 1     _ = 7  \177 = 1  \237 = 1  \277 = 1  \337 = 1  \377 = 1  


Meta-Equivalence Classes:
1 = 1
2 = 2
3 = 3
4 = 1
5 = 1
6 = 1
7 = 4
8 = 4
9 = 5
10 = 1
11 = 6
12 = 7
flex version 2.5.37 usage statistics:
  scanner options: -XvIT8 -Cem
  138/2000 NFA states
  57/1000 DFA states (333 words)
  14 rules
  Compressed tables always back-up
  Beginning-of-line patterns used
  2/40 start conditions
  92 epsilon states, 60 double epsilon states
  28/100 character classes needed 496/500 words of storage, 0 reused
  422 state/nextstate pairs created
  119/303 unique/duplicate transitions
  71/1000 base-def entries created
  201/2000 (peak 270) nxt-chk entries created
  98/2500 (peak 168) template nxt-chk entries created
  34 empty table entries
  24 protos created
  14 templates created, 34 uses
  12/256 equivalence classes created
  7/256 meta-equivalence classes created
  4 (1 saved) hash collisions, 67 DFAs equal
  0 sets of reallocations needed
  812 total table entries needed


#########################################################################
# Run program under gdb, observe segfault:
#########################################################################

$ gdb ./xtpanel
Reading symbols from /home/xyz/src/xtpanel-3.24G3/xtpanel...done.

(gdb) run -file test.xt
Starting program: /home/xyz/src/xtpanel-3.24G3/./xtpanel -file test.xt
xtpanel_scan
button={
    label="  QUIT  "
    background=lightblue
}
xtpanel_scan_end

Program received signal SIGSEGV, Segmentation fault.
0x00000000004098b7 in yylex () at lex.yy.c:873
873                     *yy_cp = (yy_hold_char);

#
# Backtrace:
#
(gdb) bt
#0  0x00000000004098b7 in yylex () at lex.yy.c:873
#1  0x000000000040bf24 in xtpanel_scan (
    buffer=0x6564a0 "button={\n    label=\"  QUIT  \"\n    
background=lightblue\n}", root=0x6517d0) at xtpanel_scan.l:313
#2  0x0000000000405288 in parse_file (file=0x656260, root=0x6517d0)
    at parse.c:378
#3  0x000000000040518d in parse_file_named (filename=0x7fffffffe90f "test.xt", 
    root=0x6517d0, use_cpp=0, cpp_args=0x655e50 "") at parse.c:338
#4  0x000000000040465b in parse_args (argc=0, argv=0x7fffffffe5e0, 
    root=0x6517d0) at parse.c:167
#5  0x000000000041abc3 in xtp_init_app (argc=2, argv=0x7fffffffe5d0)
    at xtpanel_init.c:157
#6  0x0000000000403d42 in main (argc=3, argv=0x7fffffffe5c8) at main.c:53
NONSEPAR [^ \t\n\{\}]
WHITE    [ \t\n]
ALPHA    [A-Za-z]
ALPHANUM [A-Za-z0-9_-]
TAG     {ALPHA}{ALPHANUM}*=
TAGBRACE {ALPHA}{ALPHANUM}*=\{
SQ      \'([^']*\'\')*[^']*[']
DQ      \"([^"]*\"\")*[^"]*["]
BQ      \`([^`]*\`\`)*[^`]*[`]
LEFT    \{
RIGHT   \}

%{

/*
 * Copyright 1992 the Board of Trustees of the Leland Stanford Junior
 * University. Official permission to use this software is included in
 * the documentation. It authorizes you to use this file for any
 * non-commercial purpose, provided that this copyright notice is not
 * removed and that any modifications made to this file are commented
 * and dated in the style of the example below.
 */
 
/*
 *
 *  source file:   ./xtpanel/xtpanel-scan.l
 * 
 * Steve Cole, Dave Nichols (SEP), August 31 1992
 *      Inserted this sample edit history entry.
 *      Please log any further modifications made to this file:
 * Steve Cole, Dave Nichols (SEP), November 20 1992 -  version 2.00
 *      1) added new objects: toggle, scrollbar, graph.
 *      2) added new actions: ASSIGN, SET.
 *      3) objects can have multiple actions.
 *      4) backquoted strings in actions get executed at action time.
 * Steve Losen (s...@virginia.edu) 3 Mar 1993
 *      introduced `` as an escaped backquote.
 * Dave Nichols (SEP), Sept 2 1993 -  
 *      added support for using flex
 * Dave Nichols (SEP), Nov 16 1993 -  
 *      Use X11/Xos.h, this requires undefining "input" before
 *      the include as the X11 includes have a variable called input.
 * Dave Nichols (Geco-Prakla), Sept 29 1995 -  
 *      Don't redefine yylook as a macro, gcc complains about later
 *      definition.
 */

/* lexical scanning for xtpanel */

#define DEBUG 

#undef input

#include <ctype.h>
#include <stdio.h>
#include <string.h>

#include <X11/Xos.h>

#if defined(SVR4) || defined(SYSV)
#define bcopy(a,b,c) memcpy(b,a,c)
#endif

#include "tree.h"
#include "eval_command.h"

#ifndef MIN
#define MIN(A,B) (A<B?A:B)
#endif
#ifndef MAX
#define MAX(A,B) (A>B?A:B)
#endif

#define MAX_NEST 20
static int stack_ptr = -1;
static char *input_buf;
static char *input_buf_start;
static char *input_buf_end;

static entry *entry_stack[MAX_NEST];

#ifdef FLEX_SCANNER

/* one character at a time to ensure accurate error reporting */

#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) \
   { if( input_buf == input_buf_end+1 ) { \
        result=0; \
     }else{ \
        result=1;\
        *buf = *input_buf;\
        input_buf++; \
     } \
   }

/*        result = MIN( max_size, input_buf_end-input_buf+1 ); \ */
/*        bcopy(input_buf,buf,result); \ */
/*        input_buf += result; \ */
/*     }\ */
/*   } */

#undef yywrap

#else

#undef input
#define input() ((int) *(input_buf++))
#undef unput
/* The redundant  =(c) insures side effects of expressions occur */
#define unput(c) (*(--(input_buf))=(c))


/* define the look ahead buffer size to something big
 * This is needed in case they have a very big text 
 * string in quotes.
 */
#undef YYLMAX
#define YYLMAX 50000

char my_yytmp[YYLMAX];

#define yywrap xtpanel_wrap
#define yylex  xtpanel_lexscan
#define yylook xtpanel_yylook

#endif

entry *tree_ent;
entry *treetop;
int len;
int left=0;

static void syntax_err();
static int massage();

extern int bad_obj_syntax();
extern int bad_attr_syntax();

/* template check */
extern void new_template();

void template_check( a, b ) 
entry* a, *b;
{
if( !strcmp(a->tag,"template") && !strcmp(b->tag,"name" )) 
  new_template( b->value );
}


%}
%S FOUNDTAG 
%%
<FOUNDTAG>{SQ}          {
                         len = yyleng-2; tree_ent->value=malloc(len+1);
                         len = massage(yytext+1,tree_ent->value,len,yytext[0]);
                         tree_ent->value[len]='\0';  
                         add_child( treetop, tree_ent );
                         template_check( treetop, tree_ent );
#ifdef DEBUG
                         fprintf(stderr,"<FOUNDTAG>{SQ}\n");
                         fprintf(stderr,"%s\n",tree_ent->value);
#endif
                         BEGIN 0; 
                         }
<FOUNDTAG>{BQ}          { /* backquotes are now evaluated in get_value */
                         len=yyleng; tree_ent->value=malloc(len+1);
                         bcopy(yytext,tree_ent->value,len+1); 
                         tree_ent->value[len]='\0'; 
                         add_child( treetop, tree_ent );
                         template_check( treetop, tree_ent );
#ifdef DEBUG
                         fprintf(stderr,"<FOUNDTAG>{BQ}\n");
                         fprintf(stderr,"%s\n",tree_ent->value);
#endif
                         BEGIN 0; 
                         }
<FOUNDTAG>{DQ}          {
                         len = yyleng-2; tree_ent->value=malloc(len+1);
                         len = massage(yytext+1,tree_ent->value,len,yytext[0]);
                         tree_ent->value[len]='\0'; 
                         add_child( treetop, tree_ent );
                         template_check( treetop, tree_ent );
#ifdef DEBUG
                         fprintf(stderr,"<FOUNDTAG>{DQ}\n");
                         fprintf(stderr,"%s\n",tree_ent->value);
#endif
                         BEGIN 0; 
                         }
<FOUNDTAG>[^'"]{NONSEPAR}*      {
                         len=yyleng; tree_ent->value=malloc(len+1);
                         bcopy(yytext,tree_ent->value,len+1); 
                         tree_ent->value[len]='\0'; 
                         add_child( treetop, tree_ent );
                         template_check( treetop, tree_ent );
#ifdef DEBUG
                         fprintf(stderr,"<FOUNDTAG>{NONSEPAR}\n");
                         fprintf(stderr,"%s\n",tree_ent->value);
#endif
                         BEGIN 0; 
                         }
{TAGBRACE}             { /* start of a new level of braces */
                         tree_ent = new_entry( yytext, 
                                        get_taglen(yytext,yyleng-1));
                         /* check that this is a valid sublevel name */
                         if( bad_obj_syntax( treetop, tree_ent ) ){
                          syntax_err("Invalid tag name");
                         }
                         push_entry( tree_ent );
                         left++;
#ifdef DEBUG
                         fprintf(stderr,"{TAGBRACE}\n");
                         fprintf(stderr,"%s\n",tree_ent->tag);
#endif
                        }
([ \t]){TAGBRACE}       { /* start of a new level of braces */
                         tree_ent = new_entry( yytext+1, 
                                        get_taglen(yytext+1,yyleng-2));
                         /* check that this is a valid sublevel name */
                         if( bad_obj_syntax( treetop, tree_ent ) ){
                          syntax_err("Invalid tag name");
                         }
                         push_entry(tree_ent);
                         left++;
#ifdef DEBUG
                         fprintf(stderr,"[ \\t]{TAGBRACE}\n");
                         fprintf(stderr,"%s\n",tree_ent->tag);
#endif
                        }
{TAG}/{NONSEPAR}        {
                         tree_ent = new_entry( yytext, yyleng-1 );
                         /* check that this is a valid entry name */
                         if( bad_attr_syntax( treetop, tree_ent ) ){
                          syntax_err("Invalid tag name");
                         }
#ifdef DEBUG
                         fprintf(stderr,"{TAG}/{NONSEPAR}\n");
                         fprintf(stderr,"%s\n",tree_ent->tag);
#endif
                         BEGIN FOUNDTAG;
                         }
{TAG}{WHITE}            { /* an empty tag */
                          syntax_err("unexpected empty field ");
                         }
{RIGHT}                 { /* end of a level of braces */
                         pop_entry();
                         left--; 
#ifdef DEBUG
                         fprintf(stderr,"{RIGHT}\n");
#endif
                         if( left<0 ) {
                            syntax_err("unmatched right brace");
                         }
                        }
{LEFT}                  { /* found a left brace in the wrong context */
#ifdef DEBUG
                         fprintf(stderr,"{LEFT}\n");
#endif
                          syntax_err("left brace found in an unexpected place");
                        }
{WHITE}+                {
#ifdef DEBUG
                        fprintf(stderr,"Ignored whitespace\n");
                        fprintf(stderr,"length %d\n",yyleng);
#endif
                        }
^\![^\n]*               {/* skip comment lines */;
#ifdef DEBUG
                         fprintf(stderr,"Comment line\n");
#endif
                        }
\![^\n]*                        { /* comment not at start of line, allow for 
now */
#ifdef DEBUG
                        fprintf(stderr,"Trailing comment\n");
#endif
/*                      syntax_err("comment introducer not at start of line");*/
                        }
.                       {
#ifdef DEBUG
                        fprintf(stderr,"Something unrecognised\n");
#endif
                        syntax_err("unrecognisable construct");
                        }
%%


/* workhorse to decode xtpanel files; */

entry* xtpanel_scan( buffer, root )
char* buffer;
entry* root;
{
 extern int yylex();

#ifdef DEBUG
  fprintf(stderr,"xtpanel_scan\n%s\nxtpanel_scan_end\n",buffer);
#endif
 

 /* note the input buffer should be null terminated */
 input_buf = buffer;
 input_buf_start = input_buf;
 input_buf_end = input_buf + strlen(input_buf)-1 ;

 /* all the info we find will be stored under the root entry */
 push_entry( root );

#ifdef FLEX_SCANNER
 yy_init=1;
#endif

 yylex();
 if( left > 0 ) {
    fprintf(stderr," %d unmatched left braces present \n",left);
    exit(-1);
 }
 if( left < 0 ) {
    fprintf(stderr," %d unmatched right braces present \n",-left);
    exit(-1);
 }

}
/* get the tag length from a string that may have spaces around the equal */
int get_taglen( str, len )
char *str; int len;
{
char *temp;
int ret;
temp = malloc( len+1); strncpy( temp, str, len ); temp[len]='\0';
ret= strcspn( temp, " =" ) ;
free(temp);
return ret;
}


/* print a syntax error, try and give them enough context to figure
 * out where it is */
static void  syntax_err( message )
char *message;
{
    char temp[41];
    int lchar,rchar,nchar,i,j,linepos;

    /* print the error message */
    fprintf(stderr,"\nSyntax Error: %s\n\n", message);

    /* back up to the character causing the error */
    input_buf--; 

    /* print enough characters on either side to give he user some context*/
    lchar = MIN( 20, input_buf - input_buf_start );
    rchar = MIN( 20, input_buf_end - input_buf);
    nchar = lchar+rchar+1;
    strncpy( temp, (input_buf-lchar), nchar ); temp[nchar] = '\0';

    /* print stuff to the left of the point */
    for( i=0; i<lchar; i++ ){
        putc( temp[i], stderr );
        if( temp[i] == '\n' ){
           linepos=0;
        }else if( temp[i] == '\t' ){
           linepos += 8;
        }else{
           linepos++;
        }
    }

    /* print from the point up to the end or the next newline */
    for( i=lchar; ( i<nchar && temp[i] != '\n' ) ; i++ ){
        putc( temp[i], stderr );
    }

    /* print the marker that points at the error */
    putc( '\n', stderr );
    for( j=0; j<linepos; j++ ){ putc( ' ', stderr ); }
    fprintf(stderr,"^--- error detected at text ending here (I think)\n",temp);

    /* print the rest of the text (if any ) */
    for( j=i+1; j<nchar; j++ ){  putc( temp[j], stderr ); }
    putc( '\n', stderr );

    exit(-1);
}

push_entry( ent )
entry* ent;
{
if( stack_ptr >=0 ) add_child( entry_stack[stack_ptr], ent );
stack_ptr++;
if( stack_ptr >=MAX_NEST ){
   fprintf(stderr," items nested too deeply, only %d levels supported\n",
            MAX_NEST);
   exit(-1);
}
entry_stack[stack_ptr] = ent;
treetop = entry_stack[stack_ptr];
}


pop_entry()
{
stack_ptr--;
if( stack_ptr >= 0 ) treetop = entry_stack[stack_ptr] ;
}

int
yywrap()
{
    pop_entry();
    if(stack_ptr < 0) return(1);
    return(0);
} 


/* play with quoted strings and newlines etc. */
static int
massage(string,out,len,quote)
register char *string, *out;
register int len, quote;
{
  register int i,j;
  for(i=0,j=0; i<len-1; j++) {
    out[j]=string[i++];

    if(out[j]==quote) /* compress doubled quotes */
      if(string[i]==quote) i++;
    
    if(out[j]=='\\') {
      if(string[i]== 'n') { 
           /* turn backslash n "\n" into a newline */
           i++; out[j] = '\n';
      }else if( string[i] == '\n' ){ /* remove backslash newline */
           i++; j--;
      }
    }
    
  }
  if(i<len) out[j++] = string[i];
  return(j);
}
button={
    label="  QUIT  "
    background=lightblue
}
   
_______________________________________________
help-flex mailing list
help-flex@gnu.org
https://lists.gnu.org/mailman/listinfo/help-flex

Reply via email to