~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to dbug/vargs.h

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 *                                                                            *
 
3
 *                                 N O T I C E                                *
 
4
 *                                                                            *
 
5
 *                    Copyright Abandoned, 1987, Fred Fish                    *
 
6
 *                                                                            *
 
7
 *                                                                            *
 
8
 *      This previously copyrighted work has been placed into the  public     *
 
9
 *      domain  by  the  author  and  may be freely used for any purpose,     *
 
10
 *      private or commercial.                                                *
 
11
 *                                                                            *
 
12
 *      Because of the number of inquiries I was receiving about the  use     *
 
13
 *      of this product in commercially developed works I have decided to     *
 
14
 *      simply make it public domain to further its unrestricted use.   I     *
 
15
 *      specifically  would  be  most happy to see this material become a     *
 
16
 *      part of the standard Unix distributions by AT&T and the  Berkeley     *
 
17
 *      Computer  Science  Research Group, and a standard part of the GNU     *
 
18
 *      system from the Free Software Foundation.                             *
 
19
 *                                                                            *
 
20
 *      I would appreciate it, as a courtesy, if this notice is  left  in     *
 
21
 *      all copies and derivative works.  Thank you.                          *
 
22
 *                                                                            *
 
23
 *      The author makes no warranty of any kind  with  respect  to  this     *
 
24
 *      product  and  explicitly disclaims any implied warranties of mer-     *
 
25
 *      chantability or fitness for any particular purpose.                   *
 
26
 *                                                                            *
 
27
 ******************************************************************************
 
28
 */
 
29
 
 
30
 
 
31
/*
 
32
 *  FILE
 
33
 *
 
34
 *      vargs.h    include file for environments without varargs.h
 
35
 *
 
36
 *  SCCS
 
37
 *
 
38
 *      @(#)vargs.h     1.2     5/8/88
 
39
 *
 
40
 *  SYNOPSIS
 
41
 *
 
42
 *      #include "vargs.h"
 
43
 *
 
44
 *  DESCRIPTION
 
45
 *
 
46
 *      This file implements a varargs macro set for use in those
 
47
 *      environments where there is no system supplied varargs.  This
 
48
 *      generally works because systems which don't supply a varargs
 
49
 *      package are precisely those which don't strictly need a varargs
 
50
 *      package.  Using this one then allows us to minimize source
 
51
 *      code changes.  So in some sense, this is a "portable" varargs
 
52
 *      since it is only used for convenience, when it is not strictly
 
53
 *      needed.
 
54
 *
 
55
 */
 
56
 
 
57
/*
 
58
 *      These macros allow us to rebuild an argument list on the stack
 
59
 *      given only a va_list.  We can use these to fake a function like
 
60
 *      vfprintf, which gets a fixed number of arguments, the last of
 
61
 *      which is a va_list, by rebuilding a stack and calling the variable
 
62
 *      argument form fprintf.  Of course this only works when vfprintf
 
63
 *      is not available in the host environment, and thus is not available
 
64
 *      for fprintf to call (which would give us an infinite loop).
 
65
 *
 
66
 *      Note that ARGS_TYPE is a long, which lets us get several bytes
 
67
 *      at a time while also preventing lots of "possible pointer alignment
 
68
 *      problem" messages from lint.  The messages are valid, because this
 
69
 *      IS nonportable, but then we should only be using it in very
 
70
 *      nonrestrictive environments, and using the real varargs where it
 
71
 *      really counts.
 
72
 *
 
73
 */
 
74
 
 
75
#define ARG0 a0
 
76
#define ARG1 a1
 
77
#define ARG2 a2
 
78
#define ARG3 a3
 
79
#define ARG4 a4
 
80
#define ARG5 a5
 
81
#define ARG6 a6
 
82
#define ARG7 a7
 
83
#define ARG8 a8
 
84
#define ARG9 a9
 
85
 
 
86
#define ARGS_TYPE long
 
87
#define ARGS_LIST ARG0,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8,ARG9
 
88
#define ARGS_DCL auto ARGS_TYPE ARGS_LIST
 
89
 
 
90
/*
 
91
 *      A pointer of type "va_list" points to a section of memory
 
92
 *      containing an array of variable sized arguments of unknown
 
93
 *      number.  This pointer is initialized by the va_start
 
94
 *      macro to point to the first byte of the first argument.
 
95
 *      We can then use it to walk through the argument list by
 
96
 *      incrementing it by the size of the argument being referenced.
 
97
 */
 
98
 
 
99
typedef char *va_list;
 
100
 
 
101
/*
 
102
 *      The first variable argument overlays va_alist, which is
 
103
 *      nothing more than a "handle" which allows us to get the
 
104
 *      address of the first argument on the stack.  Note that
 
105
 *      by definition, the va_dcl macro includes the terminating
 
106
 *      semicolon, which makes use of va_dcl in the source code
 
107
 *      appear to be missing a semicolon.
 
108
 */
 
109
 
 
110
#define va_dcl ARGS_TYPE va_alist;
 
111
 
 
112
/*
 
113
 *      The va_start macro takes a variable of type "va_list" and
 
114
 *      initializes it.  In our case, it initializes a local variable
 
115
 *      of type "pointer to char" to point to the first argument on
 
116
 *      the stack.
 
117
 */
 
118
 
 
119
#define va_start(list) list = (char *) &va_alist
 
120
 
 
121
/*
 
122
 *      The va_end macro is a null operation for our use.
 
123
 */
 
124
 
 
125
#define va_end(list)
 
126
 
 
127
/*
 
128
 *      The va_arg macro is the tricky one.  This one takes
 
129
 *      a va_list as the first argument, and a type as the second
 
130
 *      argument, and returns a value of the appropriate type
 
131
 *      while advancing the va_list to the following argument.
 
132
 *      For our case, we first increment the va_list arg by the
 
133
 *      size of the type being recovered, cast the result to
 
134
 *      a pointer of the appropriate type, and then dereference
 
135
 *      that pointer as an array to get the previous arg (which
 
136
 *      is the one we wanted.
 
137
 */
 
138
 
 
139
#define va_arg(list,type) ((type *) (list += sizeof (type)))[-1]