Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
b1ea9d0e
Commit
b1ea9d0e
authored
Oct 15, 2012
by
Wayne Stambaugh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Minor FP_LIB_ID object changes.
parent
0dc4d9c1
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
64 additions
and
158 deletions
+64
-158
fp_lib_id.cpp
common/fp_lib_id.cpp
+18
-96
fp_lib_table.cpp
common/fp_lib_table.cpp
+0
-1
fp_lib_id.h
include/fp_lib_id.h
+46
-61
No files found.
common/fp_lib_id.cpp
View file @
b1ea9d0e
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
* This program source code file is part of KiCad, a free EDA CAD application.
*
*
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2010 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2010 KiCad Developers, see change_log.txt for contributors.
*
*
* This program is free software; you can redistribute it and/or
* This program is free software; you can redistribute it and/or
...
@@ -76,31 +77,12 @@ int RevCmp( const char* s1, const char* s2 )
...
@@ -76,31 +77,12 @@ int RevCmp( const char* s1, const char* s2 )
//----<Policy and field test functions>-------------------------------------
//----<Policy and field test functions>-------------------------------------
// These all return -1 on success, or >= 0 if there is an error at a
// particular character offset into their respective arguments. If >=0,
// then that return value gives the character offset of the error.
static
inline
int
okLogical
(
const
std
::
string
&
aField
)
static
inline
int
okLogical
(
const
std
::
string
&
aField
)
{
{
// std::string::npos is largest positive number, casting to int makes it -1.
// std::string::npos is largest positive number, casting to int makes it -1.
// Returning that means success.
// Returning that means success.
return
int
(
aField
.
find_first_of
(
":/"
)
);
return
int
(
aField
.
find_first_of
(
":"
)
);
}
static
inline
int
okBase
(
const
std
::
string
&
aField
)
{
int
offset
=
int
(
aField
.
find_first_of
(
":/"
)
);
if
(
offset
!=
-
1
)
return
offset
;
// cannot be empty
if
(
!
aField
.
size
()
)
return
0
;
return
offset
;
// ie. -1
}
}
...
@@ -120,13 +102,13 @@ static int okRevision( const std::string& aField )
...
@@ -120,13 +102,13 @@ static int okRevision( const std::string& aField )
return
0
;
// first character position "is in error", is best we can do.
return
0
;
// first character position "is in error", is best we can do.
}
}
//----</Policy and field test functions>-------------------------------------
//----</Policy and field test functions>-------------------------------------
void
FP_LIB_ID
::
clear
()
void
FP_LIB_ID
::
clear
()
{
{
logical
.
clear
();
logical
.
clear
();
baseName
.
clear
();
footprintName
.
clear
();
footprintName
.
clear
();
revision
.
clear
();
revision
.
clear
();
}
}
...
@@ -139,7 +121,6 @@ int FP_LIB_ID::Parse( const std::string& aId )
...
@@ -139,7 +121,6 @@ int FP_LIB_ID::Parse( const std::string& aId )
const
char
*
rev
=
EndsWithRev
(
aId
);
const
char
*
rev
=
EndsWithRev
(
aId
);
size_t
revNdx
;
size_t
revNdx
;
size_t
partNdx
;
size_t
partNdx
;
size_t
baseNdx
;
int
offset
;
int
offset
;
//=====<revision>=========================================
//=====<revision>=========================================
...
@@ -149,30 +130,28 @@ int FP_LIB_ID::Parse( const std::string& aId )
...
@@ -149,30 +130,28 @@ int FP_LIB_ID::Parse( const std::string& aId )
// no need to check revision, EndsWithRev did that.
// no need to check revision, EndsWithRev did that.
revision
=
aId
.
substr
(
revNdx
);
revision
=
aId
.
substr
(
revNdx
);
--
revNdx
;
// back up to omit the '/' which prece
ed
s the rev
--
revNdx
;
// back up to omit the '/' which prece
de
s the rev
}
}
else
else
{
revNdx
=
aId
.
size
();
revNdx
=
aId
.
size
();
}
//=====<logical>==========================================
//=====<logical>==========================================
if
(
(
partNdx
=
aId
.
find
(
':'
)
)
!=
aId
.
npos
)
if
(
(
partNdx
=
aId
.
find
(
':'
)
)
!=
aId
.
npos
)
{
{
offset
=
SetLogicalLib
(
aId
.
substr
(
0
,
partNdx
)
);
offset
=
SetLogicalLib
(
aId
.
substr
(
0
,
partNdx
)
);
if
(
offset
>
-
1
)
if
(
offset
>
-
1
)
{
{
return
offset
;
return
offset
;
}
}
++
partNdx
;
// skip ':'
++
partNdx
;
// skip ':'
}
}
else
else
partNdx
=
0
;
//=====<baseName>==========================================
offset
=
SetBaseName
(
aId
.
substr
(
baseNdx
,
revNdx
-
baseNdx
)
);
if
(
offset
>
-
1
)
{
{
return
offset
+
baseNdx
;
partNdx
=
0
;
}
}
return
-
1
;
return
-
1
;
...
@@ -207,37 +186,18 @@ int FP_LIB_ID::SetLogicalLib( const std::string& aLogical )
...
@@ -207,37 +186,18 @@ int FP_LIB_ID::SetLogicalLib( const std::string& aLogical )
}
}
int
FP_LIB_ID
::
SetBaseName
(
const
std
::
string
&
aBaseName
)
{
int
offset
=
okBase
(
aBaseName
);
if
(
offset
==
-
1
)
{
baseName
=
aBaseName
;
}
return
offset
;
}
int
FP_LIB_ID
::
SetFootprintName
(
const
std
::
string
&
aFootprintName
)
int
FP_LIB_ID
::
SetFootprintName
(
const
std
::
string
&
aFootprintName
)
{
{
std
::
string
base
;
int
offset
;
int
separation
=
int
(
aFootprintName
.
find_first_of
(
"/"
)
);
int
separation
=
int
(
aFootprintName
.
find_first_of
(
"/"
)
);
if
(
separation
!=
-
1
)
if
(
separation
!=
-
1
)
{
{
base
=
aFootprintName
.
substr
(
separation
+
1
);
logical
=
aFootprintName
.
substr
(
separation
+
1
);
return
separation
+
(
int
)
logical
.
size
()
+
1
;
}
}
else
else
{
{
base
=
aFootprintName
;
footprintName
=
aFootprintName
;
}
if
(
(
offset
=
SetBaseName
(
base
))
!=
-
1
)
{
return
offset
+
separation
+
1
;
}
}
return
-
1
;
return
-
1
;
...
@@ -267,8 +227,6 @@ std::string FP_LIB_ID::Format() const
...
@@ -267,8 +227,6 @@ std::string FP_LIB_ID::Format() const
ret
+=
':'
;
ret
+=
':'
;
}
}
ret
+=
baseName
;
if
(
revision
.
size
()
)
if
(
revision
.
size
()
)
{
{
ret
+=
'/'
;
ret
+=
'/'
;
...
@@ -283,8 +241,6 @@ std::string FP_LIB_ID::GetFootprintNameAndRev() const
...
@@ -283,8 +241,6 @@ std::string FP_LIB_ID::GetFootprintNameAndRev() const
{
{
std
::
string
ret
;
std
::
string
ret
;
ret
+=
baseName
;
if
(
revision
.
size
()
)
if
(
revision
.
size
()
)
{
{
ret
+=
'/'
;
ret
+=
'/'
;
...
@@ -308,7 +264,7 @@ std::string FP_LIB_ID::Format( const std::string& aLogicalLib, const std::string
...
@@ -308,7 +264,7 @@ std::string FP_LIB_ID::Format( const std::string& aLogicalLib, const std::string
if
(
offset
!=
-
1
)
if
(
offset
!=
-
1
)
{
{
THROW_PARSE_ERROR
(
_
(
"Illegal character found in logical lib name"
),
THROW_PARSE_ERROR
(
_
(
"Illegal character found in logical lib
rary
name"
),
wxString
::
FromUTF8
(
aLogicalLib
.
c_str
()
),
wxString
::
FromUTF8
(
aLogicalLib
.
c_str
()
),
aLogicalLib
.
c_str
(),
aLogicalLib
.
c_str
(),
0
,
0
,
...
@@ -319,33 +275,6 @@ std::string FP_LIB_ID::Format( const std::string& aLogicalLib, const std::string
...
@@ -319,33 +275,6 @@ std::string FP_LIB_ID::Format( const std::string& aLogicalLib, const std::string
ret
+=
':'
;
ret
+=
':'
;
}
}
{
std
::
string
base
;
int
separation
=
int
(
aFootprintName
.
find_first_of
(
"/"
)
);
if
(
separation
!=
-
1
)
{
base
=
aFootprintName
.
substr
(
separation
+
1
);
}
else
{
base
=
aFootprintName
;
}
if
(
(
offset
=
okBase
(
base
))
!=
-
1
)
{
THROW_PARSE_ERROR
(
_
(
"Illegal character found in base name"
),
wxString
::
FromUTF8
(
aRevision
.
c_str
()
),
aRevision
.
c_str
(),
0
,
offset
+
separation
+
1
);
}
ret
+=
base
;
}
if
(
aRevision
.
size
()
)
if
(
aRevision
.
size
()
)
{
{
offset
=
okRevision
(
aRevision
);
offset
=
okRevision
(
aRevision
);
...
@@ -374,16 +303,9 @@ std::string FP_LIB_ID::Format( const std::string& aLogicalLib, const std::string
...
@@ -374,16 +303,9 @@ std::string FP_LIB_ID::Format( const std::string& aLogicalLib, const std::string
void FP_LIB_ID::Test()
void FP_LIB_ID::Test()
{
{
static const char* lpids[] = {
static const char* lpids[] = {
"/R/rev0",
"smt:R_0805/rev0",
"passives/R/rev2",
"mysmt:R_0805/rev2",
":passives/R/rev3",
"device:AXIAL-0500",
"C/rev22",
"passives/C22",
"R",
"me:R",
// most difficult:
"me:/R/rev0",
"me:R/rev0",
};
};
for( unsigned i=0; i<sizeof(lpids)/sizeof(lpids[0]); ++i )
for( unsigned i=0; i<sizeof(lpids)/sizeof(lpids[0]); ++i )
...
@@ -393,10 +315,10 @@ void FP_LIB_ID::Test()
...
@@ -393,10 +315,10 @@ void FP_LIB_ID::Test()
FP_LIB_ID lpid( lpids[i] ); // parse
FP_LIB_ID lpid( lpids[i] ); // parse
// format
// format
printf( "input:'%s' full:'%s'
base:'%s'
footprintName:'%s' rev:'%s'\n",
printf( "input:'%s' full:'%s'
logical: %s
footprintName:'%s' rev:'%s'\n",
lpids[i],
lpids[i],
lpid.Format().c_str(),
lpid.Format().c_str(),
lpid.Get
BaseName
().c_str(),
lpid.Get
LogicalLib
().c_str(),
lpid.GetFootprintName().c_str(),
lpid.GetFootprintName().c_str(),
lpid.GetRevision().c_str() );
lpid.GetRevision().c_str() );
}
}
...
...
common/fp_lib_table.cpp
View file @
b1ea9d0e
...
@@ -304,4 +304,3 @@ bool FP_LIB_TABLE::InsertRow( const ROW& aRow, bool doReplace )
...
@@ -304,4 +304,3 @@ bool FP_LIB_TABLE::InsertRow( const ROW& aRow, bool doReplace )
return
false
;
return
false
;
}
}
include/fp_lib_id.h
View file @
b1ea9d0e
/*
/*
* This program source code file is part of KiCad, a free EDA CAD application.
* This program source code file is part of KiCad, a free EDA CAD application.
*
*
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2010-2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2010 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2010 KiCad Developers, see change_log.txt for contributors.
*
*
* This program is free software; you can redistribute it and/or
* This program is free software; you can redistribute it and/or
...
@@ -30,26 +31,26 @@
...
@@ -30,26 +31,26 @@
/**
/**
* Class FP_LIB_ID
* Class FP_LIB_ID
*
(aka GUID) is a Logical Par
t ID and consists of various portions much like a URI.
*
is a Logical Footprin
t ID and consists of various portions much like a URI.
* It is a container for the separated portions of a logical
part id std::string
so they
* It is a container for the separated portions of a logical
footprint id
so they
* can be accessed individually. The various portions of an FP_LIB_ID are:
* can be accessed individually. The various portions of an FP_LIB_ID are:
* logicalLibraryName, category, baseName, and revision. Only the baseName is
* logicalLibraryName (nick name), footprint name, and revision. The logical library
* mandatory. There is another construct called "footprintName" which consists of
* name and the footprint name are mandatory. The revision is optional and currently is
* [category/]baseName. That is the category followed by a slash, but only if
* not used.
* the category is not empty.
*
* <p>
* footprintName = [category/]baseName
* <p>
* Example FP_LIB_ID string:
* Example FP_LIB_ID string:
* "smt:R_0805".
* "smt:R_0805/rev0".
*
* <p>
* <p>
* <ul>
* <ul>
* <li> "smt" is the logical library name.
* <li> "smt" is the logical library name used to look up library information saved in the
* <li> "R" is the footprint name.
* #FP_LIB_TABLE.
* <li> "rev6" is the revision, which is optional. If missing then its
* <li> "R" is the name of the footprint within the library.
* <li> "rev0" is the revision, which is optional. If missing then its
* / delimiter should also not be present. A revision must begin with
* / delimiter should also not be present. A revision must begin with
* "rev" and be followed by at least one or more decimal digits.
* "rev" and be followed by at least one or more decimal digits.
* </ul>
* </ul>
*
* @author Dick Hollenbeck
* @author Dick Hollenbeck
*/
*/
class
FP_LIB_ID
// aka GUID
class
FP_LIB_ID
// aka GUID
...
@@ -60,26 +61,28 @@ public:
...
@@ -60,26 +61,28 @@ public:
/**
/**
* Constructor FP_LIB_ID
* Constructor FP_LIB_ID
* takes \a aId string and parses it. A typical FP_LIB_ID string
uses
a logical
* takes \a aId string and parses it. A typical FP_LIB_ID string
consists of
a logical
* library name followed by a footprint name.
* library name followed by a footprint name.
* e.g.: "smt:R_0805", or
* e.g.: "smt:R_0805", or
* e.g.: "mylib:R_0805"
* e.g.: "mylib:R_0805"
*
* @param aId is a string to be parsed into the FP_LIB_ID object.
*/
*/
FP_LIB_ID
(
const
std
::
string
&
aId
)
throw
(
PARSE_ERROR
);
FP_LIB_ID
(
const
std
::
string
&
aId
)
throw
(
PARSE_ERROR
);
/**
/**
* Function Parse
* Function Parse
* [re-]stuffs this FP_LIB_ID with the information from @a aId.
* [re-]stuffs this FP_LIB_ID with the information from @a aId.
* @return int - minus 1 (i.e. -1) means success, >= 0 indicates the
*
* character offset into aId at which an error was detected.
* @param aId is the string to populate the #FP_LIB_ID object.
* @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset into
* aId at which an error was detected.
*/
*/
int
Parse
(
const
std
::
string
&
aId
);
int
Parse
(
const
std
::
string
&
aId
);
/**
/**
* Function GetLogicalLib
* Function GetLogicalLib
* returns the logical library portion of a FP_LIB_ID. There is not Set accessor
* returns the logical library name portion of a FP_LIB_ID.
* for this portion since it comes from the library table and is considered
* read only here.
*/
*/
const
std
::
string
&
GetLogicalLib
()
const
const
std
::
string
&
GetLogicalLib
()
const
{
{
...
@@ -87,35 +90,17 @@ public:
...
@@ -87,35 +90,17 @@ public:
}
}
/**
/**
* Function Set
Category
* Function Set
LogicalLib
* overrides the logical
lib name portion of the FP_LIB_ID to @a aLogical, and can be empty
.
* overrides the logical
footprint library name portion of the FP_LIB_ID to @a aLogical
.
* @return int - minus 1 (i.e. -1) means success, >= 0 indicates the
* @return int - minus 1 (i.e. -1) means success, >= 0 indicates the
character offset
*
character offset into the parameter at which an error was detected, usually
*
into the parameter at which an error was detected, usually because it
*
because it
contained '/' or ':'.
*
contained '/' or ':'.
*/
*/
int
SetLogicalLib
(
const
std
::
string
&
aLogical
);
int
SetLogicalLib
(
const
std
::
string
&
aLogical
);
/**
* Function GetBaseName
* returns the part name without the category.
*/
const
std
::
string
&
GetBaseName
()
const
{
return
baseName
;
}
/**
* Function SetBaseName
* overrides the base name portion of the FP_LIB_ID to @a aBaseName
* @return int - minus 1 (i.e. -1) means success, >= 0 indicates the
* character offset into the parameter at which an error was detected, usually
* because it contained '/' or ':', or is blank.
*/
int
SetBaseName
(
const
std
::
string
&
aBaseName
);
/**
/**
* Function GetFootprintName
* Function GetFootprintName
* returns the
part name, i.e. category/baseName
without revision.
* returns the
footprint name, i.e. footprintName part
without revision.
*/
*/
const
std
::
string
&
GetFootprintName
()
const
const
std
::
string
&
GetFootprintName
()
const
{
{
...
@@ -124,18 +109,17 @@ public:
...
@@ -124,18 +109,17 @@ public:
/**
/**
* Function GetFootprintNameAndRev
* Function GetFootprintNameAndRev
* returns the part name with revision if any, i.e.
base
Name[/revN..]
* returns the part name with revision if any, i.e.
footprint
Name[/revN..]
*/
*/
std
::
string
GetFootprintNameAndRev
()
const
;
std
::
string
GetFootprintNameAndRev
()
const
;
/**
/**
* Function SetFootprintName
* Function SetFootprintName
* overrides the part name portion of the FP_LIB_ID to @a aFootprintName
* overrides the footprint name portion of the FP_LIB_ID to @a aFootprintName
* @return int - minus 1 (i.e. -1) means success, >= 0 indicates the
*
* character offset into the parameter at which an error was detected, usually
* @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset
* because it contained more than one '/', or one or more ':', or is blank.
* into the parameter at which an error was detected, usually because it contained
* A single '/' is allowed, since that is used to separate the category from the
* more than one '/', or one or more ':', or is blank.
* base name.
*/
*/
int
SetFootprintName
(
const
std
::
string
&
aFootprintName
);
int
SetFootprintName
(
const
std
::
string
&
aFootprintName
);
...
@@ -152,15 +136,16 @@ public:
...
@@ -152,15 +136,16 @@ public:
* Function SetRevision
* Function SetRevision
* overrides the revision portion of the FP_LIB_ID to @a aRevision and must
* overrides the revision portion of the FP_LIB_ID to @a aRevision and must
* be in the form "rev<num>" where "<num>" is "1", "2", etc.
* be in the form "rev<num>" where "<num>" is "1", "2", etc.
* @return int - minus 1 (i.e. -1) means success, >= 0 indicates the
*
* character offset into the parameter at which an error was detected,
* @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset*
* because it did not look like "rev23"
* into the parameter at which an error was detected,because it did not
* look like "rev23"
*/
*/
int
SetRevision
(
const
std
::
string
&
aRevision
);
int
SetRevision
(
const
std
::
string
&
aRevision
);
/**
/**
* Function Format
* Function Format
* returns the full text of the FP_LIB_ID.
* returns the full
y formatted
text of the FP_LIB_ID.
*/
*/
std
::
string
Format
()
const
;
std
::
string
Format
()
const
;
...
@@ -168,6 +153,7 @@ public:
...
@@ -168,6 +153,7 @@ public:
* Function Format
* Function Format
* returns a std::string in the proper format as an FP_LIB_ID for a combination of
* returns a std::string in the proper format as an FP_LIB_ID for a combination of
* aLogicalLib, aFootprintName, and aRevision.
* aLogicalLib, aFootprintName, and aRevision.
*
* @throw PARSE_ERROR if any of the pieces are illegal.
* @throw PARSE_ERROR if any of the pieces are illegal.
*/
*/
static
std
::
string
Format
(
const
std
::
string
&
aLogicalLib
,
const
std
::
string
&
aFootprintName
,
static
std
::
string
Format
(
const
std
::
string
&
aLogicalLib
,
const
std
::
string
&
aFootprintName
,
...
@@ -182,25 +168,24 @@ public:
...
@@ -182,25 +168,24 @@ public:
protected
:
protected
:
std
::
string
logical
;
///< logical lib name or empty
std
::
string
logical
;
///< logical lib name or empty
std
::
string
baseName
;
///< without category
std
::
string
revision
;
///< "revN[N..]" or empty
std
::
string
revision
;
///< "revN[N..]" or empty
std
::
string
footprintName
;
///<
cannot be set directory, set via SetBaseName() & SetCategory()
std
::
string
footprintName
;
///<
The name of the footprint in the logical library.
};
};
/**
/**
* Function EndsWithRev
* Function EndsWithRev
* returns a pointer to the final string segment: "revN[N..]" or NULL if none.
* returns a pointer to the final string segment: "revN[N..]" or NULL if none.
* @param start is the beginning of string segment to test, the partname or
* @param start is the beginning of string segment to test, the partname or
* any middle portion of it.
*
any middle portion of it.
* @param tail is a pointer to the terminating nul, or one past inclusive end of
* @param tail is a pointer to the terminating nul, or one past inclusive end of
* segment, i.e. the string segment of interest is [start,tail)
*
segment, i.e. the string segment of interest is [start,tail)
* @param separator is the separating byte, expected: '.' or '/', depending on context.
* @param separator is the separating byte, expected: '.' or '/', depending on context.
*/
*/
const
char
*
EndsWithRev
(
const
char
*
start
,
const
char
*
tail
,
char
separator
=
'/'
);
const
char
*
EndsWithRev
(
const
char
*
start
,
const
char
*
tail
,
char
separator
=
'/'
);
static
inline
const
char
*
EndsWithRev
(
const
std
::
string
&
aFootprintName
,
char
separator
=
'/'
)
static
inline
const
char
*
EndsWithRev
(
const
std
::
string
&
aFootprintName
,
char
separator
=
'/'
)
{
{
return
EndsWithRev
(
aFootprintName
.
c_str
(),
aFootprintName
.
c_str
()
+
aFootprintName
.
size
(),
return
EndsWithRev
(
aFootprintName
.
c_str
(),
aFootprintName
.
c_str
()
+
aFootprintName
.
size
(),
separator
);
separator
);
}
}
...
@@ -213,7 +198,7 @@ static inline const char* EndsWithRev( const std::string& aFootprintName, char s
...
@@ -213,7 +198,7 @@ static inline const char* EndsWithRev( const std::string& aFootprintName, char s
* @param s1 is a rev string like "rev10"
* @param s1 is a rev string like "rev10"
* @param s2 is a rev string like "rev1".
* @param s2 is a rev string like "rev1".
* @return int - either negative, zero, or positive depending on whether the revision
* @return int - either negative, zero, or positive depending on whether the revision
* is greater, equal, or less on the left hand side.
*
is greater, equal, or less on the left hand side.
*/
*/
int
RevCmp
(
const
char
*
s1
,
const
char
*
s2
);
int
RevCmp
(
const
char
*
s1
,
const
char
*
s2
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment