1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
25 #if (defined(_WIN32) || defined(__IBMC__))
33 static char wbuf
[4 * OBS
];
34 static char *wbp
= wbuf
;
35 static int EBCDIC_ExternTokenDetected
= 0;
36 static int EBCDIC_StartTokenDetected
= 0;
38 static unsigned char toLatin1
[256] =
40 0x00, 0x01, 0x02, 0x03, 0x9c, 0x09, 0x86, 0x7f, 0x97, 0x8d,
41 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
42 0x9d, 0x0a, 0x08, 0x87, 0x18, 0x19, 0x92, 0x8f, 0x1c, 0x1d,
43 0x1e, 0x1f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1b,
44 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, 0x90, 0x91,
45 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, 0x98, 0x99, 0x9a, 0x9b,
46 0x14, 0x15, 0x9e, 0x1a, 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1,
47 0xe3, 0xe5, 0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c,
48 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, 0xec, 0xdf,
49 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, 0x2d, 0x2f, 0xc2, 0xc4,
50 0xc0, 0xc1, 0xc3, 0xc5, 0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f,
51 0x3e, 0x3f, 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf,
52 0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22,
53 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
54 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, 0xb0, 0x6a, 0x6b, 0x6c,
55 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8,
56 0xc6, 0xa4, 0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
57 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae, 0xac, 0xa3,
58 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, 0xbd, 0xbe, 0xdd, 0xa8,
59 0xaf, 0x5d, 0xb4, 0xd7, 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45,
60 0x46, 0x47, 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5,
61 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52,
62 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff, 0x5c, 0xf7, 0x53, 0x54,
63 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2,
64 0xd3, 0xd5, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
65 0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f
71 memcpy_EBCDIC( char * pwbuf
, uchar
const *p
, int len
)
74 int processedchars
= 0;
85 /* copy spaces until " or ' */
86 while( (p
[ processedchars
] != '\"') && (p
[ processedchars
] != '\'') )
87 pwbuf
[ currpos
++ ] = p
[ processedchars
++ ];
89 /* copy first " or ' */
90 pwbuf
[ currpos
++ ] = p
[ processedchars
++ ];
92 /* convert all characters until " or ' */
93 while( processedchars
< (len
- 1) )
95 if( p
[ processedchars
] == '\\' )
97 switch( p
[ ++processedchars
] )
100 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\n'] );
105 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\t'] );
110 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\v'] );
115 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\b'] );
120 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\r'] );
125 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\f'] );
130 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\a'] );
135 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\\'] );
140 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\?'] );
145 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\''] );
150 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\"'] );
154 /* octal coded character? -> copy */
164 int startpos
= currpos
;
166 pwbuf
[ currpos
++ ] = '\\';
168 while( p
[ processedchars
] >= '0' && p
[ processedchars
] <= '7' && (currpos
< startpos
+ 4) )
169 pwbuf
[ currpos
++ ] = (unsigned char)p
[ processedchars
++ ];
173 /* hex coded character? -> copy */
177 int startpos
= currpos
;
179 pwbuf
[ currpos
++ ] = '\\';
180 pwbuf
[ currpos
++ ] = 'x';
183 while( isxdigit( p
[ processedchars
] ) && (currpos
< startpos
+ 4) )
184 pwbuf
[ currpos
++ ] = (unsigned char)p
[ processedchars
++ ];
191 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
[p
[ processedchars
++ ]] );
195 /* copy last " or ' */
196 pwbuf
[ currpos
++ ] = p
[ processedchars
];
202 maketokenrow(int size
, Tokenrow
* trp
)
206 trp
->bp
= (Token
*) domalloc(size
* sizeof(Token
));
214 growtokenrow(Tokenrow
* trp
)
216 size_t ncur
= trp
->tp
- trp
->bp
;
217 size_t nlast
= trp
->lp
- trp
->bp
;
219 trp
->max
= 3 * trp
->max
/ 2 + 1;
220 trp
->bp
= (Token
*) realloc(trp
->bp
, trp
->max
* sizeof(Token
));
221 assert(trp
->bp
); // realloc failure is OOM -> no point to handle
222 trp
->lp
= &trp
->bp
[nlast
];
223 trp
->tp
= &trp
->bp
[ncur
];
228 * Compare a row of tokens, ignoring the content of WS; return !=0 if different
231 comparetokens(Tokenrow
* tr1
, Tokenrow
* tr2
)
237 if (tr1
->lp
- tp1
!= tr2
->lp
- tp2
)
239 for (; tp1
< tr1
->lp
; tp1
++, tp2
++)
241 if (tp1
->type
!= tp2
->type
242 || (tp1
->wslen
== 0) != (tp2
->wslen
== 0)
243 || tp1
->len
!= tp2
->len
244 || strncmp((char *) tp1
->t
, (char *) tp2
->t
, tp1
->len
) != 0)
251 * replace ntok tokens starting at dtr->tp with the contents of str.
252 * tp ends up pointing just beyond the replacement.
253 * Canonical whitespace is assured on each side.
256 insertrow(Tokenrow
* dtr
, int ntok
, Tokenrow
const * str
)
258 int nrtok
= (int)rowlen(str
);
261 adjustrow(dtr
, nrtok
- ntok
);
263 movetokenrow(dtr
, str
);
268 * make sure there is WS before trp->tp, if tokens might merge in the output
271 makespace(Tokenrow
* trp
, Token
const * ntp
)
281 tt
= newstring(tp
->t
, tp
->len
, ntp
->wslen
);
282 strncpy((char *)tt
, (char *)ntp
->t
- ntp
->wslen
, ntp
->wslen
);
283 tp
->t
= tt
+ ntp
->wslen
;
284 tp
->wslen
= ntp
->wslen
;
289 * Copy an entire tokenrow into another, at tp.
290 * It is assumed that there is enough space.
291 * Not strictly conforming.
294 movetokenrow(Tokenrow
* dtr
, Tokenrow
const * str
)
298 nby
= (char *) str
->lp
- (char *) str
->bp
;
300 memmove(dtr
->tp
, str
->bp
, nby
);
304 * Move the tokens in a row, starting at tr->tp, rightward by nt tokens;
305 * nt may be negative (left move).
306 * The row may need to be grown.
307 * Non-strictly conforming because of the (char *), but easily fixed
310 adjustrow(Tokenrow
* trp
, int nt
)
316 size
= (trp
->lp
- trp
->bp
) + nt
;
317 while (size
> trp
->max
)
319 nby
= (char *) trp
->lp
- (char *) trp
->tp
;
321 memmove(trp
->tp
+ nt
, trp
->tp
, nby
);
326 * Copy a row of tokens into the destination holder, allocating
327 * the space for the contents. Return the destination.
330 copytokenrow(Tokenrow
* dtr
, Tokenrow
const * str
)
332 int len
= (int)rowlen(str
);
334 maketokenrow(len
, dtr
);
335 movetokenrow(dtr
, str
);
342 * Produce a copy of a row of tokens. Start at trp->tp.
343 * The value strings are copied as well. The first token
347 normtokenrow(Tokenrow
* trp
)
350 Tokenrow
*ntrp
= new(Tokenrow
);
353 len
= (int)(trp
->lp
- trp
->tp
);
356 maketokenrow(len
, ntrp
);
357 for (tp
= trp
->tp
; tp
< trp
->lp
; tp
++)
362 ntrp
->lp
->t
= newstring(tp
->t
, tp
->len
, 1);
363 *ntrp
->lp
->t
++ = ' ';
369 if (ntrp
->lp
> ntrp
->bp
)
378 peektokens(Tokenrow
* trp
, char *str
)
385 fprintf(stderr
, "%s ", str
);
386 if (tp
< trp
->bp
|| tp
> trp
->lp
)
387 fprintf(stderr
, "(tp offset %ld) ", (long int) (tp
- trp
->bp
));
388 for (tp
= trp
->bp
; tp
< trp
->lp
&& tp
< trp
->bp
+ 32; tp
++)
392 int c
= tp
->t
[tp
->len
];
395 fprintf(stderr
, "%s", tp
->t
);
396 tp
->t
[tp
->len
] = (uchar
) c
;
398 fprintf(stderr
, tp
== trp
->tp
? "{%x*} " : "{%x} ", tp
->type
);
400 fprintf(stderr
, "\n");
405 puttokens(Tokenrow
* trp
)
414 for (; tp
< trp
->lp
; tp
++)
418 len
= (int)(tp
->len
+ tp
->wslen
);
419 p
= tp
->t
- tp
->wslen
;
421 /* add parameter check to delete operator? */
424 if( (tp
->type
== NAME
) && (strncmp( (char*)p
, "delete", len
) == 0) )
429 if( ntp
->type
== NAME
)
431 uchar
* np
= ntp
->t
- ntp
->wslen
;
432 int nlen
= (int)(ntp
->len
+ ntp
->wslen
);
434 memcpy(wbp
, "if(", 3 );
436 memcpy(wbp
, np
, nlen
);
438 memcpy(wbp
, ")", 1 );
446 /* EBCDIC to ANSI conversion requested? */
449 /* keyword __ToLatin1__ found? -> do conversion! */
450 if( EBCDIC_StartTokenDetected
)
452 /* previous token was 'extern'? -> don't convert current token! */
453 if( EBCDIC_ExternTokenDetected
)
455 EBCDIC_ExternTokenDetected
= 0;
460 /* current token is keyword 'extern'? -> don't convert following token! */
461 if( (tp
->wslen
== 0) && (strncmp( (char*)p
, "extern", len
) == 0) )
463 EBCDIC_ExternTokenDetected
= 1;
468 /* token is string or char? -> process EBCDIC to ANSI conversion */
469 if ((tp
->type
== STRING
) || (tp
->type
== CCON
))
470 len
= memcpy_EBCDIC(wbp
, p
, len
);
477 /* keyword __ToLatin1__ found? -> don't copy keyword and start conversion */
478 if( (tp
->type
== NAME
) && (strncmp( (char*)p
, "__ToLatin1__", len
) == 0) )
480 EBCDIC_StartTokenDetected
= 1;
494 if (wbp
>= &wbuf
[OBS
])
496 if ( write(1, wbuf
, OBS
) != -1 ) {
497 if (wbp
> &wbuf
[OBS
])
498 memmove(wbuf
, wbuf
+ OBS
, wbp
- &wbuf
[OBS
]);
505 if (cursource
->fd
== 0)
514 if ( write(1, wbuf
, (int)(wbp
- wbuf
)) != -1)
522 * turn a row into just a newline
525 setempty(Tokenrow
* trp
)
528 trp
->lp
= trp
->bp
+ 1;
536 outnum(char *p
, int n
)
539 p
= outnum(p
, n
/ 10);
540 *p
++ = (char) (n
% 10 + '0');
545 * allocate and initialize a new string from s, of length l, at offset o
549 newstring(uchar
const * s
, size_t l
, size_t o
)
551 uchar
*ns
= (uchar
*) domalloc(l
+ o
+ 1);
554 return (uchar
*) strncpy((char *) ns
+ o
, (char *) s
, l
) - o
;
557 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */