summaryrefslogtreecommitdiff
path: root/reference/C/CONTRIB/SNIP/truename.c
blob: 2e4d1e34b6d54662f5e284133578ad96b4d0e89a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
** Apologies for the grotty code; I only just whipped this up.
**
** tname.c -- wrapper for the undocumented DOS function TRUENAME
**
** TRUENAME: interrupt 0x21 function 0x60
**
**   Call with: ah    =  60h
**              es:di -> destination buffer
**              ds:si -> source buffer
**
**   Returns:   carry bit set if there were problems
**
** This code hereby contributed to the public domain.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <dos.h>

#ifdef __TURBOC__
 #define _far far
#endif

/*
** Strip leading and trailing blanks from a string.
*/

char _far *strip(char _far *s)
{
      char _far *end;

      for ( ; isspace(*s); s++)
            ;

      for (end = s; *end; end++)
            ;

      for (end--; isspace(*end); *end-- = '\0')
            ;

      return s;
}

/*
** Truename itself. Note that I'm using intdosx() rather than
** playing with some inline assembler -- I've discovered some
** people that actually don't have an assembler, poor bastards :-)
*/

char _far *truename(char _far *dst, char _far *src)
{
      union REGS rg;
      struct SREGS rs;

      if (!src || !*src || !dst)
            return NULL;

      src=strip(src);

      rg.h.ah=0x60;
      rg.x.si=FP_OFF(src);
      rg.x.di=FP_OFF(dst);
      rs.ds=FP_SEG(src);
      rs.es=FP_SEG(dst);

      intdosx(&rg,&rg,&rs);

      return (rg.x.cflag) ? NULL : dst;
}

#ifdef TEST

/*
** ... and a little test function.
*/

int main(int argc, char *argv[])
{
      char buf[128]="                             ", _far *s;
      int i;

      if (3 > _osmajor)
      {
            puts("Only works with DOS 3+");
            return -1;
      }
      if(argc > 1)
      {
            for(i = 1; i < argc; i++)
            {
                  s = truename((char _far *)buf,(char _far *)argv[i]);
                  printf("%s=%s\n",argv[i], s ? buf : "(null)");
            }
      }
      else  printf("Usage: TRUENAME [filename [filename...]]\n");

      return 0;
}

#endif