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

Last change on this file since 14 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.