snapshot of project "mawk", label t20090820

This commit is contained in:
Thomas E. Dickey 2009-08-21 00:53:52 -04:00
parent 6120b1d10d
commit d3df0bbc35
10 changed files with 111 additions and 89 deletions

19
CHANGES
View File

@ -1,10 +1,21 @@
-- $MawkId: CHANGES,v 1.48 2009/08/01 15:25:03 tom Exp $
-- $MawkId: CHANGES,v 1.52 2009/08/21 00:37:08 tom Exp $
Changes by Thomas E Dickey <dickey@invisible-island.net>
20090801
modify "%s" and "%c" formatting in printf/sprintf commands to allow
zero-padding as done by nawk (Debian #339799).
20090820
minor portability/standards fixes for examples/hical
add WHINY_USERS sorted-array feature, for compatibility with gawk
(patch by Aharon Robbins).
correct lower-limit for d_to_U() function, which broke conversion of
zero in "%x" format, added in fix for Debian #303825 (report by Masami
Hiramatsu).
modify "%s" and "%c" formatting in printf/sprintf commands to ensure
that "%02s" does not do zero-padding, for standards conformance
(discussion with Aharon Robbins, Mike Brennan, prompted by Debian
#339799).
20090728
add fallback definitions for GCC_NORETURN and GCC_UNUSED to build with

View File

@ -1,4 +1,4 @@
MANIFEST for mawk, version t20090801
MANIFEST for mawk, version t20090820
--------------------------------------------------------------------------------
MANIFEST this file
ACKNOWLEDGMENT acknowledgements

32
array.c
View File

@ -1,5 +1,5 @@
/*
array.c
array.c
copyright 1991-96, Michael D. Brennan
This is a source file for mawk, an implementation of
@ -59,7 +59,7 @@ CELL* array_find(
int create_flag)
{
ANODE *ap ;
if (A->size == 0 && !create_flag)
if (A->size == 0 && !create_flag)
/* eliminating this trivial case early avoids unnecessary conversions later */
return (CELL*) 0 ;
switch (cp->type) {
@ -69,7 +69,7 @@ CELL* array_find(
Int ival = d_to_I(d) ;
if ((double)ival == d) {
if (A->type == AY_SPLIT) {
if (ival >= 1 && ival <= (int) A->size)
if (ival >= 1 && ival <= (int) A->size)
return (CELL*)A->ptr+(ival-1) ;
if (!create_flag) return (CELL*) 0 ;
convert_split_array_to_table(A) ;
@ -104,7 +104,7 @@ void array_delete(
CELL *cp)
{
ANODE *ap ;
if (A->size == 0) return ;
if (A->size == 0) return ;
switch(cp->type) {
case C_DOUBLE :
{
@ -202,7 +202,7 @@ void array_load(
SPLIT_OV *p = split_ov_list ;
SPLIT_OV *q ;
split_ov_list = (SPLIT_OV*) 0 ;
i = MAX_SPLIT ;
i = MAX_SPLIT ;
while( p ) {
cells[i].type = C_MBSTRN ;
cells[i].ptr = (PTR) p->sval ;
@ -257,6 +257,16 @@ void array_clear(ARRAY A)
static int string_compare(
const void *l,
const void *r)
{
STRING*const * a = (STRING *const *) l;
STRING*const * b = (STRING *const *) r;
return strcmp((*a)->str, (*b)->str);
}
STRING** array_loop_vector(
ARRAY A,
unsigned *sizep)
@ -279,6 +289,8 @@ STRING** array_loop_vector(
}
}
if (getenv("WHINY_USERS") != NULL) /* gawk compability */
qsort(ret, A->size, sizeof(STRING*), string_compare);
return ret ;
}
else return (STRING**) 0 ;
@ -291,7 +303,7 @@ CELL *array_cat(
CELL *p ; /* walks the eval stack */
CELL subsep ; /* local copy of SUBSEP */
unsigned subsep_len ; /* string length of subsep_str */
char *subsep_str ;
char *subsep_str ;
unsigned total_len ; /* length of cat'ed expression */
CELL *top ; /* value of sp at entry */
@ -324,7 +336,7 @@ CELL *array_cat(
for(p = sp; p <= top ; p++) free_STRING(string(p)) ;
free_STRING(string(&subsep)) ;
/* set contents of sp , sp->type > C_STRING is possible so reset */
sp->type = C_STRING ;
sp->type = C_STRING ;
sp->ptr = (PTR) sval ;
return sp ;
@ -368,7 +380,7 @@ static ANODE* find_by_ival(
break ;
}
else if (p->ival == ival) {
else if (p->ival == ival) {
/* found it, now move to the front */
if (!q) /* already at the front */
return p ;
@ -524,7 +536,7 @@ static void double_the_hash_table(ARRAY A)
ANODE *q ; /* trails p for deletion */
ANODE *tail ; /* builds new list from the back */
ANODE dummy0, dummy1 ;
for(i=0, j=old_hmask+1; (unsigned) i <= old_hmask; i++, j++)
for(i=0, j=old_hmask+1; (unsigned) i <= old_hmask; i++, j++)
{
q = &dummy0 ;
q->slink = p = table[i].slink ;
@ -551,7 +563,7 @@ static void double_the_hash_table(ARRAY A)
ANODE *q ; /* trails p for deletion */
ANODE *tail ; /* builds new list from the back */
ANODE dummy0, dummy1 ;
for(i=0, j=old_hmask+1; (unsigned) i <= old_hmask; i++, j++)
for(i=0, j=old_hmask+1; (unsigned) i <= old_hmask; i++, j++)
{
q = &dummy0 ;
q->ilink = p = table[i].ilink ;

View File

@ -1,5 +1,5 @@
/*
array.h
array.h
copyright 1991-96, Michael D. Brennan
This is a source file for mawk, an implementation of

80
array.w
View File

@ -1,4 +1,4 @@
% $MawkId: array.w,v 1.5 2009/07/24 00:57:22 tom Exp $
% $MawkId: array.w,v 1.6 2009/08/21 00:12:00 tom Exp $
% @Log: array.w,v @
% Revision 1.4 1996/09/18 00:37:25 mike
% 1) Fix stupid bozo in A[expr], expr is numeric and not integer.
@ -80,7 +80,7 @@ return identical [[CELL]] pointers although the look up methods will
be different. In this case, the [[size]] field is the number of hash nodes
in the table. When insertion of a new element would cause [[size]] to
exceed [[limit]], the table grows by doubling the number of hash chains.
The invariant,
The invariant,
$({\it hmask}+1){\it max\_ave\_list\_length}={\it limit}$, is always true.
{\it Max\_ave\_list\_length} is a tunable constant.
@ -157,13 +157,13 @@ $A[\expr]$ from the array $A$. [[cp]] points at the [[CELL]] holding
\expr\/.
\hi [[void array_load(ARRAY A, int cnt)]] builds a split array. The
values $A[1..{\it cnt}]$ are copied from the array
values $A[1..{\it cnt}]$ are copied from the array
${\it split\_buff}[0..{\it cnt}-1]$.
\hi [[void array_clear(ARRAY A)]] removes all elements of $A$. The
type of $A$ is then [[AY_NULL]].
\hi [[STRING** array_loop_vector(ARRAY A, unsigned *sizep)]]
\hi [[STRING** array_loop_vector(ARRAY A, unsigned *sizep)]]
returns a pointer
to a linear vector that holds all the strings that are indices of $A$.
The size of the the vector is returned indirectly in [[*sizep]].
@ -172,7 +172,7 @@ If [[A->size==0]], a \Null{} pointer is returned.
\hi [[CELL* array_cat(CELL *sp, int cnt)]] concatenates the elements
of ${\it sp}[1-cnt..0]$, with each element separated by [[SUBSEP]], to
compute an array index. For example, on a reference to $A[i,j]$,
[[array_cat]] computes $i\circ{\it SUBSEP}\circ j$ where
[[array_cat]] computes $i\circ{\it SUBSEP}\circ j$ where
$\circ$ denotes concatenation.
@ -185,7 +185,7 @@ STRING** array_loop_vector(ARRAY, unsigned*);
CELL* array_cat(CELL*, int);
@ Array Find
Any reference to $A[\expr]$ creates a call to
Any reference to $A[\expr]$ creates a call to
[[array_find(A,cp,CREATE)]] where [[cp]] points at the cell holding
\expr\/. The test, $\expr \hbox{ in } A$, creates a call to
[[array_find(A,cp,NO_CREATE)]].
@ -212,7 +212,7 @@ CELL* array_find(
int create_flag)
{
ANODE *ap ;
if (A->size == 0 && !create_flag)
if (A->size == 0 && !create_flag)
/* eliminating this trivial case early avoids unnecessary conversions later */
return (CELL*) 0 ;
switch (cp->type) {
@ -233,7 +233,7 @@ CELL* array_find(
To test whether [[cp->dval]] is integer, we convert to the nearest
integer by rounding towards zero (done by [[do_to_I]]) and then cast
back to double. If we get the same number we started with, then
[[cp->dval]] is integer valued.
[[cp->dval]] is integer valued.
<<if the [[*cp]] is an integer, find by integer value else find by string value>>=
{
@ -241,7 +241,7 @@ back to double. If we get the same number we started with, then
Int ival = d_to_I(d) ;
if ((double)ival == d) {
if (A->type == AY_SPLIT) {
if (ival >= 1 && ival <= (int) A->size)
if (ival >= 1 && ival <= (int) A->size)
return (CELL*)A->ptr+(ival-1) ;
if (!create_flag) return (CELL*) 0 ;
convert_split_array_to_table(A) ;
@ -280,7 +280,7 @@ static ANODE* find_by_ival(
<<search by string value if needed and create if needed>>
break ;
}
else if (p->ival == ival) {
else if (p->ival == ival) {
/* found it, now move to the front */
if (!q) /* already at the front */
return p ;
@ -299,7 +299,7 @@ static ANODE* find_by_ival(
@
When a search by integer value fails, we have to check by string
value to correctly
handle the case insertion by [[A["123"]]] and later search as
handle the case insertion by [[A["123"]]] and later search as
[[A[123]]]. This string search is necessary if and only if the
[[AY_STR]] bit is set. An important point is that all [[ANODEs]] get
created with a valid [[sval]] if [[AY_STR]] is set, because then creation
@ -435,7 +435,7 @@ call to [[array_delete(ARRAY A, CELL *cp)]]. Depending on the
type of [[*cp]], the call is routed to [[find_by_sval]] or [[find_by_ival]].
Each of these functions leaves its return value on the front of an
slist or ilist, respectively, and then it is deleted from the front of
the list. The case where $A[\expr]$ is on two lists, e.g.,
the list. The case where $A[\expr]$ is on two lists, e.g.,
[[A[12]]] and [[A["12"]]] is checked by examining the [[sval]] and
[[ival]] fields of the returned [[ANODE*]].
@ -445,7 +445,7 @@ void array_delete(
CELL *cp)
{
ANODE *ap ;
if (A->size == 0) return ;
if (A->size == 0) return ;
switch(cp->type) {
case C_DOUBLE :
{
@ -530,7 +530,7 @@ When the size of a hash table drops below a certain value, it might
be profitable to shrink the hash table. Currently we don't do this,
because our guess is that it would be a waste of time for most
[[AWK]] applications. However, we do convert an array to [[AY_NULL]]
when the size goes to zero which would resize a large hash table
when the size goes to zero which would resize a large hash table
that had been completely cleared by successive deletions.
<<decrement [[A->size]]>>=
@ -542,7 +542,7 @@ A simple operation is to create an array with the [[AWK]]
primitive [[split]]. The code that performs [[split]] puts the
pieces in the global buffer [[split_buff]]. The call
[[array_load(A, cnt)]] moves the [[cnt]] elements from [[split_buff]] to
[[A]]. This is the only way an array of type [[AY_SPLIT]] is
[[A]]. This is the only way an array of type [[AY_SPLIT]] is
created.
<<interface functions>>=
@ -564,7 +564,7 @@ void array_load(
@
When [[cnt > MAX_SPLIT]], [[split_buff]] was not big enough to hold
everything so the overflow went on the [[split_ov_list]].
everything so the overflow went on the [[split_ov_list]].
The elements from [[MAX_SPLIT+1]] to [[cnt]] get loaded into
[[cells[MAX_SPLIT..cnt-1]]] from this list.
@ -573,7 +573,7 @@ if (cnt > MAX_SPLIT) {
SPLIT_OV *p = split_ov_list ;
SPLIT_OV *q ;
split_ov_list = (SPLIT_OV*) 0 ;
i = MAX_SPLIT ;
i = MAX_SPLIT ;
while( p ) {
cells[i].type = C_MBSTRN ;
cells[i].ptr = (PTR) p->sval ;
@ -604,7 +604,7 @@ else
@ Array Clear
The function [[array_clear(ARRAY A)]] converts [[A]] to type [[AY_NULL]]
and frees all storage used by [[A]] except for the [[struct array]]
and frees all storage used by [[A]] except for the [[struct array]]
itself. This function gets called in two contexts:
(1)~when an array local to a user function goes out of scope and
(2)~execution of the [[AWK]] statement, [[delete A]].
@ -670,7 +670,7 @@ lists that we are willing to tolerate before enlarging the table.
When [[A->size]] exceeds [[A->limit]],
the hash table grows in size by doubling the number of lists.
[[A->limit]] is then reset to [[MAX_AVE_LIST_LENGTH]] times
[[A->hmask+1]].
[[A->hmask+1]].
<<local constants, defs and prototypes>>=
#define STARTING_HMASK 63 /* 2^6-1, must have form 2^n-1 */
@ -739,7 +739,7 @@ while(A->size > A->limit) {
The whole point of making the table size a power of two is to
facilitate resizing the table. If the table size is $2^n$ and
$h$ is the hash key, then $h\bmod 2^n$ is the hash chain index
which can be calculated with bit-wise and,
which can be calculated with bit-wise and,
{\mathchardef~="2026 $h ~ (2^n-1)$}.
When the table size doubles, the new bit-mask has one more bit
turned on. Elements of an old hash chain whose hash value have this bit
@ -778,14 +778,14 @@ if (A->type & AY_STR) {
ANODE *q ; /* trails p for deletion */
ANODE *tail ; /* builds new list from the back */
ANODE dummy0, dummy1 ;
for(i=0, j=old_hmask+1; (unsigned) i <= old_hmask; i++, j++)
for(i=0, j=old_hmask+1; (unsigned) i <= old_hmask; i++, j++)
<<walk one old string list, creating one new string list>>
}
@
As we walk an old string list with pointer [[p]], the expression
[[p->hval & new_hmask]] takes one of two values. If it is equal
to [[p->hval & old_hmask]] (which equals [[i]]),
to [[p->hval & old_hmask]] (which equals [[i]]),
then the node stays otherwise it gets moved
to a new string list at [[j]]. The new string list preserves order so that
the positions of the move-to-the-front heuristic are preserved.
@ -823,7 +823,7 @@ if (A->type & AY_INT) {
ANODE *q ; /* trails p for deletion */
ANODE *tail ; /* builds new list from the back */
ANODE dummy0, dummy1 ;
for(i=0, j=old_hmask+1; (unsigned) i <= old_hmask; i++, j++)
for(i=0, j=old_hmask+1; (unsigned) i <= old_hmask; i++, j++)
<<walk one old integer list, creating one new integer list>>
}
@ -850,7 +850,7 @@ Our mechanism for dealing with execution of the statement,
\medskip
\centerline{[[for(i in A) {]] {\it statements} [[}]]}
\medskip
\noindent
\noindent
is simple. We allocate a vector of [[STRING*]] of size,
[[A->size]]. Each element of the vector is a string key for~[[A]].
Note that if the [[AY_STR]] bit of [[A]] is not set, then [[A]]
@ -875,6 +875,16 @@ of the string vector. The rest of the implementation
is in the file [[execute.c]].
<<interface functions>>=
static int string_compare(
const void *l,
const void *r)
{
STRING*const * a = (STRING *const *) l;
STRING*const * b = (STRING *const *) r;
return strcmp((*a)->str, (*b)->str);
}
STRING** array_loop_vector(
ARRAY A,
unsigned *sizep)
@ -885,6 +895,8 @@ STRING** array_loop_vector(
if (!(A->type & AY_STR)) add_string_associations(A) ;
ret = (STRING**) zmalloc(A->size*sizeof(STRING*)) ;
<<for each [[ANODE]] in [[A]], put one string in [[ret]]>>
if (getenv("WHINY_USERS") != NULL) /* gawk compability */
qsort(ret, A->size, sizeof(STRING*), string_compare);
return ret ;
}
else return (STRING**) 0 ;
@ -914,7 +926,7 @@ Since a hash value is turned into a table index via bit-wise and with
\hbox{[[A->hmask]]}, it is important that the hash function does a good job
of scrambling the low-order bits of the returned hash value.
Empirical tests indicate the following function does an adequate job.
Note that for strings with length greater than 10, we only hash on
Note that for strings with length greater than 10, we only hash on
the first five characters, the last five character and the length.
<<local functions>>=
@ -953,13 +965,13 @@ concatenation of the three
elements [[i]], [[SUBSEP]] and [[j]]. This is performed by the
function [[array_cat]]. On entry, [[sp]] points at the top of a
stack of [[CELLs]].
[[Cnt]] cells are popped off the stack and concatenated together
[[Cnt]] cells are popped off the stack and concatenated together
separated by [[SUBSEP]] and the result is pushed back on the stack.
On entry, the first multi-index is in [[sp[1-cnt]]] and the last is
in [[sp[0]]]. The return value is the new stack top.
(The stack is the run-time evaluation stack.
This operation really has nothing to do with array structure, so
logically this code belongs in [[execute.c]], but remains here for
logically this code belongs in [[execute.c]], but remains here for
historical reasons.)
@ -984,11 +996,11 @@ CELL *array_cat(
@
We make a copy of [[SUBSEP]] which we can cast to string in the
unlikely event the user has assigned a number to [[SUBSEP]].
unlikely event the user has assigned a number to [[SUBSEP]].
<<subsep parts>>=
unsigned subsep_len ; /* string length of subsep_str */
char *subsep_str ;
char *subsep_str ;
<<get subsep and compute parts>>=
cellcpy(&subsep, SUBSEP) ;
@ -1004,7 +1016,7 @@ between [[sp]] and [[top]].
top = sp ; sp -= (cnt-1) ;
@
The [[total_len]] is the sum of the lengths of the [[cnt]]
The [[total_len]] is the sum of the lengths of the [[cnt]]
strings and the [[cnt-1]] copies of [[subsep]].
<<cast cells to string and compute [[total_len]]>>=
@ -1034,11 +1046,11 @@ just need to free the strings and set the contents of [[sp]].
for(p = sp; p <= top ; p++) free_STRING(string(p)) ;
free_STRING(string(&subsep)) ;
/* set contents of sp , sp->type > C_STRING is possible so reset */
sp->type = C_STRING ;
sp->type = C_STRING ;
sp->ptr = (PTR) sval ;
return sp ;
@ Loose Ends
@ Loose Ends
Here are some things we want to make sure end up in the [[.c]] and
[[.h]] files.
The compiler needs prototypes for the local functions, and we will
@ -1057,7 +1069,7 @@ static unsigned ahash(STRING*);
<<array.c notice>>=
/*
array.c
array.c
<<mawk blurb>>
*/
@ -1076,7 +1088,7 @@ available from CTAN(ftp.shsu.edu).
It's easiest to read or modify this file by working with array.w.
<<array.h notice>>=
/*
array.h
array.h
<<mawk blurb>>
*/

10
cast.c
View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: cast.c,v 1.7 2009/07/26 16:23:02 tom Exp $
* $MawkId: cast.c,v 1.8 2009/08/20 23:00:13 tom Exp $
* @Log: cast.c,v @
* Revision 1.6 1996/08/11 22:07:50 mike
* Fix small bozo in rt_error("overflow converting ...")
@ -422,8 +422,8 @@ d_to_I(double d)
/* convert a double to UInt (this is not as simple as a
cast because the results are undefined if it won't fit).
Truncate large values to +Max_Int or -Max_Int
Send nans to -Max_Int
Truncate large values to Max_UInt or 0
Send nans to 0
*/
UInt
@ -431,7 +431,7 @@ d_to_U(double d)
{
if (d >= Max_UInt)
return Max_UInt;
if (d > -Max_UInt)
if (d > 0)
return (UInt) d;
return -Max_UInt;
return 0;
}

View File

@ -1,10 +1,11 @@
#!/usr/sh
#!/bin/sh
# $MawkId: hical,v 1.4 2009/08/21 00:36:34 tom Exp $
# @(#) hical - displays previous, current & next months - today highlighted
# @(#) an "internationalizationable" version of a 3-month 'cal' display, it
# @(#) may be edited for week to start with Sun or Mon & for local language
prog=/tmp/hical.$$ ; trap 'rm -f $prog ; trap 0 ; exit' 0 1 2 3 15
prog=${TMPDIR-/tmp}/hical.$$ ; trap 'rm -f $prog ; trap 0 ; exit' 0 1 2 3 15
: ${so:=`tput smso`} ${se:=`tput rmso`}
@ -15,22 +16,19 @@ prog=/tmp/hical.$$ ; trap 'rm -f $prog ; trap 0 ; exit' 0 1 2 3 15
# d - Day of month - 01 to 31
# T - Time as HH:MM:SS
# Y - Year (including century), as decimal numbers
DATE_ARGS='%w %m %d %T 19%y'
DATE_ARGS='%w %m %d %T %Y'
# the 'awk' program file is written to a temporary file to avoid any
# "arg list too long" error messages, yet have all the code in one file
# observe when editing the program file that '\n' must be '\\n'
# NOTE: to make this script portable /bin/echo has been used instead of the
# echo built into the shell for the 'bash' shell on Linux, use 'echo -e' in
# the next line (Modification made by Edward Betts <edward@debian.org>)
/bin/echo '{
# "arg list too long" error messages, yet have all the code in one file.
cat >$prog <<'EOF'
{
# USER EDITS MAY BE REQUIRED (for FMT, day & month names, and the time stuff)
# FMT = 0 # for weekdays ordered "Mo Tu We Th Fr Sa Su"
FMT = 1 # for weekdays ordered "Su Mo Tu We Th Fr Sa"
Header[0] = "Mo Tu We Th Fr Sa Su"
Header[1] = "Su Mo Tu We Th Fr Sa"
months = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
time_is = "The time is:" ; time_fmt = "%s %s %s %s\\n"
time_is = "The time is:" ; time_fmt = "%s %s %s %s\n"
# NO MORE USER EDITS REQUIRED (I think!)
split(months,M_Name) ; split("31 28 31 30 31 30 31 31 30 31 30 31",M_Len)
daynum = $1 + FMT
@ -42,8 +40,8 @@ DATE_ARGS='%w %m %d %T 19%y'
else { Mon[1] = Mon[2] - 1 }
if ( Mon[2] == 12 ) { Year[3] = Year[3] + 1 ; Mon[3] = 1 }
else { Mon[3] = Mon[2] + 1 }
if ( Year[2] % 4 == 0 && \
Year[2] % 100 != 0 || \
if ( Year[2] % 4 == 0 &&
Year[2] % 100 != 0 ||
Year[2] % 400 == 0 ) M_Len[2] = 29
Start[2] = 7 - ( ( today - daynum ) % 7 )
Start[1] = 7 - ( ( M_Len[Mon[1]] - Start[2] ) % 7 )
@ -51,8 +49,8 @@ DATE_ARGS='%w %m %d %T 19%y'
for (i=1;i<=3;i++) { while ( Start[i] >= 7 ) Start[i] -= 7 }
for (mm=1;mm<=3;mm++) {
if ( Year[mm] != Year[mm-1] )
printf( "%s %s %s\\n", so, Year[mm], se )
if ( mm == 1 ) printf( "%s %s %s\\n", so, Header[FMT], se )
printf( "%s %s %s\n", so, Year[mm], se )
if ( mm == 1 ) printf( "%s %s %s\n", so, Header[FMT], se )
j = k = 1
while ( j <= M_Len[Mon[mm]] ) {
line = ""
@ -64,11 +62,12 @@ DATE_ARGS='%w %m %d %T 19%y'
line = sprintf( "%s%s%2s%s ", line, So, date, Se )
}
m1 = substr(M_Name[Mon[mm]],k++,1)
printf( "%s %1s %s %s%s %s\\n", so, m1, se, line, so, se )
printf( "%s %1s %s %s%s %s\n", so, m1, se, line, so, se )
}
}
printf( time_fmt, so, time_is, time, se )
}' >$prog
}
EOF
date +"$DATE_ARGS" | ${AWK:=mawk} -f $prog so=$so se=$se

4
init.c
View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: init.c,v 1.10 2009/07/27 12:12:14 tom Exp $
* $MawkId: init.c,v 1.11 2009/08/21 00:53:52 tom Exp $
* @Log: init.c,v @
* Revision 1.11 1995/08/20 17:35:21 mike
* include <stdlib.h> for MSC, needed for environ decl
@ -188,7 +188,7 @@ process_cmdline(int argc, char **argv)
switch (argv[i][1]) {
case 'W':
if (isalpha(optArg[0]))
if (isalpha((UChar) optArg[0]))
optArg[0] = (char) toupper((UChar) optArg[0]);
if (optArg[0] == 'V')
print_version();

View File

@ -1,6 +1,6 @@
/*
* $MawkId: patchlev.h,v 1.7 2009/08/01 15:26:15 tom Exp $
* $MawkId: patchlev.h,v 1.8 2009/08/20 23:13:50 tom Exp $
*/
#define PATCHLEVEL 3
#define PATCH_STRING ".3"
#define DATE_STRING "20090801"
#define DATE_STRING "20090820"

16
print.c
View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: print.c,v 1.15 2009/08/01 16:16:24 tom Exp $
* $MawkId: print.c,v 1.17 2009/08/20 21:13:07 tom Exp $
* @Log: print.c,v @
* Revision 1.7 1996/09/18 01:04:36 mike
* Check ferror() after print and printf.
@ -385,12 +385,6 @@ puts_sfmt(PTR target,
if (!(flags & sfmtWIDTH)) {
width = src_len;
}
if ((flags & sfmtZEROS) && !(flags & sfmtMINUS)) {
while (src_len < width) {
fputc('0', fp);
--width;
}
}
if (!(flags & sfmtMINUS)) {
while (src_len < width) {
fputc(' ', fp);
@ -417,12 +411,6 @@ puts_sfmt(PTR target,
if (!(flags & sfmtWIDTH)) {
width = src_len;
}
if ((flags & sfmtZEROS) && !(flags & sfmtMINUS)) {
if (src_len < width) {
buffer = SprintfFill(buffer, '0', width - src_len);
width = src_len;
}
}
if (!(flags & sfmtMINUS)) {
if (src_len < width) {
buffer = SprintfFill(buffer, ' ', width - src_len);
@ -611,7 +599,7 @@ do_printf(
bozo("printf %c");
}
single.len = 1;
single.str[0] = Ival;
single.str[0] = (char) Ival;
pf_type = PF_C;
break;