Subversion Repositories SvarDOS

Rev

Rev 1716 | Rev 1719 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1716 Rev 1717
Line 70... Line 70...
70
  unsigned long size;
70
  unsigned long size;
71
/*  char fname[13]; */
71
/*  char fname[13]; */
72
  char fname[12];
72
  char fname[12];
73
};
73
};
74
 
74
 
75
/* max amount of DTAs that can be buffered (not using 65535 because fmalloc a bit of overhead space) */
-
 
76
#define MAX_DTA_BUFCOUNT (65500 / sizeof(struct TINYDTA))
-
 
77
 
-
 
78
 
75
 
79
/* fills freebytes with free bytes for drv (A=0, B=1, etc)
76
/* fills freebytes with free bytes for drv (A=0, B=1, etc)
80
 * returns DOS ERR code on failure */
77
 * returns DOS ERR code on failure */
81
static unsigned short cmd_dir_df(unsigned long *freebytes, unsigned char drv) {
78
static unsigned short cmd_dir_df(unsigned long *freebytes, unsigned char drv) {
82
  unsigned short res = 0;
79
  unsigned short res = 0;
Line 201... Line 198...
201
  unsigned short i;
198
  unsigned short i;
202
  unsigned short availrows;  /* counter of available rows on display (used for /P) */
199
  unsigned short availrows;  /* counter of available rows on display (used for /P) */
203
  unsigned short screenw = screen_getwidth();
200
  unsigned short screenw = screen_getwidth();
204
  unsigned short wcols = screenw / WCOLWIDTH; /* number of columns in wide mode */
201
  unsigned short wcols = screenw / WCOLWIDTH; /* number of columns in wide mode */
205
  unsigned char wcolcount;
202
  unsigned char wcolcount;
-
 
203
  struct {
206
  struct nls_patterns *nls = (void *)(p->BUFFER + (p->BUFFERSZ / 2));
204
    struct nls_patterns nls;
-
 
205
    char buff64[64];
-
 
206
    char path[128];
207
  char *buff2 = p->BUFFER + (p->BUFFERSZ / 2) + sizeof(*nls);
207
  } *buf = (void *)(p->BUFFER);
208
  unsigned long summary_fcount = 0;
208
  unsigned long summary_fcount = 0;
209
  unsigned long summary_totsz = 0;
209
  unsigned long summary_totsz = 0;
210
  unsigned char drv = 0;
210
  unsigned char drv = 0;
211
  unsigned char attrfilter_may = DIR_ATTR_DEFAULT;
211
  unsigned char attrfilter_may = DIR_ATTR_DEFAULT;
212
  unsigned char attrfilter_must = 0;
212
  unsigned char attrfilter_must = 0;
Line 247... Line 247...
247
    nls_outputnl(37,11); /* "/B Uses bare format (no heading information or summary)" */
247
    nls_outputnl(37,11); /* "/B Uses bare format (no heading information or summary)" */
248
    nls_outputnl(37,12); /* "/L Uses lowercases" */
248
    nls_outputnl(37,12); /* "/L Uses lowercases" */
249
    return(CMD_OK);
249
    return(CMD_OK);
250
  }
250
  }
251
 
251
 
252
  i = nls_getpatterns(nls);
252
  i = nls_getpatterns(&(buf->nls));
253
  if (i != 0) nls_outputnl_doserr(i);
253
  if (i != 0) nls_outputnl_doserr(i);
254
 
254
 
255
  /* disable usage of thousands separator on narrow screens */
255
  /* disable usage of thousands separator on narrow screens */
256
  if (screenw < 80) nls->thousep[0] = 0;
256
  if (screenw < 80) buf->nls.thousep[0] = 0;
257
 
257
 
258
  /* parse command line */
258
  /* parse command line */
259
  for (i = 0; i < p->argc; i++) {
259
  for (i = 0; i < p->argc; i++) {
260
    if (p->argv[i][0] == '/') {
260
    if (p->argv[i][0] == '/') {
261
      const char *arg = p->argv[i] + 1;
261
      const char *arg = p->argv[i] + 1;
Line 335... Line 335...
335
  availrows = screen_getheight() - 2;
335
  availrows = screen_getheight() - 2;
336
 
336
 
337
  /* special case: "DIR drive:" (truename() fails on "C:" under MS-DOS 6.0) */
337
  /* special case: "DIR drive:" (truename() fails on "C:" under MS-DOS 6.0) */
338
  if ((filespecptr[0] != 0) && (filespecptr[1] == ':') && (filespecptr[2] == 0)) {
338
  if ((filespecptr[0] != 0) && (filespecptr[1] == ':') && (filespecptr[2] == 0)) {
339
    if ((filespecptr[0] >= 'a') && (filespecptr[0] <= 'z')) {
339
    if ((filespecptr[0] >= 'a') && (filespecptr[0] <= 'z')) {
340
      p->BUFFER[0] = filespecptr[0] - ('a' - 1);
340
      buf->path[0] = filespecptr[0] - ('a' - 1);
341
    } else {
341
    } else {
342
      p->BUFFER[0] = filespecptr[0] - ('A' - 1);
342
      buf->path[0] = filespecptr[0] - ('A' - 1);
343
    }
343
    }
344
    i = curpathfordrv(p->BUFFER, p->BUFFER[0]);
344
    i = curpathfordrv(buf->path, buf->path[0]);
345
  } else {
345
  } else {
346
    i = file_truename(filespecptr, p->BUFFER);
346
    i = file_truename(filespecptr, buf->path);
347
  }
347
  }
348
  if (i != 0) {
348
  if (i != 0) {
349
    nls_outputnl_doserr(i);
349
    nls_outputnl_doserr(i);
350
    return(CMD_FAIL);
350
    return(CMD_FAIL);
351
  }
351
  }
352
 
352
 
353
  if (format != DIR_OUTPUT_BARE) {
353
  if (format != DIR_OUTPUT_BARE) {
354
    drv = p->BUFFER[0];
354
    drv = buf->path[0];
355
    if (drv >= 'a') {
355
    if (drv >= 'a') {
356
      drv -= 'a';
356
      drv -= 'a';
357
    } else {
357
    } else {
358
      drv -= 'A';
358
      drv -= 'A';
359
    }
359
    }
360
    cmd_vol_internal(drv, buff2);
360
    cmd_vol_internal(drv, buf->buff64);
361
    sprintf(buff2, svarlang_str(37,20)/*"Directory of %s"*/, p->BUFFER);
361
    sprintf(buf->buff64, svarlang_str(37,20)/*"Directory of %s"*/, buf->path);
362
    /* trim at first '?', if any */
362
    /* trim at first '?', if any */
363
    for (i = 0; buff2[i] != 0; i++) if (buff2[i] == '?') buff2[i] = 0;
363
    for (i = 0; buf->buff64[i] != 0; i++) if (buf->buff64[i] == '?') buf->buff64[i] = 0;
364
    outputnl(buff2);
364
    outputnl(buf->buff64);
365
    outputnl("");
365
    outputnl("");
366
    availrows -= 3;
366
    availrows -= 3;
367
  }
367
  }
368
 
368
 
369
  /* if dir: append a backslash (also get its len) */
369
  /* if dir: append a backslash (also get its len) */
370
  i = path_appendbkslash_if_dir(p->BUFFER);
370
  i = path_appendbkslash_if_dir(buf->path);
371
 
371
 
372
  /* if ends with a \ then append ????????.??? */
372
  /* if ends with a \ then append ????????.??? */
373
  if (p->BUFFER[i - 1] == '\\') strcat(p->BUFFER, "????????.???");
373
  if (buf->path[i - 1] == '\\') strcat(buf->path, "????????.???");
374
 
374
 
375
  /* ask DOS for list of files, but only with allowed attribs */
375
  /* ask DOS for list of files, but only with allowed attribs */
376
  i = findfirst(dta, p->BUFFER, attrfilter_may);
376
  i = findfirst(dta, buf->path, attrfilter_may);
377
  if (i != 0) {
377
  if (i != 0) {
378
    nls_outputnl_doserr(i);
378
    nls_outputnl_doserr(i);
379
    return(CMD_FAIL);
379
    return(CMD_FAIL);
380
  }
380
  }
381
 
381
 
382
  /* if sorting is involved, then let's buffer all results (and sort them) */
382
  /* if sorting is involved, then let's buffer all results (and sort them) */
383
  if (order != NULL) {
383
  if (order != NULL) {
384
    /* allocate a memory buffer - try several sizes until one succeeds */
384
    /* allocate a memory buffer - try several sizes until one succeeds */
385
    unsigned short memsz[] = {65500, 32000, 16000, 8000, 4000, 2000, 0};
385
    const unsigned short memsz[] = {65500, 32000, 16000, 8000, 4000, 2000, 1000, 0};
386
    unsigned short max_dta_bufcount = 0;
386
    unsigned short max_dta_bufcount = 0;
387
    for (i = 0; memsz[i] != 0; i++) {
387
    for (i = 0; memsz[i] != 0; i++) {
388
      dtabuf = _fmalloc(memsz[i]);
388
      dtabuf = _fmalloc(memsz[i]);
389
      if (dtabuf != NULL) break;
389
      if (dtabuf != NULL) break;
390
    }
390
    }
Line 396... Line 396...
396
 
396
 
397
    /* remember the address so I can free it afterwards */
397
    /* remember the address so I can free it afterwards */
398
    dtabuf_root = dtabuf;
398
    dtabuf_root = dtabuf;
399
 
399
 
400
    /* compute the amount of DTAs I can buffer */
400
    /* compute the amount of DTAs I can buffer */
401
    max_dta_bufcount = 1; //memsz[i] / sizeof(struct TINYDTA);
401
    max_dta_bufcount = memsz[i] / sizeof(struct TINYDTA);
402
    printf("max_dta_bufcount = %u\n", max_dta_bufcount);
402
    printf("max_dta_bufcount = %u\n", max_dta_bufcount);
403
 
403
 
404
    do {
404
    do {
405
      /* filter out files with uninteresting attributes */
405
      /* filter out files with uninteresting attributes */
406
      if (filter_attribs(dta, attrfilter_must, attrfilter_may) == 0) continue;
406
      if (filter_attribs(dta, attrfilter_must, attrfilter_may) == 0) continue;
Line 450... Line 450...
450
        if (dta->fname[0] == '.') {
450
        if (dta->fname[0] == '.') {
451
          output(dta->fname);
451
          output(dta->fname);
452
          i = strlen(dta->fname);
452
          i = strlen(dta->fname);
453
          while (i++ < 12) output(" ");
453
          while (i++ < 12) output(" ");
454
        } else {
454
        } else {
455
          file_fname2fcb(buff2, dta->fname);
455
          file_fname2fcb(buf->buff64, dta->fname);
456
          memmove(buff2 + 9, buff2 + 8, 4);
456
          memmove(buf->buff64 + 9, buf->buff64 + 8, 4);
457
          buff2[8] = ' ';
457
          buf->buff64[8] = ' ';
458
          output(buff2);
458
          output(buf->buff64);
459
        }
459
        }
460
        output(" ");
460
        output(" ");
461
        /* either <DIR> or right aligned 10-chars byte size */
461
        /* either <DIR> or right aligned 10-chars byte size */
462
        memset(buff2, ' ', 10);
462
        memset(buf->buff64, ' ', 10);
463
        if (dta->attr & DOS_ATTR_DIR) {
463
        if (dta->attr & DOS_ATTR_DIR) {
464
          strcpy(buff2 + 10, svarlang_str(37,21));
464
          strcpy(buf->buff64 + 10, svarlang_str(37,21));
465
        } else {
465
        } else {
466
          nls_format_number(buff2 + 10, dta->size, nls);
466
          nls_format_number(buf->buff64 + 10, dta->size, &(buf->nls));
467
        }
467
        }
468
        output(buff2 + strlen(buff2) - 10);
468
        output(buf->buff64 + strlen(buf->buff64) - 10);
469
        /* two spaces and NLS DATE */
469
        /* two spaces and NLS DATE */
470
        buff2[0] = ' ';
470
        buf->buff64[0] = ' ';
471
        buff2[1] = ' ';
471
        buf->buff64[1] = ' ';
472
        if (screenw >= 80) {
472
        if (screenw >= 80) {
473
          nls_format_date(buff2 + 2, dta->date_yr + 1980, dta->date_mo, dta->date_dy, nls);
473
          nls_format_date(buf->buff64 + 2, dta->date_yr + 1980, dta->date_mo, dta->date_dy, &(buf->nls));
474
        } else {
474
        } else {
475
          nls_format_date(buff2 + 2, (dta->date_yr + 80) % 100, dta->date_mo, dta->date_dy, nls);
475
          nls_format_date(buf->buff64 + 2, (dta->date_yr + 80) % 100, dta->date_mo, dta->date_dy, &(buf->nls));
476
        }
476
        }
477
        output(buff2);
477
        output(buf->buff64);
478
 
478
 
479
        /* one space and NLS TIME */
479
        /* one space and NLS TIME */
480
        nls_format_time(buff2 + 1, dta->time_hour, dta->time_min, 0xff, nls);
480
        nls_format_time(buf->buff64 + 1, dta->time_hour, dta->time_min, 0xff, &(buf->nls));
481
        outputnl(buff2);
481
        outputnl(buf->buff64);
482
        break;
482
        break;
483
 
483
 
484
      case DIR_OUTPUT_WIDE: /* display in columns of 12 chars per item */
484
      case DIR_OUTPUT_WIDE: /* display in columns of 12 chars per item */
485
        i = strlen(dta->fname);
485
        i = strlen(dta->fname);
486
        if (dta->attr & DOS_ATTR_DIR) {
486
        if (dta->attr & DOS_ATTR_DIR) {
Line 529... Line 529...
529
  if (format != DIR_OUTPUT_BARE) {
529
  if (format != DIR_OUTPUT_BARE) {
530
    unsigned short alignpos;
530
    unsigned short alignpos;
531
    unsigned char uint32maxlen = 13; /* 13 is the max len of a 32 bit number with thousand separators (4'000'000'000) */
531
    unsigned char uint32maxlen = 13; /* 13 is the max len of a 32 bit number with thousand separators (4'000'000'000) */
532
    if (screenw < 80) uint32maxlen = 10;
532
    if (screenw < 80) uint32maxlen = 10;
533
    /* x file(s) */
533
    /* x file(s) */
534
    memset(buff2, ' ', uint32maxlen);
534
    memset(buf->buff64, ' ', uint32maxlen);
535
    i = nls_format_number(buff2 + uint32maxlen, summary_fcount, nls);
535
    i = nls_format_number(buf->buff64 + uint32maxlen, summary_fcount, &(buf->nls));
536
    alignpos = sprintf(buff2 + uint32maxlen + i, " %s ", svarlang_str(37,22)/*"file(s)"*/);
536
    alignpos = sprintf(buf->buff64 + uint32maxlen + i, " %s ", svarlang_str(37,22)/*"file(s)"*/);
537
    output(buff2 + i);
537
    output(buf->buff64 + i);
538
    /* xxxx bytes */
538
    /* xxxx bytes */
539
    i = nls_format_number(buff2 + uint32maxlen, summary_totsz, nls);
539
    i = nls_format_number(buf->buff64 + uint32maxlen, summary_totsz, &(buf->nls));
540
    output(buff2 + i + 1);
540
    output(buf->buff64 + i + 1);
541
    output(" ");
541
    output(" ");
542
    nls_outputnl(37,23); /* "bytes" */
542
    nls_outputnl(37,23); /* "bytes" */
543
    if (flags & DIR_FLAG_PAUSE) dir_pagination(&availrows);
543
    if (flags & DIR_FLAG_PAUSE) dir_pagination(&availrows);
544
    /* xxxx bytes free */
544
    /* xxxx bytes free */
545
    i = cmd_dir_df(&summary_totsz, drv);
545
    i = cmd_dir_df(&summary_totsz, drv);
546
    if (i != 0) nls_outputnl_doserr(i);
546
    if (i != 0) nls_outputnl_doserr(i);
547
    alignpos += uint32maxlen * 2;
547
    alignpos += uint32maxlen * 2;
548
    memset(buff2, ' ', alignpos); /* align the freebytes value to same column as totbytes */
548
    memset(buf->buff64, ' ', alignpos); /* align the freebytes value to same column as totbytes */
549
    i = nls_format_number(buff2 + alignpos, summary_totsz, nls);
549
    i = nls_format_number(buf->buff64 + alignpos, summary_totsz, &(buf->nls));
550
    output(buff2 + i + 1);
550
    output(buf->buff64 + i + 1);
551
    output(" ");
551
    output(" ");
552
    nls_outputnl(37,24); /* "bytes free" */
552
    nls_outputnl(37,24); /* "bytes free" */
553
    if (flags & DIR_FLAG_PAUSE) dir_pagination(&availrows);
553
    if (flags & DIR_FLAG_PAUSE) dir_pagination(&availrows);
554
  }
554
  }
555
 
555