File: o_cvs.cpp

package info (click to toggle)
fte 0.50.2b6-2
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 3,596 kB
  • ctags: 6,433
  • sloc: cpp: 47,985; ansic: 2,795; sh: 112; makefile: 105; perl: 29
file content (224 lines) | stat: -rw-r--r-- 5,960 bytes parent folder | download | duplicates (6)
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/*
 * o_cvs.cpp
 *
 * Contributed by Martin Frydl <frydl@matfyz.cz>
 *
 * Class providing access to most of CVS commands.
 */

#include "o_cvs.h"

#ifdef CONFIG_OBJ_CVS

#include "i_view.h"
#include "e_cvslog.h"
#include "o_buflist.h"
#include "s_files.h"
#include "sysdep.h"

#include <stdio.h>

static int SameDir(const char *D1, const char *D2)
{
    if (!D1||!D2) return 0;
    size_t l1=strlen (D1);
    size_t l2=strlen (D2);
    if (l1<l2) return strncmp (D1,D2,l1)==0&&strcmp (D2+l1,SSLASH)==0;
    else if (l1==l2) return !strcmp (D1,D2);
    else return strncmp (D1,D2,l2)==0&&strcmp (D1+l1,SSLASH)==0;
}

static const char CvsStatusChars[] = "?UPMCAR";
ECvs *CvsView=0;

ECvs::ECvs(int createFlags, EModel **ARoot, char* ADir, char* ACommand,
	   char* AOnFiles) :
    ECvsBase(createFlags, ARoot, "CVS"),
    LogFile(0),
    Commiting(0)
{
    CvsView=this;
    RunPipe (ADir, ACommand, AOnFiles);
}

ECvs::ECvs (int createFlags,EModel **ARoot) :
    ECvsBase (createFlags, ARoot, "CVS"),
    LogFile(0)
{
    CvsView=this;
}

ECvs::~ECvs () {
    CvsView=0;
    RemoveLogFile ();
}

void ECvs::RemoveLogFile()
{
    if (LogFile) {
        unlink (LogFile);
        free (LogFile);
        LogFile=0;
    }
}

char* ECvs::MarkedAsList()
{
    int i;
    size_t len=0;
    // First pass - calculate size
    for (i=0;i<LineCount;i++) if (Lines[i]->Status&2) len+=strlen (Lines[i]->File)+1;
    if (len==0) {
        // Nothing marked, use the file at cursor
        if (Lines[Row]->Status&4) return strdup (Lines[Row]->File);
        else return NULL;
    }
    char *s=(char *)malloc (len+1);
    s[0]=0;
    for (i=0;i<LineCount;i++) if (Lines[i]->Status&2) strcat (strcat (s,Lines[i]->File)," ");
    s[strlen (s)-1]=0;
    return s;
}

char ECvs::GetFileStatus(const char *file)
{
    // Search backward, file can be present several times (old messages)
    for (int i=LineCount-1;i>=0;i--)
        if (Lines[i]->File&&filecmp (Lines[i]->File,file)==0) return Lines[i]->Msg[0];
    return 0;
}

void ECvs::ParseLine(char* line, int len)
{
    if (len>2&&line[1]==' '&&strchr (CvsStatusChars,line[0])) {
        AddLine (line+2,-1,line,5);
    } else AddLine (0,-1,line);
}

int ECvs::RunPipe(const char *ADir, const char *ACommand, const char *AOnFiles)
{
    Commiting=0;
    if (!SameDir (Directory,ADir)) FreeLines ();
    return ECvsBase::RunPipe (ADir,ACommand,AOnFiles);
}

void ECvs::ClosePipe()
{
    ECvsBase::ClosePipe ();
    if (Commiting&&!ReturnCode) {
        // Successful commit - reload files
        // Is it safe to do this ? Currently not done, manual reload is needed
    }
    Commiting=0;
}

int ECvs::RunCommit(const char *ADir, const char *ACommand, const char *AOnFiles)
{
    if (!SameDir (Directory,ADir)) FreeLines ();

    free (Command);
    free (Directory);
    free (OnFiles);

    Command=strdup (ACommand);
    Directory=strdup (ADir);
    OnFiles=strdup (AOnFiles);

    RemoveLogFile ();
    // Disallow any CVS command while commiting
    Running=1;

    // Create message buffer
    ECvsLog *cvslog=new ECvsLog (0,&ActiveModel,Directory,OnFiles);
    LogFile=strdup (cvslog->FileName);
    View->SwitchToModel (cvslog);

    AddLine (LogFile,-1,"CVS commit start - enter message text",1);

    return 0;
}

extern BufferView *BufferList;//!!!

int ECvs::DoneCommit(int commit)
{
    Running=0;
    // Remove line with link to log
    free (Lines[LineCount-1]->File);
    free (Lines[LineCount-1]->Msg);
    LineCount--;
    UpdateList ();

    if (commit) {
        // We need a copy of Command/Directory/OnFiles because RunPipe deletes them!
        char *ACommand=(char *)malloc (strlen (Command)+strlen (LogFile)+10);
        char *ADirectory=strdup (Directory);
        char *AOnFiles=strdup (OnFiles);
        sprintf (ACommand,"%s -F %s",Command,LogFile);
        int ret=RunPipe (ADirectory,ACommand,AOnFiles);
        free (ACommand);free (ADirectory);free (AOnFiles);
        // We set Commiting after RunPipe since it sets it to 0
        // This is OK since FTE is not multi-threaded
        Commiting=1;

        if (ActiveView->Model==CvsLogView) {
            // CvsLogView is currently active, move CvsView just after it
            if (CvsLogView->Next!=CvsView) {
                // Need to move, is not at right place yet
                // Here we use the fact that if current model is closed,
                // the one just after it (Next) is focused.
                CvsView->Prev->Next=CvsView->Next;
                CvsView->Next->Prev=CvsView->Prev;
                CvsView->Next=CvsLogView->Next;
                CvsLogView->Next->Prev=CvsView;
                CvsLogView->Next=CvsView;
                CvsView->Prev=CvsLogView;
            }
        }
        // else - CvsLogView is not active, there is need to make CvsView
        // active some other way. However, SwitchToModel() or SelectModel()
        // calls does not work. Currently I don't know how to do this. !!!

        return ret;
    } else {
        RemoveLogFile();
        UpdateList();
        return 0;
    }
}

// If running, can't be closed without asking
int ECvs::CanQuit()
{
    if (Running) return 0;else return 1;
}

// Ask user if we can close this model
int ECvs::ConfQuit(GxView* V, int multiFile)
{
    if (CvsLogView) {
        // Log is open
        if (CvsLogView->ConfQuit(V,multiFile)) {
            // Commit confirmed or discarded - depends on Running
            ActiveView->DeleteModel(CvsLogView);
        } else return 0;
    }
    if (Running) {
        // CVS command in progress
        switch (V->Choice(GPC_ERROR,"CVS command is running",2,"&Kill","&Cancel","")) {
            case 0: // Kill
                return 1;
            case 1: // Cancel
            default:
                return 0;
        }
    } else return 1;
}

// Event map - this name is used in config files when defining eventmap
EEventMap *ECvs::GetEventMap()
{
    return FindEventMap("CVS");
}

#endif