Subversion Repositories SvarDOS

Compare Revisions

Ignore whitespace Rev 419 → Rev 420

/svarcom/trunk/cmd/dir.c
29,20 → 29,28
* NOTE: Multiple /A are not supported - only the last one is significant.
*/
 
#define WCOLWIDTH 15 /* width of a column in wide mode output */
 
static int cmd_dir(struct cmd_funcparam *p) {
const char *filespecptr = NULL;
struct DTA *dta = (void *)0x80; /* set DTA to its default location at 80h in PSP */
unsigned short i;
unsigned short availrows; /* counter of available rows on display (used for /P) */
unsigned short wcols = screen_getwidth() / WCOLWIDTH; /* number of columns in wide mode */
unsigned char wcolcount;
struct nls_patterns *nls = (void *)(p->BUFFER + (BUFFER_SIZE / 3));
char *buff2 = p->BUFFER + (BUFFER_SIZE / 3 * 2);
 
#define DIR_FLAG_PAUSE 1
#define DIR_FLAG_WIDE 2
#define DIR_FLAG_RECUR 4
#define DIR_FLAG_BARE 8
#define DIR_FLAG_LCASE 16
#define DIR_FLAG_LCASE 8
unsigned char flags = 0;
// unsigned char attribs_show = 0; /* show only files with ALL these attribs */
// unsigned char attribs_hide = 0; /* hide files with ANY of these attribs */
 
#define DIR_OUTPUT_NORM 1
#define DIR_OUTPUT_WIDE 2
#define DIR_OUTPUT_BARE 3
unsigned char format = DIR_OUTPUT_NORM;
 
if (cmd_ishlp(p)) {
outputnl("Displays a list of files and subdirectories in a directory");
outputnl("");
69,6 → 77,9
return(-1);
}
 
i = nls_getpatterns(nls);
if (i != 0) outputnl(doserr(i));
 
/* parse command line */
for (i = 0; i < p->argc; i++) {
if (p->argv[i][0] == '/') {
87,13 → 98,21
break;
case 'b':
case 'B':
flags |= DIR_FLAG_BARE;
format = DIR_OUTPUT_BARE;
break;
case 'w':
case 'W':
format = DIR_OUTPUT_WIDE;
break;
case 'p':
case 'P':
flags |= DIR_FLAG_PAUSE;
if (neg) flags &= (0xff ^ DIR_FLAG_PAUSE);
break;
case 'l':
case 'L':
flags |= DIR_FLAG_LCASE;
break;
default:
outputnl("Invalid switch");
return(-1);
125,9 → 144,8
return(-1);
}
 
if ((flags & DIR_FLAG_BARE) == 0) {
if (format != DIR_OUTPUT_BARE) {
unsigned char drv = p->BUFFER[0];
char *buff2 = p->BUFFER + (BUFFER_SIZE / 2);
if (drv >= 'a') {
drv -= 'a';
} else {
154,20 → 172,74
}
 
availrows = screen_getheight();
wcolcount = 0; /* may be used for columns counting with wide mode */
 
outputnl(dta->fname);
availrows--;
do {
if (flags & DIR_FLAG_LCASE) _strlwr(dta->fname); /* OpenWatcom extension, probably does not care about NLS so results may be odd with non-A-Z characters... */
 
while (findnext(dta) == 0) {
outputnl(dta->fname);
if (flags & DIR_FLAG_PAUSE) {
availrows--;
if (availrows < 2) {
press_any_key();
availrows = screen_getheight();
}
switch (format) {
case DIR_OUTPUT_NORM:
/* print fname-space-extension (unless it's "." or "..", then print as-is) */
if (dta->fname[0] == '.') {
output(dta->fname);
i = strlen(dta->fname);
while (i++ < 12) output(" ");
} else {
file_fname2fcb(buff2, dta->fname);
memmove(buff2 + 9, buff2 + 8, 4);
buff2[8] = ' ';
output(buff2);
}
output(" ");
/* either <DIR> or right aligned 10-chars byte size */
memset(buff2, ' ', 10);
if (dta->attr & DOS_ATTR_DIR) {
strcpy(buff2 + 10, "<DIR>");
} else {
_ultoa(dta->size, buff2 + 10, 10); /* OpenWatcom extension */
}
output(buff2 + strlen(buff2) - 10);
/* two spaces and NLS DATE */
buff2[0] = ' ';
buff2[1] = ' ';
nls_format_date(buff2 + 2, dta->date_yr + 1980, dta->date_mo, dta->date_dy, nls);
output(buff2);
 
/* one space and NLS TIME */
nls_format_time(buff2 + 1, dta->time_hour, dta->time_min, nls);
outputnl(buff2);
break;
 
case DIR_OUTPUT_WIDE: /* display in columns of 12 chars per item */
i = strlen(dta->fname);
if (dta->attr & DOS_ATTR_DIR) {
i += 2;
output("[");
output(dta->fname);
output("]");
} else {
output(dta->fname);
}
while (i++ < WCOLWIDTH) output(" ");
if (++wcolcount == wcols) {
wcolcount = 0;
outputnl("");
}
break;
 
case DIR_OUTPUT_BARE:
outputnl(dta->fname);
break;
}
}
 
if ((flags & DIR_FLAG_PAUSE) && (--availrows < 2)) {
press_any_key();
availrows = screen_getheight();
}
 
} while (findnext(dta) == 0);
 
if (wcolcount != 0) outputnl("");
 
return(-1);
}
/svarcom/trunk/helpers.c
4,9 → 4,11
*/
 
#include <i86.h> /* MK_FP() */
#include <stdio.h> /* sprintf() */
 
#include "helpers.h"
 
 
/* case-insensitive comparison of strings, returns non-zero on equality */
int imatch(const char *s1, const char *s2) {
for (;;) {
252,8 → 254,8
unsigned short i;
 
/* fill dst with 11 spaces and a NULL terminator */
for (i = 0; i < 12; i++) dst[i] = ' ';
dst[12] = 0;
for (i = 0; i < 11; i++) dst[i] = ' ';
dst[11] = 0;
 
/* copy fname until dot (.) or 8 characters */
for (i = 0; i < 8; i++) {
399,3 → 401,111
 
return(r);
}
 
 
/* fills a nls_patterns struct with current NLS patterns, returns 0 on success, DOS errcode otherwise */
unsigned short nls_getpatterns(struct nls_patterns *p) {
unsigned short r = 0;
 
_asm {
mov ax, 0x3800 /* DOS 2+ -- Get Country Info for current country */
mov dx, p /* DS:DX points to the CountryInfoRec buffer */
int 0x21
jnc DONE
mov [r], ax /* copy DOS err code to r */
DONE:
}
 
return(r);
}
 
 
/* computes a formatted date based on NLS patterns found in p
* returns length of result */
unsigned short nls_format_date(char *s, unsigned short yr, unsigned char mo, unsigned char dy, const struct nls_patterns *p) {
unsigned short items[3];
/* preset date/month/year in proper order depending on date format */
switch (p->dateformat) {
case 0: /* USA style: m d y */
items[0] = mo;
items[1] = dy;
items[2] = yr;
break;
case 1: /* EU style: d m y */
items[0] = dy;
items[1] = mo;
items[2] = yr;
break;
case 2: /* Japan-style: y m d */
default:
items[0] = yr;
items[1] = mo;
items[2] = dy;
break;
}
/* compute the string */
return(sprintf(s, "%02u%s%02u%s%02u", items[0], p->datesep, items[1], p->datesep, items[2]));
}
 
 
/* computes a formatted time based on NLS patterns found in p
* returns length of result */
unsigned short nls_format_time(char *s, unsigned char ho, unsigned char mn, const struct nls_patterns *p) {
char ampm[2] = {0, 0};
const char *fmt = "%02u%s%02u%s";
if (p->timefmt == 0) {
if (ho == 12) {
ampm[0] = 'p';
} else if (ho > 12) {
ho -= 12;
ampm[0] = 'p';
} else { /* ho < 12 */
if (ho == 0) ho = 12;
ampm[0] = 'a';
}
fmt = "%2u%s%02u%s";
}
return(sprintf(s, fmt, ho, p->timesep, mn, ampm));
}
 
 
/* computes a formatted integer number based on NLS patterns found in p
* returns length of result */
unsigned short nls_format_number(char *s, long num, const struct nls_patterns *p) {
unsigned short sl = 0, res, i;
unsigned char thcount = 0;
 
/* handle negative values */
if (num < 0) {
s[sl++] = '-';
num = 0 - num;
}
 
/* write the absolute value now */
do {
if ((thcount == 3) && (p->thousep[0] != 0)) {
s[sl++] = p->thousep[0];
thcount = 0;
}
s[sl++] = '0' + num % 10;
num /= 10;
thcount++;
} while (num > 0);
 
/* terminate the string and remember its size */
s[sl] = 0;
res = sl;
 
/* reverse the string now (it has been build in reverse) */
if (s[0] == '-') {
sl--;
s++;
}
for (i = 0; i <= (sl / 2); i++) {
thcount = s[i];
s[i] = s[sl - (i + 1)];
s[sl - (i + 1)] = thcount;
}
 
return(res);
}
/svarcom/trunk/helpers.h
26,12 → 26,49
_Packed struct DTA {
char reserved[21];
unsigned char attr;
unsigned short time;
unsigned short date;
unsigned short time_sec2:5;
unsigned short time_min:6;
unsigned short time_hour:5;
unsigned short date_dy:5;
unsigned short date_mo:4;
unsigned short date_yr:7;
unsigned long size;
char fname[13];
};
 
 
/* this is also known as the "Country Info Block" or "CountryInfoRec":
* offset size desc
* +0 2 wDateFormat 0=USA (m d y), 1=Europe (d m y), 2=Japan (y m d)
* +2 5 szCrncySymb currency symbol (ASCIIZ)
* +7 2 szThouSep thousands separator (ASCIIZ)
* +9 2 szDecSep decimal separator (ASCIIZ)
* +0bH 2 szDateSep date separator (ASCIIZ)
* +0dH 2 szTimeSep time separator (ASCIIZ)
* +0fH 1 bCrncyFlags currency format flags
* +10H 1 bCrncyDigits decimals digits in currency
* +11H 1 bTimeFormat time format 0=12h 1=24h
* +12H 4 pfCasemap Casemap FAR call address
* +16H 2 szDataSep data list separator (ASCIIZ)
* +18H 10 res reserved zeros
* 34 total length
*/
_Packed struct nls_patterns {
unsigned short dateformat;
char currency[5];
char thousep[2];
char decsep[2];
char datesep[2];
char timesep[2];
unsigned char currflags;
unsigned char currdigits;
unsigned char timefmt;
void far *casemapfn;
char datalistsep[2];
char reserved[10];
};
 
 
#define DOS_ATTR_RO 1
#define DOS_ATTR_HID 2
#define DOS_ATTR_SYS 4
89,4 → 126,19
* returns 0 on success, doserr otherwise */
unsigned short curpathfordrv(char *buff, unsigned char d);
 
/* fills a nls_patterns struct with current NLS patterns, returns 0 on success, DOS errcode otherwise */
unsigned short nls_getpatterns(struct nls_patterns *p);
 
/* computes a formatted date based on NLS patterns found in p
* returns length of result */
unsigned short nls_format_date(char *s, unsigned short yr, unsigned char mo, unsigned char dy, const struct nls_patterns *p);
 
/* computes a formatted time based on NLS patterns found in p
* returns length of result */
unsigned short nls_format_time(char *s, unsigned char ho, unsigned char mn, const struct nls_patterns *p);
 
/* computes a formatted integer number based on NLS patterns found in p
* returns length of result */
unsigned short nls_format_number(char *s, long num, const struct nls_patterns *p);
 
#endif