xref: /openbsd/gnu/usr.bin/cvs/windows-NT/SCC/scc.c (revision 2286d8ed)
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