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 .
24 #if (defined(_WIN32) || defined(__IBMC__))
32 static char wbuf
[4 * OBS
];
33 static char *wbp
= wbuf
;
34 static int EBCDIC_ExternTokenDetected
= 0;
35 static int EBCDIC_StartTokenDetected
= 0;
37 unsigned char toLatin1
[256] =
39 0x00, 0x01, 0x02, 0x03, 0x9c, 0x09, 0x86, 0x7f, 0x97, 0x8d,
40 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
41 0x9d, 0x0a, 0x08, 0x87, 0x18, 0x19, 0x92, 0x8f, 0x1c, 0x1d,
42 0x1e, 0x1f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1b,
43 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, 0x90, 0x91,
44 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, 0x98, 0x99, 0x9a, 0x9b,
45 0x14, 0x15, 0x9e, 0x1a, 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1,
46 0xe3, 0xe5, 0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c,
47 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, 0xec, 0xdf,
48 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, 0x2d, 0x2f, 0xc2, 0xc4,
49 0xc0, 0xc1, 0xc3, 0xc5, 0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f,
50 0x3e, 0x3f, 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf,
51 0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22,
52 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
53 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, 0xb0, 0x6a, 0x6b, 0x6c,
54 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8,
55 0xc6, 0xa4, 0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
56 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae, 0xac, 0xa3,
57 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, 0xbd, 0xbe, 0xdd, 0xa8,
58 0xaf, 0x5d, 0xb4, 0xd7, 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45,
59 0x46, 0x47, 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5,
60 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52,
61 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff, 0x5c, 0xf7, 0x53, 0x54,
62 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2,
63 0xd3, 0xd5, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
64 0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f
70 memcpy_EBCDIC( char * pwbuf
, uchar
*p
, int len
)
73 int processedchars
= 0;
84 /* copy spaces until " or ' */
85 while( (p
[ processedchars
] != '\"') && (p
[ processedchars
] != '\'') )
86 pwbuf
[ currpos
++ ] = p
[ processedchars
++ ];
88 /* copy first " or ' */
89 pwbuf
[ currpos
++ ] = p
[ processedchars
++ ];
91 /* convert all characters until " or ' */
92 while( processedchars
< (len
- 1) )
94 if( p
[ processedchars
] == '\\' )
96 switch( p
[ ++processedchars
] )
99 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\n'] );
104 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\t'] );
109 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\v'] );
114 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\b'] );
119 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\r'] );
124 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\f'] );
129 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\a'] );
134 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\\'] );
139 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\?'] );
144 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\''] );
149 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
['\"'] );
153 /* octal coded character? -> copy */
163 int startpos
= currpos
;
165 pwbuf
[ currpos
++ ] = '\\';
167 while( p
[ processedchars
] >= '0' && p
[ processedchars
] <= '7' && (currpos
< startpos
+ 4) )
168 pwbuf
[ currpos
++ ] = (unsigned char)p
[ processedchars
++ ];
172 /* hex coded character? -> copy */
176 int startpos
= currpos
;
178 pwbuf
[ currpos
++ ] = '\\';
179 pwbuf
[ currpos
++ ] = 'x';
182 while( isxdigit( p
[ processedchars
] ) && (currpos
< startpos
+ 4) )
183 pwbuf
[ currpos
++ ] = (unsigned char)p
[ processedchars
++ ];
190 currpos
+= sprintf( &pwbuf
[ currpos
], MASK
, toLatin1
[p
[ processedchars
++ ]] );
194 /* copy last " or ' */
195 pwbuf
[ currpos
++ ] = p
[ processedchars
];
201 maketokenrow(int size
, Tokenrow
* trp
)
205 trp
->bp
= (Token
*) domalloc(size
* sizeof(Token
));
213 growtokenrow(Tokenrow
* trp
)
215 size_t ncur
= trp
->tp
- trp
->bp
;
216 size_t nlast
= trp
->lp
- trp
->bp
;
218 trp
->max
= 3 * trp
->max
/ 2 + 1;
219 trp
->bp
= (Token
*) realloc(trp
->bp
, trp
->max
* sizeof(Token
));
220 trp
->lp
= &trp
->bp
[nlast
];
221 trp
->tp
= &trp
->bp
[ncur
];
226 * Compare a row of tokens, ignoring the content of WS; return !=0 if different
229 comparetokens(Tokenrow
* tr1
, Tokenrow
* tr2
)
235 if (tr1
->lp
- tp1
!= tr2
->lp
- tp2
)
237 for (; tp1
< tr1
->lp
; tp1
++, tp2
++)
239 if (tp1
->type
!= tp2
->type
240 || (tp1
->wslen
== 0) != (tp2
->wslen
== 0)
241 || tp1
->len
!= tp2
->len
242 || strncmp((char *) tp1
->t
, (char *) tp2
->t
, tp1
->len
) != 0)
249 * replace ntok tokens starting at dtr->tp with the contents of str.
250 * tp ends up pointing just beyond the replacement.
251 * Canonical whitespace is assured on each side.
254 insertrow(Tokenrow
* dtr
, int ntok
, Tokenrow
* str
)
256 int nrtok
= (int)rowlen(str
);
259 adjustrow(dtr
, nrtok
- ntok
);
261 movetokenrow(dtr
, str
);
266 * make sure there is WS before trp->tp, if tokens might merge in the output
269 makespace(Tokenrow
* trp
, Token
* ntp
)
279 tt
= newstring(tp
->t
, tp
->len
, ntp
->wslen
);
280 strncpy((char *)tt
, (char *)ntp
->t
- ntp
->wslen
, ntp
->wslen
);
281 tp
->t
= tt
+ ntp
->wslen
;
282 tp
->wslen
= ntp
->wslen
;
288 * Copy an entire tokenrow into another, at tp.
289 * It is assumed that there is enough space.
290 * Not strictly conforming.
293 movetokenrow(Tokenrow
* dtr
, Tokenrow
* str
)
297 nby
= (char *) str
->lp
- (char *) str
->bp
;
298 memmove(dtr
->tp
, str
->bp
, nby
);
302 * Move the tokens in a row, starting at tr->tp, rightward by nt tokens;
303 * nt may be negative (left move).
304 * The row may need to be grown.
305 * Non-strictly conforming because of the (char *), but easily fixed
308 adjustrow(Tokenrow
* trp
, int nt
)
314 size
= (trp
->lp
- trp
->bp
) + nt
;
315 while (size
> trp
->max
)
317 nby
= (char *) trp
->lp
- (char *) trp
->tp
;
319 memmove(trp
->tp
+ nt
, trp
->tp
, nby
);
324 * Copy a row of tokens into the destination holder, allocating
325 * the space for the contents. Return the destination.
328 copytokenrow(Tokenrow
* dtr
, Tokenrow
* str
)
330 int len
= (int)rowlen(str
);
332 maketokenrow(len
, dtr
);
333 movetokenrow(dtr
, str
);
339 * Produce a copy of a row of tokens. Start at trp->tp.
340 * The value strings are copied as well. The first token
344 normtokenrow(Tokenrow
* trp
)
347 Tokenrow
*ntrp
= new(Tokenrow
);
350 len
= (int)(trp
->lp
- trp
->tp
);
353 maketokenrow(len
, ntrp
);
354 for (tp
= trp
->tp
; tp
< trp
->lp
; tp
++)
359 ntrp
->lp
->t
= newstring(tp
->t
, tp
->len
, 1);
360 *ntrp
->lp
->t
++ = ' ';
366 if (ntrp
->lp
> ntrp
->bp
)
375 peektokens(Tokenrow
* trp
, char *str
)
382 fprintf(stderr
, "%s ", str
);
383 if (tp
< trp
->bp
|| tp
> trp
->lp
)
384 fprintf(stderr
, "(tp offset %ld) ", (long int) (tp
- trp
->bp
));
385 for (tp
= trp
->bp
; tp
< trp
->lp
&& tp
< trp
->bp
+ 32; tp
++)
389 int c
= tp
->t
[tp
->len
];
392 fprintf(stderr
, "%s", tp
->t
);
393 tp
->t
[tp
->len
] = (uchar
) c
;
395 fprintf(stderr
, tp
== trp
->tp
? "{%x*} " : "{%x} ", tp
->type
);
397 fprintf(stderr
, "\n");
402 puttokens(Tokenrow
* trp
)
411 for (; tp
< trp
->lp
; tp
++)
415 len
= (int)(tp
->len
+ tp
->wslen
);
416 p
= tp
->t
- tp
->wslen
;
418 /* add parameter check to delete operator? */
421 if( (tp
->type
== NAME
) && (strncmp( (char*)p
, "delete", len
) == 0) )
426 if( ntp
->type
== NAME
)
428 uchar
* np
= ntp
->t
- ntp
->wslen
;
429 int nlen
= (int)(ntp
->len
+ ntp
->wslen
);
431 memcpy(wbp
, "if(", 3 );
433 memcpy(wbp
, np
, nlen
);
435 memcpy(wbp
, ")", 1 );
443 /* EBCDIC to ANSI conversion requested? */
446 /* keyword __ToLatin1__ found? -> do conversion! */
447 if( EBCDIC_StartTokenDetected
)
449 /* previous token was 'extern'? -> don't convert current token! */
450 if( EBCDIC_ExternTokenDetected
)
452 EBCDIC_ExternTokenDetected
= 0;
457 /* current token is keyword 'extern'? -> don't convert following token! */
458 if( (tp
->wslen
== 0) && (strncmp( (char*)p
, "extern", len
) == 0) )
460 EBCDIC_ExternTokenDetected
= 1;
465 /* token is string or char? -> process EBCDIC to ANSI conversion */
466 if ((tp
->type
== STRING
) || (tp
->type
== CCON
))
467 len
= memcpy_EBCDIC(wbp
, p
, len
);
474 /* keyword __ToLatin1__ found? -> don't copy keyword and start conversion */
475 if( (tp
->type
== NAME
) && (strncmp( (char*)p
, "__ToLatin1__", len
) == 0) )
477 EBCDIC_StartTokenDetected
= 1;
491 if (wbp
>= &wbuf
[OBS
])
493 if ( write(1, wbuf
, OBS
) != -1 ) {
494 if (wbp
> &wbuf
[OBS
])
495 memmove(wbuf
, wbuf
+ OBS
, wbp
- &wbuf
[OBS
]);
502 if (cursource
->fd
== 0)
511 if ( write(1, wbuf
, (int)(wbp
- wbuf
)) != -1)
519 * turn a row into just a newline
522 setempty(Tokenrow
* trp
)
525 trp
->lp
= trp
->bp
+ 1;
533 outnum(char *p
, int n
)
536 p
= outnum(p
, n
/ 10);
537 *p
++ = (char) (n
% 10 + '0');
542 * allocate and initialize a new string from s, of length l, at offset o
546 newstring(uchar
* s
, size_t l
, size_t o
)
548 uchar
*ns
= (uchar
*) domalloc(l
+ o
+ 1);
551 return (uchar
*) strncpy((char *) ns
+ o
, (char *) s
, l
) - o
;
554 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */