source: trunk/pin/include/p2putil.ch@ 1

Last change on this file since 1 was 1, checked in by bart, 18 years ago

Initial checkin of PIN.EXE source code
this contains memory fixes for larger PPD files

File size: 19.2 KB
Line 
1// included into convert.c
2// utility functions
3
4/*
5** D74609
6*/
7/***************************************************************************
8 *
9 * FUNCTION NAME = roundImgAreaVals
10 *
11 * DESCRIPTION = Used for the *ImageableArea key. This function either
12 * rounds the floating point value to the nearest integer, or
13 * truncates the floating point value to the base integer.
14 * The new integer value is stored in the output buffer.
15 *
16 * INPUT = i - Offset to the input buffer where the floating point
17 * string is read.
18 * fIncFrac - Contains one of the following values:
19 * TRUNCATE_FLOAT - Truncate the floating point value to the
20 * base integer (i.e. 25.2 -> 25, 14.8 -> 14).
21 * ROUND_FLOAT - Rounds the floating point value to the next
22 * higher integer value, providing that there is a fractional
23 * value (i.e 25.1 -> 26, 79.8 -> 80, 15.0 -> 15, 4.0 -> 4).
24 * Any other value will yield unpredictable results.
25 * cMovePastChar - Character value that is passed on to
26 * MovePast to indicate what character to move past on the
27 * buffer. For this function's first call, the argument
28 * is usually '"' (quote), and most subsequent calls are ' '
29 * (space).
30 *
31 * OUTPUT = NONE.
32 *
33 * RETURN-NORMAL = Returns the latest offset (passed in from i above).
34 * RETURN-ERROR = NONE.
35 *
36 ************************************************************************* */
37VOID roundImgAreaVals(int *i, float fIncFrac, CHAR cMovePastChar )
38{
39 USHORT j;
40
41 *i += MovePast( pbPrBuffer + *i, cMovePastChar );
42
43 /*
44 ** @V2.187860
45 ** Since spaces are used as terminators in this function, a leading space
46 ** may cause the string offset to stop before skipping to the next value.
47 ** By removing all leading spaces, this ensures that the string offset moves
48 ** to the next value.
49 */
50 /*
51 ** @V3.0100963
52 ** Check for all valid spaces, not just for the whitespace. This is to
53 ** prevent a repeat performance in what was happening with MovePast().
54 */
55 while (isspace( *(pbPrBuffer + *i) ) )
56 {
57 (*i)++;
58 }
59
60 /*
61 ** For the imageable area, only the integer value is to be stored. By
62 ** adding a fraction (fIncFrac) to the whole number taken from the PPD, it
63 ** either increase the integer value by one, or keep the integer unchanged.
64 ** Then the fraction can be discarded (convert it to a USHORT).
65 */
66 j = (USHORT) (atof( pbPrBuffer + *i ) + fIncFrac);
67
68 memcpy((pbItemsBuffer + cbBuffout), (PCHAR) &j, sizeof( USHORT ) );
69 cbBuffout += sizeof( USHORT );
70}
71
72
73
74/***************************************************************************
75 *
76 * FUNCTION NAME = atoRound
77 *
78 * DESCRIPTION = rounds off a fractional number to nearest integer
79 *
80 * INPUT = pchBuffer - pointer to buffer containing number
81 *
82 * OUTPUT = NONE.
83 *
84 * RETURN-NORMAL = NONE.
85 * RETURN-ERROR = NONE.
86 *
87 ************************************************************************* */
88
89int atoRound( char *pchBuffer )
90{
91 int i;
92
93 i = atoi( pchBuffer );
94
95 while (*pchBuffer >= '0' && *pchBuffer <= '9')
96 {
97 pchBuffer++;
98 }
99
100 if (*pchBuffer == '.')
101 {
102 pchBuffer++;
103
104 if (*pchBuffer >= '5')
105 {
106 i++;
107 }
108 }
109 return( i );
110}
111
112/***************************************************************************
113 *
114 * FUNCTION NAME = RepWarning
115 *
116 * DESCRIPTION = prints the given message (pszMsg) with the given
117 * line fragment (pszLine), including the current
118 * input line number. If line fragment is NULL, then
119 * only the message is displayed.
120 *
121 * INPUT = err - error number
122 * pszLine - optional text
123 *
124 * OUTPUT = NONE.
125 *
126 * RETURN-NORMAL = NONE.
127 * RETURN-ERROR = NONE.
128 *
129 ************************************************************************* */
130
131VOID RepWarning( ErrType err, char *pszLine )
132{
133 printf( "%s", szErrmsgs[err] );
134
135 if (pszLine)
136 {
137 printf( " %s", pszLine );
138 }
139}
140
141/***************************************************************************
142 *
143 * FUNCTION NAME = RepError
144 *
145 * DESCRIPTION = Same as RepWarning, but terminates as well.
146 *
147 * INPUT = err - error number
148 * pszLine - optional text
149 *
150 * OUTPUT = NONE.
151 *
152 * RETURN-NORMAL = NONE.
153 * RETURN-ERROR = NONE.
154 *
155 ************************************************************************* */
156
157VOID RepError( ErrType err, char *pszLine )
158{
159 RepWarning( err, pszLine );
160 exit( 1 );
161}
162
163/***************************************************************************
164 *
165 * FUNCTION NAME = SkipNumber
166 *
167 * DESCRIPTION = This routine moves the input buffer pointer forward
168 * to skip the next number. Returns the number of bytes
169 * skipped.
170 *
171 * INPUT = pszLine - line to skip
172 * OUTPUT = NONE.
173 *
174 * RETURN-NORMAL = NONE.
175 * RETURN-ERROR = NONE.
176 *
177 ************************************************************************* */
178
179int SkipNumber( char *pszLine )
180{
181 int i;
182
183 i = SkipBlank( pszLine );
184
185 if (*(pszLine+i) == '+' || *(pszLine+i) == '-' || *(pszLine+i) == '.')
186 {
187 i++;
188 }
189
190 while (*(pszLine+i) >= '0' && *(pszLine+i) <= '9')
191 {
192 i++;
193 }
194
195 if (*(pszLine + i) == '.')
196 {
197 i++;
198
199 while (*(pszLine+i) >= '0' && *(pszLine+i) <= '9')
200 {
201 i++;
202 }
203 }
204 return( i );
205}
206
207/***************************************************************************
208 *
209 * FUNCTION NAME = SkipBlank
210 *
211 * DESCRIPTION = This routine moves the input buffer pointer forward
212 * to the next non-white character. Returns the
213 * number of bytes skipped.
214 *
215 * INPUT = pszLine - line to skip
216 *
217 * OUTPUT = NONE.
218 *
219 * RETURN-NORMAL = NONE.
220 * RETURN-ERROR = NONE.
221 *
222 ************************************************************************* */
223
224int SkipBlank( char *pszLine )
225{
226 int i;
227
228 i = 0;
229
230 while (*(pszLine+i) && (*(pszLine+i) == ' ' || *(pszLine+i) == '\t'))
231 {
232 i++;
233 }
234 return( i );
235}
236
237/***************************************************************************
238 *
239 * FUNCTION NAME = MovePast
240 *
241 * DESCRIPTION = This routine returns the offset to skip past the
242 * first occurrence of character chSkip.
243 *
244 * INPUT = pbBuffer - pointer to buffer containing text
245 * chSkip - character to skip
246 *
247 * OUTPUT = NONE.
248 *
249 * RETURN-NORMAL = NONE.
250 * RETURN-ERROR = NONE.
251 *
252 ************************************************************************* */
253
254int MovePast( char *pbBuffer, char chSkip )
255{
256 int i;
257
258 i = 0;
259
260 /*
261 ** @V2.1100963
262 ** Check for tab characters (0x09) as well as whitespaces. Theoretically, it
263 ** would be easier to replace the ' ' and 0x09 check with isspace(), but
264 ** to make things safer, just add the 0x09 check (with the excpetion of the
265 ** HP 4V, it has been working up to now. We don't want to possibly break
266 ** another PPD by replacing with isspace() ).
267 */
268 /*
269 ** GP@SWHT Defect 225880
270 ** We have 10 ppd's where are used TAB (0x09) instead of space
271 ** So if MovePast is searching for space, search also for TAB char.
272 */
273 while ( ( *(pbBuffer+i) != chSkip ) &&
274 ( *(pbBuffer+i) != 0x09 || chSkip != ' ' ) && // GP@SWHT D225880
275 ( *(pbBuffer+i) >= ' ' || *(pbBuffer+i) == 0x09 )
276 )
277 {
278 i++;
279 }
280 i++;
281
282 // @V3.OEM There may be more than one blank in the PPD file, so get
283 // past all of them
284 while ( ( *(pbBuffer+i) == chSkip) ||
285 ( *(pbBuffer+i) == 0x09 && chSkip == ' ' ) // GP@SWHT D225880
286 )
287 {
288 i++;
289 }
290 return( i );
291}
292
293
294/*
295** @V2.177675
296** This function previously copied the quoted contents to a destination buffer
297** and stored the string length in the first byte. Now, this function does a
298** standard NULL-terminated string copy for the contents within the quotes.
299*/
300/*
301** @V3.0129238
302** Include the forward slash ('/') as a delimeter if bIncludeSlash is TRUE.
303** If bIncludeSlash is FALSE, do not include the forward slash as a
304** delimiter.
305*/
306/***************************************************************************
307 *
308 * FUNCTION NAME = CopyString
309 *
310 * DESCRIPTION = This routine copies a string from source to
311 * destination with delimiters as a double Quote,
312 * blank, colon, or forward slash (optional). The string
313 * is NULL terminated.
314 *
315 * INPUT = szDestn - destination string
316 * szSource - source string
317 * iMaxLen - length of destination string
318 * uiOpt - Options for copying //@V4.HexChar
319 * CSTR_NORMAL
320 * CSTR_INCLUDE_SLASH - Include the forward slash ('/')
321 * as a delimiter.
322 * CSTR_HEX2CHAR - Convert hex <e1> strings to chars.
323 * CSTR_EXCLUDE_DQUOTE- Exclude the double quote (")
324 * as a delimiter. GP@SWHT
325 *
326 * OUTPUT = NONE.
327 *
328 * RETURN-NORMAL = Number of characters in the copied string.
329 * RETURN-ERROR = NONE.
330 *
331 ************************************************************************* */
332
333int CopyString(char *szDestn, char *szSource, int iMaxlen, UINT uiOpt)
334{
335 int i,j;
336
337 int fInHex; // flag, if we currently are processing hex string
338
339 // these variables keep state in case we have to abort hex string conversion
340 // (if it's actually not hex string, just <some string>...
341 int iHexRollbackSrc;
342 int iHexRollbackDest;
343 int iHexDigits;
344
345 char chHex;
346
347 char *str_in;
348 char *str_out;
349
350
351
352 iMaxlen--; /* maxlen is actually 1 based, i is a 0 based index, if you hit the max
353 * then add a NULL you may have a memory violation, so adjust by 1 [wgs] */
354
355 if (!(*szSource)) /* if the string is empty, do nothing */
356 return(0);
357
358
359 i = 0;
360 j = 0;
361 str_in = szSource;
362 str_out = szDestn;
363
364 fInHex = FALSE;
365
366
367 /* @V4.HexChar Begin
368 ** OldCode
369 ** while (*szSource && *szSource != '"' && (*szSource >= ' ' || *szSource < 0) &&
370 ** *szSource != ':' && ((bIncludeSlash == TRUE && *szSource != '/') ||
371 ** bIncludeSlash != TRUE) && i < iMaxlen)
372 ** {
373 ** *(szDestn + i++) = *(szSource++);
374 ** }
375 **
376 ** New Code translates also hex strings <e1> to chars
377 ** if CSTR_HEX2CHAR is set.
378 */
379
380 while ( str_in[i] &&
381 (str_in[i] != '"' || (uiOpt & CSTR_EXCLUDE_DQUOTE) ) &&
382 (str_in[i] >= ' ' || str_in[i] < 0) &&
383 str_in[i] != ':' &&
384 ( ( (uiOpt & CSTR_INCLUDE_SLASH) && str_in[i] != '/') ||
385 !(uiOpt & CSTR_INCLUDE_SLASH) )
386 && j < iMaxlen)
387 {
388 if ( uiOpt & CSTR_HEX2CHAR )
389 {
390
391 //@HEXSTR fix hex string parsing code to support PPD standard.
392 //
393 // note: very similar code is countained in charstr.c::ConvertCharset
394 // if you fix a bug here, don't forget to fix it there too.
395 //
396
397 if( !fInHex && str_in[i]=='<' )
398 {
399 // this might be the beginning of <hex> string
400
401 fInHex = TRUE;
402 iHexRollbackSrc = i;
403 iHexRollbackDest = j;
404 iHexDigits = 0;
405 i++;
406 continue;
407 }
408 else if( fInHex && str_in[i]=='>' )
409 {
410 // hex string is terminated
411
412 if( iHexDigits )
413 {
414 // this string is error, rollback
415 i = iHexRollbackSrc;
416 j = iHexRollbackDest;
417
418 // get over the '<' character
419 str_out[j]=str_in[i];
420 i++;
421 j++;
422
423 // just go on copying
424 }
425 else
426 {
427 i++;
428 }
429
430 fInHex = FALSE;
431 iHexDigits = 0;
432 continue;
433 }
434 else if( fInHex )
435 {
436 // processing the hex string
437
438 char ch = str_in[i];
439
440 // check if it's acceptable hex char
441
442 if( ch >= '0' && ch<='9' )
443 {
444 chHex = (chHex << 4) | (ch - '0');
445 iHexDigits++;
446 }
447 else if( ch >= 'a' && ch<='f' )
448 {
449 chHex = (chHex << 4) | (ch - 'a' + 0xA);
450 iHexDigits++;
451 }
452 else if( ch >= 'A' && ch<='F' )
453 {
454 chHex = (chHex << 4) | (ch - 'A' + 0xA);
455 iHexDigits++;
456 }
457 else if( ch == ' ' || ch == '\t' )
458 {
459 // these are acceptable chars, must be ignored
460 // (note: this is different from charset.c processing
461 // where they would be copied verbatim !)
462
463 ; // do nothing
464 }
465 else
466 {
467 // just bail, return to copying the string as if hex mode never happened
468 i = iHexRollbackSrc;
469 j = iHexRollbackDest;
470
471 // get over the '<' character
472 str_out[j]=str_in[i];
473 i++;
474 j++;
475
476 fInHex = FALSE;
477 iHexDigits = 0;
478
479 // just go on copying
480 continue;
481 }
482
483 // must be 2 or more(even nr) hex characters
484 if( iHexDigits == 2 )
485 {
486 str_out[j] = chHex;
487 j++;
488
489 iHexDigits = 0;
490 }
491
492 i++;
493 continue;
494 }
495
496 }
497
498 str_out[j]=str_in[i];
499 i++;
500 j++;
501 }
502 // @V4.HexChar End
503
504 str_out[j] = 0;
505 j++; // required
506
507//debug print
508// printf(" === %s ===\n", str_out );
509
510 return( j );
511} /* CopyString */
512
513
514/*
515** @V2.177675
516** This function previously copied the quoted contents to a destination buffer
517** and stored the string length in the first byte. Now, this function does a
518** standard NULL-terminated string copy for the contents within the quotes.
519*/
520/***************************************************************************
521 *
522 * FUNCTION NAME = CopyInQuote
523 *
524 * DESCRIPTION = This routine copies a NULL-terminated string from source to
525 * destination with delimiters as a double Quote. This
526 * function returns the string length, in bytes, including
527 * the terminator.
528 *
529 * If fRemoveDots is TRUE the dots in the target
530 * string will be replaced with underscores. This is
531 * to get around a in the IBM spooler which chokes on
532 * more than one dot in a printer model name.
533 *
534 * INPUT = szDestn - destination string
535 * szSource - source string
536 * fRemoveDots - flag
537 *
538 * OUTPUT = NONE.
539 *
540 * RETURN-NORMAL = NONE.
541 * RETURN-ERROR = NONE.
542 *
543 ************************************************************************* */
544
545int CopyInQuote(char *szDestn,char *szSource,BOOL fRemoveDots, BOOL CompressFlag)
546{
547 /*@V3.0CMPS01 start */
548 int j, k;
549//ULONG ulKey; NOTUSED
550 PWORDELEMENT pW;
551 PSZ pszP;
552 /*@V3.0CMPS01 end */
553 register int i = 0;
554 BOOL fInHexString = FALSE;
555
556 /*
557 ** @V2.177675
558 ** Remove MAX_ESC_STR_LEN. Some PPD commands may exceed 256 characters.
559 */
560
561 if (!(*szSource)) /* if the string is empty, do nothing */
562 return(i);
563
564 /* Remove excess leading spaces */
565 while (*szSource && isspace( *szSource ))
566 {
567 szSource++;
568 }
569
570 /*
571 ** Change any dots to underscores if needed
572 */
573 if ( fRemoveDots )
574 {
575 pszP = szSource;
576
577 while ( *pszP != '"' )
578 {
579 if ( *pszP == '.' )
580 {
581 *pszP = '_';
582 }
583
584 pszP++;
585 }
586 }
587
588
589 while (*szSource && *szSource != '"') /* make sure we check the null too. [wgs] */
590 {
591 if ( isalnum( *szSource ) )
592 {
593 /* copy ANs to buffer */
594 j = 0;
595 /*
596 ** A word is alphanumeric. Dots are allowed as long as in
597 ** the middle
598 */
599 while ( isalnum( *szSource ) ||
600 ((*szSource == '.') && isalnum( *(szSource+1) ) ) )
601 {
602 *(szDestn + i + j++ ) = *(szSource++);
603 }
604 if ( j > 1 ) /* a multi char word */
605 {
606 if (CompressFlag == TRUE)
607 {
608 *(szDestn + i + j ) = '\0';
609//
610// if ( fWriteWords ) /* Write out words if needed */
611// {
612// fprintf (ppdOut, "%s\n",szDestn+i);
613// }
614
615 if ( ( pW = SearchHashTable( (PSZ) szDestn+i ) ) != 0 ) //Look in hash table
616 {
617 /*
618 ** For each list we pass write a 0xff out - first list no FFs
619 ** secon write one FF, third write two ...
620 */
621 for ( k = 0; k < pW->sList; k++ )
622 {
623 *(szDestn + i++) = '\xFF';
624 }
625 *(szDestn + i++) = pW->sIndex;
626 }
627 else
628 {
629 i += j; /* move i by word */
630 }
631 }
632 else
633 {
634 i += j; /* move i by word */
635 }
636 }
637 else
638 {
639 i += j; /* move i by word */
640 }
641 }
642
643 else
644 if (isspace( *szSource ))
645 {
646 /*
647 ** If space use one space char and skip rest
648 --
649 ** Keep it a space Not tab CR LF etc...
650 */
651 BOOL fFoundLF = FALSE;
652
653 if ( *szSource != '\n' )
654 {
655 *(szDestn + i++) = ' ';
656 }
657 else
658 {
659 *(szDestn + i++) = '\n';
660 fFoundLF = TRUE;
661 }
662
663 szSource++;
664
665 /* Remove excess any spaces */
666 while ( isspace( *szSource ) &&
667 ( *szSource != '\n' || fFoundLF == TRUE ) )
668 {
669 szSource++;
670 }
671 }
672
673 else
674 {
675 // @V4.1200417
676 // This is either a hex string or dict entry
677 if ( *szSource == '<' )
678 {
679 // It's a Dict entry
680 if ( *(szSource+1) == '<' )
681 {
682 *(szDestn + i++) = *(szSource++);
683 }
684 else
685 {
686 // Do not compress hex strings
687 // If compression is already off then nothing really needs to change
688 fInHexString = CompressFlag;
689 CompressFlag = FALSE;
690 }
691 }
692 else
693 if ( *szSource == '>' &&
694 fInHexString == TRUE )
695 {
696 fInHexString = FALSE;
697 CompressFlag = TRUE;
698 }
699
700 *(szDestn + i++) = *(szSource++);
701 }
702 }
703
704 /*
705 ** NULL-terminate the destination string.
706 */
707
708 *(szDestn + i++) = 0;
709
710 return( i );
711} /* CopyInQuote */
712
713
Note: See TracBrowser for help on using the repository browser.