1780d15dfStholo /* This file was written by Jim Kingdon, and is hereby placed
2780d15dfStholo in the public domain. */
3780d15dfStholo
4780d15dfStholo #include <Wtypes.h>
5780d15dfStholo #include <stdio.h>
6780d15dfStholo #include <direct.h> /* For chdir */
7780d15dfStholo
8*2286d8edStholo #include "pubscc.h"
9780d15dfStholo
10780d15dfStholo /* We get to put whatever we want here, and the caller will pass it
11*2286d8edStholo to us, so we don't need any global variables. This is the
12*2286d8edStholo "void *context_arg" argument to most of the Scc* functions. */
13780d15dfStholo struct context {
14780d15dfStholo FILE *debuglog;
15780d15dfStholo /* Value of the CVSROOT we are currently working with (that is, the
16780d15dfStholo "open project" in SCC terminology), malloc'd, or NULL if there is
17780d15dfStholo no project currently open. */
18780d15dfStholo char *root;
19780d15dfStholo /* Local directory (working directory in CVS parlance). */
20780d15dfStholo char *local;
21780d15dfStholo SCC_outproc outproc;
22780d15dfStholo };
23780d15dfStholo
24*2286d8edStholo /* In addition to context_arg, most of the Scc* functions take a
25*2286d8edStholo "HWND window" argument. This is so that we can put up dialogs.
26*2286d8edStholo The window which is passed in is the IDE's window, which we
27*2286d8edStholo should use as the parent of dialogs that we put up. */
28*2286d8edStholo
29780d15dfStholo #include <windows.h>
30780d15dfStholo
31780d15dfStholo /* Report a malloc error and return the SCC_return_* value which the
32780d15dfStholo caller should return to the IDE. Probably this should be getting
33780d15dfStholo the window argument too, but for the moment we don't need it.
34780d15dfStholo Note that we only use this for errors which occur after the
35780d15dfStholo context->outproc is set up. */
36780d15dfStholo SCC_return
malloc_error(struct context * context)37780d15dfStholo malloc_error (struct context *context)
38780d15dfStholo {
39780d15dfStholo (*context->outproc) ("Out of memory\n", SCC_outproc_error);
40780d15dfStholo return SCC_return_non_specific_error;
41780d15dfStholo }
42780d15dfStholo
43780d15dfStholo /* Return the version of the SCC spec, major version in the high word,
44780d15dfStholo minor version in the low word. */
45780d15dfStholo LONG
SccGetVersion(void)46*2286d8edStholo SccGetVersion (void)
47780d15dfStholo {
48780d15dfStholo /* We implement version 1.1 of the spec. */
49780d15dfStholo return 0x10001;
50780d15dfStholo }
51780d15dfStholo
52780d15dfStholo SCC_return
SccInitialize(void ** contextp,HWND window,LPSTR caller,LPSTR name,LPLONG caps,LPSTR path,LPDWORD co_comment_len,LPDWORD comment_len)53780d15dfStholo SccInitialize (void **contextp, HWND window, LPSTR caller, LPSTR name,
54780d15dfStholo LPLONG caps, LPSTR path, LPDWORD co_comment_len,
55780d15dfStholo LPDWORD comment_len)
56780d15dfStholo {
57780d15dfStholo struct context *context;
58780d15dfStholo FILE *fp;
59780d15dfStholo fp = fopen ("d:\\debug.scc", "w");
60780d15dfStholo if (fp == NULL)
61780d15dfStholo /* Do what? Return some error value? */
62780d15dfStholo abort ();
63780d15dfStholo context = malloc (sizeof (struct context));
64780d15dfStholo if (context == NULL)
65780d15dfStholo {
66780d15dfStholo fprintf (fp, "Out of memory\n");
67780d15dfStholo fclose (fp);
68780d15dfStholo /* Do what? Return some error? */
69780d15dfStholo abort ();
70780d15dfStholo }
71780d15dfStholo context->debuglog = fp;
72780d15dfStholo context->root = NULL;
73780d15dfStholo *contextp = context;
74780d15dfStholo fprintf (fp, "Made it into SccInitialize!\n");
75780d15dfStholo *caps = (SCC_cap_GetProjPath
76780d15dfStholo | SCC_cap_AddFromScc
77780d15dfStholo | SCC_cap_want_outproc);
78780d15dfStholo
79780d15dfStholo /* I think maybe this should have some more CVS-like
80780d15dfStholo name, like "CVS Root", if we decide that is what
81780d15dfStholo a SCC "project" is. */
82780d15dfStholo strncpy (path, "CVS Project:", SCC_max_init_path);
83780d15dfStholo fprintf (fp, "Caller name is %s\n", caller);
84780d15dfStholo strncpy (name, "CVS", SCC_max_name);
85780d15dfStholo /* CVS has no limit on comment length. But I suppose
86780d15dfStholo we need to return a value which is small enough for
87780d15dfStholo a caller to allocate a buffer this big. Not that I
88780d15dfStholo would write a caller that way, but..... */
89780d15dfStholo *co_comment_len = 8192;
90780d15dfStholo *comment_len = 8192;
91780d15dfStholo fflush (fp);
92780d15dfStholo return SCC_return_success;
93780d15dfStholo }
94780d15dfStholo
95780d15dfStholo SCC_return
SccUninitialize(void * context_arg)96780d15dfStholo SccUninitialize (void *context_arg)
97780d15dfStholo {
98780d15dfStholo struct context *context = (struct context *)context_arg;
99780d15dfStholo if (ferror (context->debuglog))
100780d15dfStholo /* FIXME: return error value... */
101780d15dfStholo if (fclose (context->debuglog) == EOF)
102780d15dfStholo /* FIXME: return error value, I think. */
103780d15dfStholo ;
104780d15dfStholo free (context);
105780d15dfStholo return SCC_return_success;
106780d15dfStholo }
107780d15dfStholo
108780d15dfStholo SCC_return
SccOpenProject(void * context_arg,HWND window,LPSTR user,LPSTR project,LPSTR local_proj,LPSTR aux_proj,LPSTR comment,SCC_outproc outproc,LONG flags)109780d15dfStholo SccOpenProject (void *context_arg, HWND window, LPSTR user,
110780d15dfStholo LPSTR project, LPSTR local_proj, LPSTR aux_proj,
111*2286d8edStholo LPSTR comment, SCC_outproc outproc,
112*2286d8edStholo LONG flags)
113780d15dfStholo {
114780d15dfStholo struct context *context = (struct context *)context_arg;
115780d15dfStholo
116780d15dfStholo /* This can happen if the IDE opens a project which is not under
117780d15dfStholo CVS control. I'm not sure whether checking for aux_proj
118780d15dfStholo being "" is the right way to detect this case, but it seems
119780d15dfStholo it should work because I think that the source code control
120780d15dfStholo system is what has control over the contents of aux_proj. */
121780d15dfStholo if (aux_proj[0] == '\0')
122780d15dfStholo return SCC_return_unknown_project;
123780d15dfStholo
124780d15dfStholo context->root = malloc (strlen (aux_proj) + 5);
125780d15dfStholo if (context->root == NULL)
126780d15dfStholo return SCC_return_non_specific_error;
127780d15dfStholo strcpy (context->root, aux_proj);
128780d15dfStholo /* Since we don't yet support creating projects, we don't
129780d15dfStholo do anything with flags. */
130780d15dfStholo
131780d15dfStholo if (outproc == 0)
132780d15dfStholo {
133780d15dfStholo /* This supposedly can happen if the IDE chooses not to implement
134780d15dfStholo the outproc feature. */
135780d15dfStholo fprintf (context->debuglog, "Uh oh. outproc is a null pointer\n");
136780d15dfStholo context->root = NULL;
137780d15dfStholo fflush (context->debuglog);
138780d15dfStholo return SCC_return_non_specific_error;
139780d15dfStholo }
140780d15dfStholo context->outproc = outproc;
141780d15dfStholo
142780d15dfStholo fprintf (context->debuglog, "SccOpenProject (aux_proj=%s)\n", aux_proj);
143780d15dfStholo
144780d15dfStholo context->local = malloc (strlen (local_proj) + 5);
145780d15dfStholo if (context->local == NULL)
146780d15dfStholo return malloc_error (context);
147780d15dfStholo strcpy (context->local, local_proj);
148780d15dfStholo
149780d15dfStholo fflush (context->debuglog);
150780d15dfStholo return SCC_return_success;
151780d15dfStholo }
152780d15dfStholo
153780d15dfStholo SCC_return
SccCloseProject(void * context_arg)154780d15dfStholo SccCloseProject (void *context_arg)
155780d15dfStholo {
156780d15dfStholo struct context *context = (struct context *)context_arg;
157780d15dfStholo fprintf (context->debuglog, "SccCloseProject\n");
158780d15dfStholo fflush (context->debuglog);
159780d15dfStholo if (context->root != NULL)
160780d15dfStholo free (context->root);
161780d15dfStholo context->root = NULL;
162780d15dfStholo return SCC_return_success;
163780d15dfStholo }
164780d15dfStholo
165780d15dfStholo /* cvs get. */
166780d15dfStholo SCC_return
SccGet(void * context_arg,HWND window,LONG num_files,LPSTR * file_names,LONG options,void * prov_options)167780d15dfStholo SccGet (void *context_arg, HWND window, LONG num_files,
168*2286d8edStholo LPSTR *file_names,
169*2286d8edStholo LONG options,
170*2286d8edStholo void *prov_options)
171780d15dfStholo {
172780d15dfStholo struct context *context = (struct context *)context_arg;
173780d15dfStholo int i;
174780d15dfStholo char *fname;
175780d15dfStholo
176780d15dfStholo fprintf (context->debuglog, "SccGet: %d; files:", num_files);
177780d15dfStholo #if 1
178780d15dfStholo for (i = 0; i < num_files; ++i)
179780d15dfStholo {
180780d15dfStholo fprintf (context->debuglog, "%s ", file_names[i]);
181780d15dfStholo }
182780d15dfStholo #endif
183780d15dfStholo fprintf (context->debuglog, "\n");
184*2286d8edStholo if (options & SCC_cmdopt_dir)
185780d15dfStholo fprintf (context->debuglog, " Get all\n");
186780d15dfStholo /* Should be using this flag to set -R vs. -l. */
187*2286d8edStholo if (options & SCC_cmdopt_recurse)
188780d15dfStholo fprintf (context->debuglog, " recurse\n");
189780d15dfStholo
190780d15dfStholo for (i = 0; i < num_files; ++i)
191780d15dfStholo {
192780d15dfStholo /* As with all file names passed to us by the SCC, these
193780d15dfStholo file names are absolute pathnames. I think they will
194780d15dfStholo tend to be paths within context->local, although I
195780d15dfStholo don't know whether there are any exceptions to that. */
196780d15dfStholo fname = file_names[i];
197780d15dfStholo fprintf (context->debuglog, "%s ", fname);
198*2286d8edStholo /* Here we would write to the file named fname. */
199780d15dfStholo }
200780d15dfStholo fprintf (context->debuglog, "\nExiting SccGet\n");
201780d15dfStholo fflush (context->debuglog);
202780d15dfStholo return SCC_return_success;
203780d15dfStholo }
204780d15dfStholo
205780d15dfStholo /* cvs edit. */
206780d15dfStholo SCC_return
SccCheckout(void * context_arg,HWND window,LONG num_files,LPSTR * file_names,LPSTR comment,LONG options,void * prov_options)207780d15dfStholo SccCheckout (void *context_arg, HWND window, LONG num_files,
208*2286d8edStholo LPSTR *file_names, LPSTR comment,
209*2286d8edStholo LONG options,
210780d15dfStholo void *prov_options)
211780d15dfStholo {
212b78423f6Stholo struct context *context = (struct context *)context_arg;
213b78423f6Stholo fprintf (context->debuglog, "SccCheckout num_files=%ld\n", num_files);
214b78423f6Stholo fflush (context->debuglog);
215b78423f6Stholo /* For the moment we say that all files are not ours. I'm not sure
216b78423f6Stholo whether this is ever necessary; that is, whether the IDE will call
217b78423f6Stholo us except where we have told the IDE that a file is under source
218b78423f6Stholo control. */
219b78423f6Stholo /* I'm not sure what we would do if num_files > 1 and we wanted to
220b78423f6Stholo return different statuses for different files. */
221b78423f6Stholo return SCC_return_non_scc_file;
222780d15dfStholo }
223780d15dfStholo
224780d15dfStholo /* cvs ci. */
225780d15dfStholo SCC_return
SccCheckin(void * context_arg,HWND window,LONG num_files,LPSTR * file_names,LPSTR comment,LONG options,void * prov_options)226780d15dfStholo SccCheckin (void *context_arg, HWND window, LONG num_files,
227*2286d8edStholo LPSTR *file_names, LPSTR comment,
228*2286d8edStholo LONG options,
229780d15dfStholo void *prov_options)
230780d15dfStholo {
231780d15dfStholo return SCC_return_not_supported;
232780d15dfStholo }
233780d15dfStholo
234780d15dfStholo /* cvs unedit. */
235780d15dfStholo SCC_return
SccUncheckout(void * context_arg,HWND window,LONG num_files,LPSTR * file_names,LONG options,void * prov_options)236780d15dfStholo SccUncheckout (void *context_arg, HWND window, LONG num_files,
237*2286d8edStholo LPSTR *file_names,
238*2286d8edStholo LONG options,
239*2286d8edStholo void *prov_options)
240780d15dfStholo {
241780d15dfStholo return SCC_return_not_supported;
242780d15dfStholo }
243780d15dfStholo
244780d15dfStholo /* cvs add + cvs ci, more or less, I think (but see also
245780d15dfStholo the "keep checked out" flag in options). */
246780d15dfStholo SCC_return
SccAdd(void * context_arg,HWND window,LONG num_files,LPSTR * file_names,LPSTR comment,LONG * options,void * prov_options)247780d15dfStholo SccAdd (void *context_arg, HWND window, LONG num_files,
248*2286d8edStholo LPSTR *file_names, LPSTR comment,
249*2286d8edStholo LONG *options,
250780d15dfStholo void *prov_options)
251780d15dfStholo {
252780d15dfStholo return SCC_return_not_supported;
253780d15dfStholo }
254780d15dfStholo
255780d15dfStholo /* cvs rm -f + cvs ci, I think. Should barf if SCC_REMOVE_KEEP
256780d15dfStholo (or maybe just put the file there, as if the user had removed
257780d15dfStholo it and then done a "copy <saved-file> <filename>". */
258780d15dfStholo SCC_return
SccRemove(void * context_arg,HWND window,LONG num_files,LPSTR * file_names,LPSTR comment,LONG options,void * prov_options)259780d15dfStholo SccRemove (void *context_arg, HWND window, LONG num_files,
260*2286d8edStholo LPSTR *file_names, LPSTR comment,
261*2286d8edStholo LONG options,
262780d15dfStholo void *prov_options)
263780d15dfStholo {
264780d15dfStholo return SCC_return_not_supported;
265780d15dfStholo }
266780d15dfStholo
267780d15dfStholo /* mv, cvs add, cvs rm, and cvs ci, I think. */
268780d15dfStholo SCC_return
SccRename(void * context_arg,HWND window,LPSTR old_name,LPSTR new_name)269780d15dfStholo SccRename (void *context_arg, HWND window, LPSTR old_name,
270780d15dfStholo LPSTR new_name)
271780d15dfStholo {
272780d15dfStholo return SCC_return_not_supported;
273780d15dfStholo }
274780d15dfStholo
275*2286d8edStholo /* If SCC_cmdopt_compare_files, SCC_cmdopt_consult_checksum, or
276*2286d8edStholo SCC_cmdopt_consult_timestamp, then we are supposed to silently
277*2286d8edStholo return a status, without providing any information directly to the
278*2286d8edStholo user. For no args or checksum (which we fall back to full compare)
279*2286d8edStholo basically a call to No_Diff or ? in the client case. For
280*2286d8edStholo timestamp, just a Classify_File. Now, if contents not set, then
281*2286d8edStholo want to do a cvs diff, and preferably start up WinDiff or something
282*2286d8edStholo (to be determined, for now perhaps could just return text via
283*2286d8edStholo outproc). */
284780d15dfStholo SCC_return
SccDiff(void * context_arg,HWND window,LPSTR file_name,LONG options,void * prov_options)285780d15dfStholo SccDiff (void *context_arg, HWND window, LPSTR file_name,
286*2286d8edStholo LONG options,
287*2286d8edStholo void *prov_options)
288780d15dfStholo {
289780d15dfStholo return SCC_return_not_supported;
290780d15dfStholo }
291780d15dfStholo
292780d15dfStholo /* cvs log, I presume. If we want to get fancier we could bring
293780d15dfStholo up a screen more analogous to the tkCVS log window, let the user
294780d15dfStholo do "cvs update -r", etc. */
295780d15dfStholo SCC_return
SccHistory(void * context_arg,HWND window,LONG num_files,LPSTR * file_names,LONG options,void * prov_options)296780d15dfStholo SccHistory (void *context_arg, HWND window, LONG num_files,
297*2286d8edStholo LPSTR *file_names,
298*2286d8edStholo LONG options,
299*2286d8edStholo void *prov_options)
300780d15dfStholo {
301780d15dfStholo return SCC_return_not_supported;
302780d15dfStholo }
303780d15dfStholo
304780d15dfStholo /* cvs status, presumably. */
305780d15dfStholo SCC_return
SccProperties(void * context_arg,HWND window,LPSTR file_name)306780d15dfStholo SccProperties (void *context_arg, HWND window, LPSTR file_name)
307780d15dfStholo {
308780d15dfStholo return SCC_return_not_supported;
309780d15dfStholo }
310780d15dfStholo
311780d15dfStholo /* Not sure what this should do. The most obvious thing is some
312780d15dfStholo kind of front-end to "cvs admin" but I'm not actually sure that
313780d15dfStholo is the most useful thing. */
314780d15dfStholo SCC_return
SccRunScc(void * context_arg,HWND window,LONG num_files,LPSTR * file_names)315780d15dfStholo SccRunScc (void *context_arg, HWND window, LONG num_files,
316780d15dfStholo LPSTR *file_names)
317780d15dfStholo {
318780d15dfStholo return SCC_return_not_supported;
319780d15dfStholo }
320780d15dfStholo
321780d15dfStholo /* Lots of things that we could do here. Options to get/update
322*2286d8edStholo such as -r -D -k etc. just for starters. Note that the terminology is
323*2286d8edStholo a little confusing here. This function relates to "provider options"
324*2286d8edStholo (prov_options) which are a way for us to provide extra dialogs beyond
325*2286d8edStholo the basic ones for a particular command. It is unrelated to "command
326*2286d8edStholo options" (SCC_cmdopt_*). */
327780d15dfStholo SCC_return
SccGetCommandOptions(void * context_arg,HWND window,enum SCC_command command,void ** prov_optionsp)328780d15dfStholo SccGetCommandOptions (void *context_arg, HWND window,
329780d15dfStholo enum SCC_command command,
330780d15dfStholo void **prov_optionsp)
331780d15dfStholo {
332780d15dfStholo return SCC_return_not_supported;
333780d15dfStholo }
334780d15dfStholo
335780d15dfStholo /* Not existing CVS functionality, I don't think.
336780d15dfStholo Need to be able to tell user about what files
337780d15dfStholo are out there without actually getting them. */
338780d15dfStholo SCC_return
SccPopulateList(void * context_arg,enum SCC_command command,LONG num_files,LPSTR * file_names,SCC_popul_proc populate,void * callerdat,LONG options)339780d15dfStholo SccPopulateList (void *context_arg, enum SCC_command command,
340780d15dfStholo LONG num_files,
341780d15dfStholo LPSTR *file_names, SCC_popul_proc populate,
342*2286d8edStholo void *callerdat,
343*2286d8edStholo LONG options)
344780d15dfStholo {
345780d15dfStholo return SCC_return_success;
346780d15dfStholo }
347780d15dfStholo
348780d15dfStholo /* cvs status, sort of. */
349780d15dfStholo SCC_return
SccQueryInfo(void * context_arg,LONG num_files,LPSTR * file_names,LPLONG status)350780d15dfStholo SccQueryInfo (void *context_arg, LONG num_files, LPSTR *file_names,
351780d15dfStholo LPLONG status)
352780d15dfStholo {
353780d15dfStholo return SCC_return_not_supported;
354780d15dfStholo }
355780d15dfStholo
356*2286d8edStholo /* Like QueryInfo, but fast and for only a single file. For example, the
357*2286d8edStholo development environment might call this quite frequently to keep its
358*2286d8edStholo screen display updated. */
359780d15dfStholo SCC_return
SccGetEvents(void * context_arg,LPSTR file_name,LPLONG status,LPLONG events_remaining)360*2286d8edStholo SccGetEvents (void *context_arg, LPSTR file_name,
361*2286d8edStholo LPLONG status,
362780d15dfStholo LPLONG events_remaining)
363780d15dfStholo {
364780d15dfStholo /* They say this is supposed to only return cached status
365*2286d8edStholo information, not go to disk or anything. I assume that
366*2286d8edStholo QueryInfo and probably the usual calls like Get would cause
367*2286d8edStholo us to cache the status in the first place. */
368780d15dfStholo return SCC_return_success;
369780d15dfStholo }
370780d15dfStholo
371780d15dfStholo /* This is where the user gives us the CVSROOT. */
372780d15dfStholo SCC_return
SccGetProjPath(void * context_arg,HWND window,LPSTR user,LPSTR proj_name,LPSTR local_proj,LPSTR aux_proj,BOOL allow_change,BOOL * new)373780d15dfStholo SccGetProjPath (void *context_arg, HWND window, LPSTR user,
374780d15dfStholo LPSTR proj_name, LPSTR local_proj, LPSTR aux_proj,
375780d15dfStholo BOOL allow_change, BOOL *new)
376780d15dfStholo {
377780d15dfStholo /* For now we just hardcode the CVSROOT. In the future we will
378780d15dfStholo of course prompt the user for it (simple implementation would
379780d15dfStholo have them supply a string; potentially better implementation
380780d15dfStholo would have menus or something for access methods and so on,
381780d15dfStholo although it might also have a way of bypassing that in case
382780d15dfStholo CVS supports new features that the GUI code doesn't
383780d15dfStholo understand). We probably will also at some point want a
384780d15dfStholo "project" to encompass both a CVSROOT and a directory or
385780d15dfStholo module name within that CVSROOT, but we don't try to handle
386780d15dfStholo that yet either. We also will want to be able to use "user"
387780d15dfStholo instead of having the username encoded in the aux_proj or
388780d15dfStholo proj_name, probably. */
389780d15dfStholo
390780d15dfStholo struct context *context = (struct context *)context_arg;
391780d15dfStholo fprintf (context->debuglog, "SccGetProjPath called\n");
392780d15dfStholo
393780d15dfStholo /* At least for now we leave the proj_name alone, and just use
394780d15dfStholo the aux_proj. */
395780d15dfStholo strncpy (proj_name, "zwork", SCC_max_path);
396780d15dfStholo strncpy (aux_proj, ":server:harvey:/home/kingdon/zwork/cvsroot",
397780d15dfStholo SCC_max_path);
398780d15dfStholo if (local_proj[0] == '\0' && allow_change)
399780d15dfStholo strncpy (local_proj, "d:\\sccwork", SCC_max_path);
400780d15dfStholo /* I don't think I saw anything in the spec about this,
401780d15dfStholo but let's see if it helps. */
402780d15dfStholo if (_chdir (local_proj) < 0)
403780d15dfStholo fprintf (context->debuglog, "Error in chdir: %s", strerror (errno));
404780d15dfStholo
405780d15dfStholo if (*new)
406780d15dfStholo /* It is OK for us to prompt the user for creating a new
407780d15dfStholo project. */
408780d15dfStholo /* We will say that the user said to create a new one. */
409780d15dfStholo *new = 1;
410780d15dfStholo
411780d15dfStholo fflush (context->debuglog);
412780d15dfStholo return SCC_return_success;
413780d15dfStholo }
414780d15dfStholo
415780d15dfStholo /* Pretty much similar to SccPopulateList. */
416780d15dfStholo SCC_return
SccAddFromScc(void * context_arg,HWND window,LONG * files,char *** file_names)417780d15dfStholo SccAddFromScc (void *context_arg, HWND window, LONG *files,
418780d15dfStholo char ***file_names)
419780d15dfStholo {
420780d15dfStholo struct context *context = (struct context *)context_arg;
421780d15dfStholo
422780d15dfStholo /* For now we have hardcoded the notion that there are two files,
423780d15dfStholo foo.c and bar.c. */
424780d15dfStholo #define NUM_FILES 2
425780d15dfStholo if (files == NULL)
426780d15dfStholo {
427780d15dfStholo char **p;
428780d15dfStholo
429780d15dfStholo /* This means to free the memory that is allocated for
430780d15dfStholo file_names. */
431780d15dfStholo for (p = *file_names; *p != NULL; ++p)
432780d15dfStholo {
433780d15dfStholo fprintf (context->debuglog, "Freeing %s\n", *p);
434780d15dfStholo free (*p);
435780d15dfStholo }
436780d15dfStholo }
437780d15dfStholo else
438780d15dfStholo {
439780d15dfStholo *file_names = malloc ((NUM_FILES + 1) * sizeof (char **));
440780d15dfStholo if (*file_names == NULL)
441780d15dfStholo return malloc_error (context);
442780d15dfStholo (*file_names)[0] = malloc (80);
443780d15dfStholo if ((*file_names)[0] == NULL)
444780d15dfStholo return malloc_error (context);
445780d15dfStholo strcpy ((*file_names)[0], "foo.c");
446780d15dfStholo (*file_names)[1] = malloc (80);
447780d15dfStholo if ((*file_names)[1] == NULL)
448780d15dfStholo return malloc_error (context);
449780d15dfStholo strcpy ((*file_names)[1], "bar.c");
450780d15dfStholo (*file_names)[2] = NULL;
451780d15dfStholo *files = 2;
452780d15dfStholo
453780d15dfStholo /* Are we supposed to also Get the files? Or is the IDE
454780d15dfStholo next going to call SccGet on each one? The spec doesn't
455780d15dfStholo say explicitly. */
456780d15dfStholo }
457780d15dfStholo fprintf (context->debuglog, "Success in SccAddFromScc\n");
458780d15dfStholo fflush (context->debuglog);
459780d15dfStholo return SCC_return_success;
460780d15dfStholo }
461780d15dfStholo
462780d15dfStholo /* This changes several aspects of how we interact with the IDE. */
463780d15dfStholo SCC_return
SccSetOption(void * context_arg,LONG option,LONG val)464*2286d8edStholo SccSetOption (void *context_arg,
465*2286d8edStholo LONG option,
466*2286d8edStholo LONG val)
467780d15dfStholo {
468780d15dfStholo return SCC_return_success;
469780d15dfStholo }
470